This commit is contained in:
Ben
2019-12-03 23:48:37 +00:00
parent e886ca3847
commit f62d80b667
6 changed files with 154 additions and 20 deletions

View File

@@ -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?

BIN
2019/3rdDay/challenge1 Normal file

Binary file not shown.

View File

@@ -84,10 +84,10 @@ int main(int argc, char** argv)
std::string input;
std::getline( infile, input );
std::vector<std::string> wireS1 = tokenise( "R75,D30,R83,U83,L12,D49,R71,U7,L72"); // tokenise( input );
std::vector<std::string> wireS1 = tokenise( input );
std::getline( infile, input );
std::vector<std::string> wireS2 = tokenise( "U62,R66,U55,R34,D71,R55,D58,R83" );// tokenise( input );
std::vector<std::string> 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<vec2, int> 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<int> 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() );

Binary file not shown.

BIN
2019/3rdDay/challenge2 Normal file

Binary file not shown.

116
2019/3rdDay/challenge2.cpp Normal file
View File

@@ -0,0 +1,116 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <math.h>
std::vector<std::string> tokenise( std::string input )
{
std::stringstream ssInput( input );
std::vector<std::string> 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<vec2>
{
size_t operator()( const vec2& v ) const
{
return v.x ^ v.y;
}
};
}
std::unordered_map<vec2, int> genPath( std::vector<std::string> wire )
{
std::unordered_map<vec2, int> 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<std::string> wireS1 = tokenise( input );
std::getline( infile, input );
std::vector<std::string> 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;
}