2019 Day 03 solution

This commit is contained in:
Josh Creek
2019-12-04 22:45:42 +00:00
parent bd33ab558b
commit e8a844b990
5 changed files with 276 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<RootNamespace>Day_03</RootNamespace>
</PropertyGroup>
</Project>
+197
View File
@@ -0,0 +1,197 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
namespace Day_03
{
class Program
{
static void Main(string[] args)
{
//Part1();
Part2();
}
public class WireTouchPoint
{
public int x { get; set; }
public int y { get; set; }
}
static List<WireTouchPoint> FindAllWireTouchPoints(List<string> wireCommands)
{
List<WireTouchPoint> touchPoints = new List<WireTouchPoint>(){};
int currentX = 0;
int currentY = 0;
WireTouchPoint initialWTP = new WireTouchPoint();
initialWTP.x = currentX;
initialWTP.y = currentY;
touchPoints.Add(initialWTP);
// For each command, record every co-ordinate the wire touches
foreach(string wireCommand in wireCommands)
{
// Not bothering with error catching for converting strings to ints as the data cannot be wrongly typed in the input file
int distance = System.Convert.ToInt32(wireCommand.Substring(1));
// Handle the different commands in the first letter of each command string
switch (wireCommand[0])
{
case 'U':
// Up
for(int i = 0; i < distance; i++)
{
currentY += 1;
WireTouchPoint wtp = new WireTouchPoint();
wtp.x = currentX;
wtp.y = currentY;
touchPoints.Add(wtp);
}
break;
case 'D':
// Down
for(int i = 0; i < distance; i++)
{
currentY -= 1;
WireTouchPoint wtp = new WireTouchPoint();
wtp.x = currentX;
wtp.y = currentY;
touchPoints.Add(wtp);
}
break;
case 'L':
// Left
for(int i = 0; i < distance; i++)
{
currentX -= 1;
WireTouchPoint wtp = new WireTouchPoint();
wtp.x = currentX;
wtp.y = currentY;
touchPoints.Add(wtp);
}
break;
case 'R':
// Right
for(int i = 0; i < distance; i++)
{
currentX += 1;
WireTouchPoint wtp = new WireTouchPoint();
wtp.x = currentX;
wtp.y = currentY;
touchPoints.Add(wtp);
}
break;
default:
break;
}
}
return touchPoints;
}
internal class WireTouchPointComparer : IEqualityComparer<WireTouchPoint>
{
public bool Equals(WireTouchPoint wtp1, WireTouchPoint wtp2)
{
if(wtp1.x == wtp2.x && wtp1.y == wtp2.y)
{
return true;
}
return false;
}
// public int GetHashCode(WireTouchPoint obj)
// {
// return obj.x.GetHashCode();
// }
public int GetHashCode(WireTouchPoint obj)
{
unchecked
{
int hash = 17;
hash = hash * 23 + obj.x.GetHashCode();
hash = hash * 23 + obj.y.GetHashCode();
return hash;
}
}
}
static void Part1()
{
// Each line is one wire's path trace
var wire1 = File.ReadAllLines("input.txt")[0];
var wire2 = File.ReadAllLines("input.txt")[1];
List<string> wire1Commands = wire1.Split(',').ToList();
List<string> wire2Commands = wire2.Split(',').ToList();
// Find all points each wire touches
List<WireTouchPoint> wire1TouchPoints = FindAllWireTouchPoints(wire1Commands);
List<WireTouchPoint> wire2TouchPoints = FindAllWireTouchPoints(wire2Commands);
// Find all points where the two wires cross
var crossingPoints = wire1TouchPoints.Intersect(wire2TouchPoints, new WireTouchPointComparer()).Where(cp => cp.x != 0 && cp.y != 0);
// Declare a large default shortest distance, probably should be setting as null and null-checking later but multitasking while writing this so cba
int shortestManhattanDistance = 9999999;
// For each crossing point, work out the Manhattan distance to the central port
foreach(WireTouchPoint crossingPoint in crossingPoints)
{
// Convert co-ordinates to be positive numbers for calculating distance
int xVal = crossingPoint.x > 0 ? crossingPoint.x : crossingPoint.x * -1;
int yVal = crossingPoint.y > 0 ? crossingPoint.y : crossingPoint.y * -1;
int manhattanDistance = (xVal - 0) + (yVal - 0);
// Work out if it is shorter than the previously found one
if(manhattanDistance < shortestManhattanDistance)
{
shortestManhattanDistance = manhattanDistance;
}
}
Console.WriteLine("Part 1: The Manhattan distance from the central port to the closest intersection is " + shortestManhattanDistance);
}
static void Part2()
{
// Each line is one wire's path trace
var wire1 = File.ReadAllLines("input.txt")[0];
var wire2 = File.ReadAllLines("input.txt")[1];
List<string> wire1Commands = wire1.Split(',').ToList();
List<string> wire2Commands = wire2.Split(',').ToList();
// Find all points each wire touches
List<WireTouchPoint> wire1TouchPoints = FindAllWireTouchPoints(wire1Commands);
List<WireTouchPoint> wire2TouchPoints = FindAllWireTouchPoints(wire2Commands);
// Find all points where the two wires cross
var crossingPoints = wire1TouchPoints.Intersect(wire2TouchPoints, new WireTouchPointComparer()).Where(cp => cp.x != 0 && cp.y != 0);
// Declare a large default minimum steps, probably should be setting as null and null-checking later but multitasking while writing this so cba
int minimumSteps = 9999999;
foreach(WireTouchPoint crossingPoint in crossingPoints)
{
// Calculate the number of steps each wire takes to reach each the intersection
// 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.
// Calculate the minimum number of steps each wire takes to reach the crossing point (using the index rather than index + 1 as the lists are zero-indexed ordered by the route taken but we want to ignore the start co-ordinates) - this will always return the first (i.e. closest) index
int steps1 = wire1TouchPoints.FindIndex(tp => tp.x == crossingPoint.x && tp.y == crossingPoint.y);
int steps2 = wire2TouchPoints.FindIndex(tp => tp.x == crossingPoint.x && tp.y == crossingPoint.y);
int totalSteps = steps1 + steps2;
// Work out if it is fewer steps than the previously found one
if(totalSteps < minimumSteps)
{
minimumSteps = totalSteps;
}
}
Console.WriteLine("Part 2: The fewest combined steps the wires must take to reach an intersection is " + minimumSteps);
}
}
}
+40
View File
@@ -0,0 +1,40 @@
--- Day 3: Crossed Wires ---
The gravity assist was successful, and you're well on your way to the Venus refuelling station. During the rush back on Earth, the fuel management system wasn't completely installed, so that's next on the priority list.
Opening the front panel reveals a jumble of wires. Specifically, two wires are connected to a central port and extend outward on a grid. You trace the path each wire takes as it leaves the central port, one wire per line of text (your puzzle input).
The wires twist and turn, but the two wires occasionally cross paths. To fix the circuit, you need to find the intersection point closest to the central port. Because the wires are on a grid, use the Manhattan distance for this measurement. While the wires do technically cross right at the central port where they both start, this point does not count, nor does a wire count as crossing with itself.
For example, if the first wire's path is R8,U5,L5,D3, then starting from the central port (o), it goes right 8, up 5, left 5, and finally down 3:
...........
...........
...........
....+----+.
....|....|.
....|....|.
....|....|.
.........|.
.o-------+.
...........
Then, if the second wire's path is U7,R6,D4,L4, it goes up 7, right 6, down 4, and left 4:
...........
.+-----+...
.|.....|...
.|..+--X-+.
.|..|..|.|.
.|.-X--+.|.
.|..|....|.
.|.......|.
.o-------+.
...........
These wires cross at two locations (marked X), but the lower-left one is closer to the central port: its distance is 3 + 3 = 6.
Here are a few more examples:
R75,D30,R83,U83,L12,D49,R71,U7,L72
U62,R66,U55,R34,D71,R55,D58,R83 = distance 159
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?
+28
View File
@@ -0,0 +1,28 @@
--- 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?
+2
View File
@@ -0,0 +1,2 @@
R1008,U336,R184,D967,R451,D742,L235,U219,R57,D439,R869,U207,L574,U670,L808,D675,L203,D370,L279,U448,L890,U297,R279,D613,L411,D530,L372,D88,R986,U444,R319,D95,L385,D674,R887,U855,R794,U783,R633,U167,L587,D545,L726,D196,R681,U609,R677,U881,R153,D724,L63,U246,R343,U315,R580,U872,L516,U95,R463,D809,R9,U739,R540,U670,L434,D699,L158,U47,L383,D483,L341,U61,R933,D269,R816,D589,R488,D169,R972,D534,L995,D277,L887,D657,R628,D322,R753,U813,L284,D237,R676,D880,L50,D965,L401,D619,R858,U313,L156,U535,R664,U447,L251,U168,L352,U881,L734,U270,L177,D903,L114,U998,L102,D149,R848,D586,L98,D157,R942,U496,R857,U362,R398,U86,R469,U358,L721,D631,R176,D365,L112,U472,L557,D153,R97,D639,L457,U566,R570,U106,R504,D292,L94,U499,R358,U653,L704,D627,R544,D24,L407,U513,R28,U643,L510,U579,R825,D376,L867,U999,R134,D734,R654,D989,L920,U872,R64,U626,R751,D425,R620,U274,L471,D83,R979,U577,L43,D320,R673,D187,R300,U134,L451,D717,R857,U576,R570,U988,R745,U840,R799,U809,R573,U354,L208,D976,L417,U473,L555,U563,L955,U823,R712,D869,L145,D735,L780,D74,R421,U42,L158,U689,R718,D455,L670,U128,L744,U401,R149,U102,L122,U832,R872,D40,R45,D325,L553,U980,L565,D497,L435,U647,L209,D822,L593,D28,R936,U95,R349,U511,L243,U895,R421,U336,L986,U264,R376,D183,R480,D947,R416,D706,R118,D799,R424,D615,R384,U185,L338,U14,R576,D901,L734,D417,L62,D254,R784,D973,R987,D848,R32,D72,L535,D633,L668,D664,R308,D474,L418,D39,L473,U388,L518,D544,R118,D948,L844,D956,R605,U14,L948,D78,L689,U443,L996,U932,R81,D879,R556,D633,R131
L993,U227,L414,U228,L304,U53,R695,U765,R162,D264,L530,U870,R771,D395,R27,D200,L235,D834,L559,D128,R284,U912,L959,U358,R433,U404,L539,U799,R271,D734,L104,U261,R812,D15,L474,U887,R606,U366,L694,U156,R385,D667,L329,D434,R745,U776,L319,U756,R208,D457,R705,U999,R284,U98,L657,U214,R639,D937,R675,U444,L891,D587,L914,D4,R294,D896,R534,D584,L887,U878,L807,U202,R505,U234,L284,D5,R667,U261,L127,D482,R777,D223,L707,D468,L606,U345,L509,D967,R437,U995,R28,D376,L2,D959,L814,U702,L38,D154,L79,D439,L259,U143,L376,U700,R894,U165,L300,D58,R631,D47,R684,U935,R262,D857,R797,D599,L705,U792,R439,D444,R398,D887,L81,D40,R671,U332,L820,U252,R691,U412,L794,D661,R810,U157,R858,U566,R892,D543,R10,D725,L653,D812,R733,D804,R816,U862,R994,U221,L33,U271,R766,D591,R575,D970,R152,D693,L916,U404,L658,D847,L605,D433,L583,U587,L129,D103,R407,U780,L901,D676,L846,D687,L9,D47,R295,D597,L808,U134,L186,D676,L62,U305,L73,D369,L468,U30,L472,U280,L413,U961,L98,D966,R308,D178,L21,D789,L871,D671,R665,U927,L906,U633,L135,D894,R110,D205,R324,D665,R143,D450,L978,U385,R442,D853,L518,U542,R211,U857,R119,D872,L246,U380,L874,U463,R153,U982,R832,D784,L652,U545,R71,U386,R427,D827,R986,U870,R959,U232,R509,U675,R196,U389,R944,U149,R152,U571,R527,U495,L441,U511,L899,D996,L707,D455,L358,D423,L14,D427,R144,D703,L243,U157,R876,D538,R26,D577,L385,U622,L149,D852,L225,U475,L811,D520,L226,U523,L338,D79,R565,U766,L609,U496,L189,D446,R63,U396,L629,U312,L841,D639,R466,U808,L60,D589,L146,U114,R165,U96,L809,D704,L61