diff --git a/2019/3rdDay/challenge.txt b/2019/3rdDay/challenge.txt index 8cb0d30..d8961b7 100644 --- a/2019/3rdDay/challenge.txt +++ b/2019/3rdDay/challenge.txt @@ -39,3 +39,32 @@ R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51 U98,R91,D20,R16,D67,R40,U7,R15,U6,R7 = distance 135 What is the Manhattan distance from the central port to the closest intersection? + +--- Part Two --- +It turns out that this circuit is very timing-sensitive; you actually need to minimize the signal delay. + +To do this, calculate the number of steps each wire takes to reach each intersection; choose the intersection where the sum of both wires' steps is lowest. If a wire visits a position on the grid multiple times, use the steps value from the first time it visits that position when calculating the total value of a specific intersection. + +The number of steps a wire takes is the total number of grid squares the wire has entered to get to that location, including the intersection being considered. Again consider the example from above: + +........... +.+-----+... +.|.....|... +.|..+--X-+. +.|..|..|.|. +.|.-X--+.|. +.|..|....|. +.|.......|. +.o-------+. +........... +In the above example, the intersection closest to the central port is reached after 8+5+5+2 = 20 steps by the first wire and 7+6+4+3 = 20 steps by the second wire for a total of 20+20 = 40 steps. + +However, the top-right intersection is better: the first wire takes only 8+5+2 = 15 and the second wire takes only 7+6+2 = 15, a total of 15+15 = 30 steps. + +Here are the best steps for the extra examples from above: + +R75,D30,R83,U83,L12,D49,R71,U7,L72 +U62,R66,U55,R34,D71,R55,D58,R83 = 610 steps +R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51 +U98,R91,D20,R16,D67,R40,U7,R15,U6,R7 = 410 steps +What is the fewest combined steps the wires must take to reach an intersection? diff --git a/2019/3rdDay/challenge1 b/2019/3rdDay/challenge1 new file mode 100644 index 0000000..6eb7f18 Binary files /dev/null and b/2019/3rdDay/challenge1 differ diff --git a/2019/3rdDay/challenge1.cpp b/2019/3rdDay/challenge1.cpp index 7b0a7f2..6c74204 100644 --- a/2019/3rdDay/challenge1.cpp +++ b/2019/3rdDay/challenge1.cpp @@ -84,10 +84,10 @@ int main(int argc, char** argv) std::string input; std::getline( infile, input ); - std::vector wireS1 = tokenise( "R75,D30,R83,U83,L12,D49,R71,U7,L72"); // tokenise( input ); + std::vector wireS1 = tokenise( input ); std::getline( infile, input ); - std::vector wireS2 = tokenise( "U62,R66,U55,R34,D71,R55,D58,R83" );// tokenise( input ); + std::vector wireS2 = tokenise( input ); // Construct map of nodes // for each point a wire @@ -132,30 +132,19 @@ int main(int argc, char** argv) return -1; }; - - std::unordered_map wires; - - for ( int i = 0; i < wire1.Visited.size(); i++ ) - { - wires[wire1.Visited[i]] = 1; - } - - for ( int i = 0; i < wire2.Visited.size(); i++ ) - { - if ( wires[wire1.Visited[i]] == 1 ) - wires[wire1.Visited[i]]++; - } - std::vector intersectDistances; - for ( auto it = wires.begin(); it != wires.end(); it++ ) + // This takes a good few seconds + for ( int i = 0; i < wire1.Visited.size(); i++ ) { - if ( it->second == 2 ) + + vec2 v = wire1.Visited[i]; + if ( find( wire2.Visited, v ) != -1 ) { - vec2 v = it->first; - std::cout << v.x << " " << v.y << std::endl; + std::cout << "Found : " << v.x << " " << v.y << std::endl; intersectDistances.push_back( std::abs( v.x ) + std::abs( v.y ) ); } + } int minDistance = *std::min_element( intersectDistances.cbegin(), intersectDistances.cend() ); diff --git a/2019/3rdDay/challenge1.exe b/2019/3rdDay/challenge1.exe deleted file mode 100644 index a93f341..0000000 Binary files a/2019/3rdDay/challenge1.exe and /dev/null differ diff --git a/2019/3rdDay/challenge2 b/2019/3rdDay/challenge2 new file mode 100644 index 0000000..250387c Binary files /dev/null and b/2019/3rdDay/challenge2 differ diff --git a/2019/3rdDay/challenge2.cpp b/2019/3rdDay/challenge2.cpp new file mode 100644 index 0000000..83a8422 --- /dev/null +++ b/2019/3rdDay/challenge2.cpp @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +std::vector tokenise( std::string input ) +{ + std::stringstream ssInput( input ); + std::vector stream; + + std::string s; + while( std::getline( ssInput, s, ',' ) ) { + stream.push_back( s ); + } + + return stream; +} + +struct vec2 +{ + int x; + int y; + + bool operator==(const vec2& v) const + { + return x == v.x && y == v.y; + } +}; + +namespace std +{ + template <> + struct hash + { + size_t operator()( const vec2& v ) const + { + return v.x ^ v.y; + } + }; +} + +std::unordered_map genPath( std::vector wire ) +{ + std::unordered_map path; + vec2 pos = { 0, 0 }; + path[pos] = 0; + + auto up = []( vec2& p ) { p.y -= 1; }; + auto down = []( vec2& p ) { p.y += 1; }; + auto left = []( vec2& p ) { p.x -= 1; }; + auto right = []( vec2& p ) { p.x += 1; }; + + void (*stepSingle)(vec2&); + + int stepCounter = 0; + + for ( auto& element : wire ) + { + char dir = element[0]; + int steps = std::stoi( element.substr( 1, element.size() ) ); + + switch ( dir ) + { + case 'U': stepSingle = up; break; + case 'D': stepSingle = down; break; + case 'R': stepSingle = right; break; + case 'L': stepSingle = left; break; + default: break; + } + + for( int i = 0; i < steps; i++ ) + { + stepSingle( pos ); + path[pos] = ++stepCounter; + } + } + + return path; +} + +int main(int argc, char** argv) +{ + + std::ifstream infile( argv[1] ); + + std::string input; + + std::getline( infile, input ); + std::vector wireS1 = tokenise( input ); + + std::getline( infile, input ); + std::vector wireS2 = tokenise( input ); + + auto path1 = genPath(wireS1); + auto path2 = genPath(wireS2); + + int res = INFINITY; + + for ( auto [pos, steps] : path2 ) + { + // Intersect + if ( path1.count( pos ) > 0 ) + { + std::cout << pos.x << ":" << pos.y << " " << steps << std::endl; + if ( steps == 0 ) continue; + res = std::min( res, path1[pos] + path2[pos] ); + } + } + + std::cout << "Shortest Distance to Complete : " << res << std::endl; + +}