Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Advent of Code 2020 Day 12 Parts 1 and 2 solution by Mike LeSauvage
- public class FerryPathAnalyzer : MonoBehaviour
- {
- [SerializeField] TextAsset ferryPathTextfile = null; //Hooked up in the input text in the Unity editor.
- //The facing characters are indexed into by the ship's facing variable.
- //It is important that it proceeds clockwise around the cardinal points.
- static char[] FACING_CHARS = { 'N', 'E', 'S', 'W' };
- //Ship state
- //facing is unsigned so (facing-x) % 4 will always result in a number from 0-3.
- //This keeps it in the range of FACING_CHARS.
- uint facing = 1; //Equivalent to 'E' when indexing into FACING_CHARS.
- int westEast = 0;
- int northSouth = 0;
- //Waypoint state (for part 2)
- int wayPointNorthSouth = 1;
- int wayPointWestEast = 10;
- void Start()
- {
- string[] ferryPathStrings = ferryPathTextfile.text.Split('\n');
- //Solve Part one.
- foreach (string instruction in ferryPathStrings)
- {
- ParsePartOneDirections(instruction);
- }
- int manhattanDistance = Mathf.Abs(northSouth) + Mathf.Abs(westEast);
- Debug.Log($"Part One Manhattan Distance: {manhattanDistance}");
- //Reset for part two and solve.
- westEast = 0;
- northSouth = 0;
- foreach (string instruction in ferryPathStrings)
- {
- ParsePartTwoDirections(instruction);
- }
- manhattanDistance = Mathf.Abs(northSouth) + Mathf.Abs(westEast);
- Debug.Log($"Part Two Manhattan Distance: {manhattanDistance}");
- }
- void ParsePartTwoDirections(string instruction)
- {
- char order = instruction[0];
- int quantity = int.Parse(instruction.Substring(1));
- switch (order)
- {
- case 'N':
- wayPointNorthSouth += quantity;
- break;
- case 'S':
- wayPointNorthSouth -= quantity;
- break;
- case 'E':
- wayPointWestEast += quantity;
- break;
- case 'W':
- wayPointWestEast -= quantity;
- break;
- case 'L':
- (wayPointWestEast, wayPointNorthSouth) = RotateCoordsByDegress(wayPointWestEast, wayPointNorthSouth, quantity); //Clockwise is +ve in standard coordinates.
- break;
- case 'R':
- (wayPointWestEast, wayPointNorthSouth) = RotateCoordsByDegress(wayPointWestEast, wayPointNorthSouth, -quantity); //Clockwise is -ve in standard coordinates.
- break;
- case 'F':
- westEast += wayPointWestEast * quantity;
- northSouth += wayPointNorthSouth * quantity;
- break;
- default:
- Debug.LogError($"Invalid instruction: {instruction}");
- break;
- }
- }
- // Rotates an (x,y) coordinate around the (0,0) position.
- // See https://en.wikipedia.org/wiki/Rotation_matrix for the matrix multiplication math that gives these formulas.
- (int, int) RotateCoordsByDegress(int x, int y, int degrees)
- {
- float rads = degrees * Mathf.Deg2Rad;
- int newX = Mathf.RoundToInt((x * Mathf.Cos(rads) - y * (int)Mathf.Sin(rads)));
- int newY = Mathf.RoundToInt((x * Mathf.Sin(rads) + y * (int)Mathf.Cos(rads)));
- return (newX, newY);
- }
- // Follows the ship directions for NSEW instructions.
- // L and R instructions update the ship's facing.
- // F instructions look at the ship's current facing and translate it to a new
- // N S E or W instruction of the same quantity, calling this parser again
- // to translate the distance.
- void ParsePartOneDirections(string instruction)
- {
- char order = instruction[0];
- int quantity = int.Parse(instruction.Substring(1));
- int turns;
- switch (order)
- {
- case 'N':
- northSouth += quantity;
- break;
- case 'S':
- northSouth -= quantity;
- break;
- case 'E':
- westEast += quantity;
- break;
- case 'W':
- westEast -= quantity;
- break;
- case 'L':
- turns = quantity / 90;
- facing = (facing - (uint)turns) % 4; //indexes left through FACING_CHARS, wrapping when out of bounds.
- break;
- case 'R':
- turns = quantity / 90;
- facing = (facing + (uint)turns) % 4; //indexes left through FACING_CHARS, wrapping when out of bounds.
- break;
- case 'F':
- string pseudoInstruction = $"{FACING_CHARS[facing]}{quantity}";
- ParsePartOneDirections(pseudoInstruction);
- break;
- default:
- Debug.LogError($"Invalid instruction: {instruction}");
- break;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement