diff --git a/12input.txt b/12input.txt new file mode 100644 index 0000000..cc7929c --- /dev/null +++ b/12input.txt @@ -0,0 +1,783 @@ +N4 +F85 +L90 +N4 +E3 +L90 +E1 +L90 +W4 +R270 +S5 +F54 +N5 +W4 +L90 +N1 +F55 +L90 +S2 +N2 +L180 +F97 +W1 +F55 +N1 +L180 +F45 +F49 +L90 +F76 +R90 +S3 +F35 +N3 +W1 +S4 +R90 +S4 +F83 +L90 +S1 +F41 +S2 +R90 +F98 +N5 +F51 +L90 +N4 +W1 +F73 +W5 +F34 +S3 +R180 +F85 +N1 +F74 +W4 +F97 +L270 +F65 +W5 +R90 +S1 +W5 +L90 +W2 +N4 +N1 +F81 +S3 +L270 +F96 +W2 +F39 +F27 +W4 +L180 +F75 +N4 +W2 +F38 +R90 +W4 +F100 +R180 +E5 +R180 +E5 +R90 +S5 +L90 +F17 +W3 +N5 +F9 +N1 +W4 +F80 +S1 +W4 +F50 +R180 +W4 +L90 +E4 +F78 +N3 +F86 +W2 +R90 +F46 +S3 +W5 +L180 +S1 +L90 +L90 +F54 +R90 +N5 +E5 +F83 +S4 +W3 +R180 +E4 +N5 +E5 +F90 +W1 +S3 +W5 +F91 +L90 +N1 +F22 +E4 +S2 +F65 +R90 +F16 +R90 +E4 +R180 +W3 +R90 +F94 +L180 +F2 +W1 +R180 +N1 +F59 +R270 +E2 +R90 +S3 +S3 +R90 +F52 +N2 +L90 +R90 +E5 +L90 +R180 +S3 +F26 +E4 +S1 +W5 +R90 +E5 +F69 +E2 +L90 +S2 +E3 +S5 +W2 +S3 +W3 +F78 +N5 +E5 +F87 +L90 +W5 +S1 +L90 +F21 +L90 +F80 +W2 +N4 +W2 +L270 +F52 +L90 +R90 +N3 +F29 +L90 +F20 +R90 +W1 +R90 +E1 +F100 +W1 +S4 +E3 +S3 +F73 +S4 +L90 +S5 +W4 +R180 +E4 +F32 +S1 +R270 +E4 +S5 +L90 +F64 +F12 +E5 +F59 +E4 +F85 +N2 +F27 +R90 +W4 +N2 +F7 +N2 +E3 +F70 +W1 +R180 +F50 +R270 +F43 +L90 +E3 +F23 +W4 +N2 +F15 +L180 +N4 +F31 +R90 +F35 +N1 +E2 +S4 +E4 +N1 +F98 +S2 +W5 +N5 +R90 +F59 +W2 +F22 +S1 +S4 +W5 +F10 +L90 +E3 +R90 +W4 +F11 +N3 +L90 +F12 +S1 +R90 +F25 +E3 +E1 +R90 +F66 +S5 +E1 +F33 +W1 +F57 +L90 +N4 +F44 +W4 +L90 +N5 +L270 +F25 +S3 +F20 +L180 +E4 +R90 +F49 +E4 +S1 +F96 +W2 +R90 +F26 +L180 +F78 +L180 +F88 +W2 +N4 +E1 +F12 +E4 +F81 +E1 +F97 +S3 +E2 +F21 +R180 +S4 +E1 +S4 +E5 +R90 +E4 +S2 +S1 +L90 +L90 +W1 +S5 +L180 +S2 +W2 +S2 +E5 +N5 +W5 +F57 +R270 +N1 +W3 +N5 +F47 +R180 +F28 +S1 +E1 +L180 +F34 +N1 +F96 +S5 +W2 +L90 +S5 +F48 +L90 +E4 +S5 +F24 +L90 +F95 +W1 +R180 +E2 +F76 +R90 +N1 +F51 +S3 +E4 +F24 +S2 +E5 +R90 +E1 +R90 +S4 +E3 +F70 +S1 +E4 +F43 +R180 +F84 +E2 +R90 +F70 +E1 +R90 +F85 +E2 +L90 +F29 +S4 +F73 +F25 +S5 +R180 +S2 +F66 +S3 +F5 +F52 +N3 +L180 +E5 +F14 +W5 +S5 +F81 +N4 +F67 +E3 +R180 +S1 +W4 +F96 +F100 +L270 +F65 +R90 +W2 +S5 +E3 +F32 +F61 +L180 +F57 +N2 +L90 +F10 +F57 +N2 +R90 +F34 +E5 +F13 +E3 +N2 +L90 +N2 +F68 +N3 +W1 +F49 +L90 +F91 +E3 +F84 +F73 +L90 +S1 +E3 +S4 +F66 +L90 +N3 +E2 +S1 +L180 +S5 +L90 +S4 +E4 +S1 +L180 +R90 +S2 +W4 +F59 +L90 +F6 +R90 +W2 +S5 +R180 +S1 +S2 +F96 +W1 +R180 +F87 +R90 +F67 +W5 +L270 +E4 +F51 +R180 +S4 +L90 +F59 +E5 +F66 +E2 +S1 +E4 +F79 +S1 +L180 +F41 +R270 +F66 +L90 +F90 +E4 +S2 +R180 +W2 +F4 +L90 +S5 +L90 +F18 +L90 +F90 +R90 +N4 +E5 +R90 +E4 +S2 +W3 +F97 +W4 +F53 +L90 +S5 +F61 +S2 +F72 +E4 +R90 +S2 +R90 +S2 +F56 +W2 +R180 +W3 +L90 +F31 +F65 +S2 +F11 +N5 +W4 +L270 +E2 +N4 +L90 +F90 +L90 +N3 +L90 +E3 +L90 +F8 +S2 +F63 +L270 +E4 +F51 +F40 +L90 +F34 +W1 +L180 +F79 +N5 +R90 +L90 +W3 +L180 +W1 +L180 +E1 +R90 +N2 +E5 +S1 +R90 +E3 +S2 +E2 +F56 +S2 +W3 +F95 +R90 +N4 +R270 +W4 +S5 +F33 +L180 +N3 +F95 +N1 +E2 +S3 +F4 +L90 +F66 +S1 +R90 +E2 +S3 +F11 +R90 +S5 +N1 +E2 +F64 +N2 +W5 +S2 +F2 +N1 +R90 +N4 +L180 +N1 +F95 +W5 +F99 +F6 +N4 +F69 +S2 +E4 +F49 +R90 +F91 +F76 +R90 +S1 +E2 +S3 +F79 +W4 +L90 +F18 +S5 +R90 +E4 +S1 +F91 +N3 +F40 +E2 +L90 +W2 +S4 +R90 +S1 +R90 +F59 +W3 +N2 +W1 +F86 +R90 +F32 +S1 +F22 +S2 +F4 +S3 +E5 +S4 +S4 +E5 +S4 +F36 +E4 +L90 +F35 +L180 +N1 +W1 +L90 +N4 +R180 +R90 +F22 +R180 +E2 +S2 +W5 +F99 +E2 +S3 +F22 +E1 +L180 +S2 +L180 +W4 +R270 +F26 +N5 +E2 +F89 +E5 +L90 +N4 +R90 +W4 +L270 +W5 +N5 +W4 +S2 +E3 +N4 +W1 +F95 +W1 +F10 +N3 +R90 +W1 +F73 +W1 +N3 +F33 +L180 +E3 +R90 +R90 +N2 +E4 +E5 +W4 +N1 +F91 +N1 +W1 +F49 +S2 +E5 +S3 +F43 +W5 +F34 +E3 +E1 +N1 +E3 +L180 +W2 +F27 +L180 +E5 +F28 +R90 +W1 +L90 +F99 +S2 +F48 +W1 +W1 +R180 +W1 +L180 +F35 \ No newline at end of file diff --git a/2020.csproj b/2020.csproj index 390ba66..953c3e8 100644 --- a/2020.csproj +++ b/2020.csproj @@ -44,6 +44,9 @@ PreserveNewest + + PreserveNewest + diff --git a/Program.cs b/Program.cs index c54995c..dc64140 100644 --- a/Program.cs +++ b/Program.cs @@ -16,6 +16,7 @@ Q09.Go(); Q10.Go(); Q11.Go(); + Q12.Go(); Util.Log($"Total time={(System.DateTime.Now - start).TotalMilliseconds}ms"); } } diff --git a/Q12.cs b/Q12.cs new file mode 100644 index 0000000..93e6a52 --- /dev/null +++ b/Q12.cs @@ -0,0 +1,227 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; + +namespace _2020 +{ + class Q12 + { + [DebuggerDisplay("({x}, {y})")] + struct Vec2 + { + public int x; + public int y; + } + + static Vec2 shipPosition; + static Vec2 waypointPosition = new Vec2() { x = 10, y = 1 }; + static int facingDir = 90; + + static List> instructions = new List>(); + + public static void Go() + { + var start = DateTime.Now; + MakeList(); + Util.Log($"Q12 MakeList took {(DateTime.Now - start).TotalMilliseconds}ms"); + var p1start = DateTime.Now; + Part1(); + Util.Log($"Q12 part1 took {(DateTime.Now - p1start).TotalMilliseconds}ms"); + var p2start = DateTime.Now; + Part2(); + Util.Log($"Q12 part2 took {(DateTime.Now - p2start).TotalMilliseconds}ms"); + + Util.Log($"Q12 took {(DateTime.Now - start).TotalMilliseconds}ms"); + } + + static void MakeList() + { + foreach (var line in File.ReadAllLines("12input.txt")) + { + instructions.Add(new Tuple(line[0], Convert.ToInt32(line[1..]) % 360)); + } + } + + static void MoveDir(ref Vec2 vec, char dir, int amount) + { + switch (dir) + { + case 'N': + vec.y += amount; + break; + + case 'S': + vec.y -= amount; + break; + + case 'E': + vec.x += amount; + break; + + case 'W': + vec.x -= amount; + break; + + default: + throw new Exception("Invalid MoveDir direction"); + } + } + + static void MoveShipDir(char dir, int amount) + { + MoveDir(ref shipPosition, dir, amount); + } + + static void MoveShipToWaypoint(int amount) + { + shipPosition.x += waypointPosition.x * amount; + shipPosition.y += waypointPosition.y * amount; + } + + static void MoveWaypointDir(char dir, int amount) + { + MoveDir(ref waypointPosition, dir, amount); + } + + static char GetFacingDir() + { + if (facingDir == 0) + { + return 'N'; + } + else if (facingDir == 90) + { + return 'E'; + } + else if (facingDir == 180) + { + return 'S'; + } + else if (facingDir == 270) + { + return 'W'; + } + + throw new Exception("Invalid facing dir"); + } + + static void RotateShipDir(char dir, int amount) + { + if (amount % 90 != 0) + { + throw new Exception("Turned toward a non-cardinal direction"); + } + + if (dir == 'R') + { + facingDir = (facingDir + amount) % 360; + } + else if (dir == 'L') + { + facingDir = (facingDir - amount); + while (facingDir < 0) + { + facingDir = 360 + facingDir; + } + } + else + { + throw new Exception("Invalid rotation dir"); + } + } + + static void RotateWaypointDir(char dir, int amount) + { + if (amount % 90 != 0) + { + throw new Exception("Turned toward a non-cardinal direction"); + } + + switch (amount % 360) + { + case 180: + waypointPosition.y = -waypointPosition.y; + waypointPosition.x = -waypointPosition.x; + break; + + case 90: + if (dir == 'R') + { + var tmp = waypointPosition.x; + waypointPosition.x = waypointPosition.y; + waypointPosition.y = -tmp; + } + else if (dir == 'L') + { + var tmp = waypointPosition.y; + waypointPosition.y = waypointPosition.x; + waypointPosition.x = -tmp; + } + break; + + case 270: + RotateWaypointDir(dir == 'R' ? 'L' : 'R', 90); + break; + + default: + throw new Exception("Unexpected waypoint rotation direction"); + } + } + + static void Part1() + { + foreach (var inst in instructions) + { + switch (inst.Item1) + { + case 'N': + case 'S': + case 'E': + case 'W': + MoveShipDir(inst.Item1, inst.Item2); + break; + + case 'F': + MoveShipDir(GetFacingDir(), inst.Item2); + break; + + case 'R': + case 'L': + RotateShipDir(inst.Item1, inst.Item2); + break; + } + } + + Util.Log($"Q12Part1: finished facing {facingDir}, x={shipPosition.x}, y={shipPosition.y}, manhattan dist={Math.Abs(shipPosition.x) + Math.Abs(shipPosition.y)}"); + } + + static void Part2() + { + shipPosition = new Vec2(); + foreach (var inst in instructions) + { + switch (inst.Item1) + { + case 'N': + case 'S': + case 'E': + case 'W': + MoveWaypointDir(inst.Item1, inst.Item2); + break; + + case 'F': + MoveShipToWaypoint(inst.Item2); + break; + + case 'R': + case 'L': + RotateWaypointDir(inst.Item1, inst.Item2); + break; + } + } + + Util.Log($"Q12Part2: finished facing {facingDir}, x={shipPosition.x}, y={shipPosition.y}, manhattan dist={Math.Abs(shipPosition.x) + Math.Abs(shipPosition.y)}"); + } + } +}