diff options
Diffstat (limited to '2020/day-12')
-rw-r--r-- | 2020/day-12/README.org | 226 | ||||
-rwxr-xr-x | 2020/day-12/day-12.raku | 83 | ||||
-rw-r--r-- | 2020/day-12/input | 770 |
3 files changed, 1079 insertions, 0 deletions
diff --git a/2020/day-12/README.org b/2020/day-12/README.org new file mode 100644 index 0000000..4127135 --- /dev/null +++ b/2020/day-12/README.org @@ -0,0 +1,226 @@ +#+SETUPFILE: ~/.emacs.d/org-templates/level-3.org +#+HTML_LINK_UP: ../../index.html#2020 +#+OPTIONS: toc:1 +#+EXPORT_FILE_NAME: index +#+TITLE: Day 12 - Rain Risk + +* Puzzle +- This puzzle is taken from: https://adventofcode.com/2020/day/12 + +Your ferry made decent progress toward the island, but the storm came in +faster than anyone expected. The ferry needs to take evasive actions! + +Unfortunately, the ship's navigation computer seems to be +malfunctioning; rather than giving a route directly to safety, it +produced extremely circuitous instructions. When the captain uses the PA +system to ask if anyone can help, you quickly volunteer. + +The navigation instructions (your puzzle input) consists of a sequence +of single-character actions paired with integer input values. After +staring at them for a few minutes, you work out what they probably mean: + +- Action N means to move north by the given value. +- Action S means to move south by the given value. +- Action E means to move east by the given value. +- Action W means to move west by the given value. +- Action L means to turn left the given number of degrees. +- Action R means to turn right the given number of degrees. +- Action F means to move forward by the given value in the direction the + ship is currently facing. + +The ship starts by facing east. Only the L and R actions change the +direction the ship is facing. (That is, if the ship is facing east and +the next instruction is N10, the ship would move north 10 units, but +would still move east if the following action were F.) + +For example: +#+BEGIN_SRC +F10 +N3 +F7 +R90 +F11 +#+END_SRC + +These instructions would be handled as follows: + +- F10 would move the ship 10 units east (because the ship starts by + facing east) to east 10, north 0. +- N3 would move the ship 3 units north to east 10, north 3. +- F7 would move the ship another 7 units east (because the ship is still + facing east) to east 17, north 3. +- R90 would cause the ship to turn right by 90 degrees and face south; + it remains at east 17, north 3. +- F11 would move the ship 11 units south to east 17, south 8. + +At the end of these instructions, the ship's Manhattan distance (sum of +the absolute values of its east/west position and its north/south +position) from its starting position is 17 + 8 = 25. + +Figure out where the navigation instructions lead. What is the Manhattan +distance between that location and the ship's starting position? +** Part 2 +Before you can give the destination to the captain, you realize that the +actual action meanings were printed on the back of the instructions the +whole time. + +Almost all of the actions indicate how to move a waypoint which is +relative to the ship's position: + +- Action N means to move the waypoint north by the given value. +- Action S means to move the waypoint south by the given value. +- Action E means to move the waypoint east by the given value. +- Action W means to move the waypoint west by the given value. +- Action L means to rotate the waypoint around the ship left + (counter-clockwise) the given number of degrees. +- Action R means to rotate the waypoint around the ship right + (clockwise) the given number of degrees. +- Action F means to move forward to the waypoint a number of times equal + to the given value. + +The waypoint starts 10 units east and 1 unit north relative to the ship. +The waypoint is relative to the ship; that is, if the ship moves, the +waypoint moves with it. + +For example, using the same instructions as above: + +- F10 moves the ship to the waypoint 10 times (a total of 100 units east + and 10 units north), leaving the ship at east 100, north 10. The + waypoint stays 10 units east and 1 unit north of the ship. +- N3 moves the waypoint 3 units north to 10 units east and 4 units north + of the ship. The ship remains at east 100, north 10. +- F7 moves the ship to the waypoint 7 times (a total of 70 units east + and 28 units north), leaving the ship at east 170, north 38. The + waypoint stays 10 units east and 4 units north of the ship. +- R90 rotates the waypoint around the ship clockwise 90 degrees, moving + it to 4 units east and 10 units south of the ship. The ship remains at + east 170, north 38. +- F11 moves the ship to the waypoint 11 times (a total of 44 units east + and 110 units south), leaving the ship at east 214, south 72. The + waypoint stays 4 units east and 10 units south of the ship. + +After these operations, the ship's Manhattan distance from its starting +position is 214 + 72 = 286. + +Figure out where the navigation instructions actually lead. What is the +Manhattan distance between that location and the ship's starting +position? +* Solution +=@instructions= hold the instructions & =Instruction= is a token that will +parse them. It seperates the action from value. =@ship= holds the position +of ship, 0th index will hold east/west position where east is positive & +1st index holds north/south position where north will be positive. +#+BEGIN_SRC raku +unit sub MAIN ( + Int $part where * == 1|2 = 1 #= part to run (1 or 2) +); + +my @instructions = "input".IO.lines; + +# east/west, north/south. east/north are positive. +my Int @ship[2] = 0, 0; + +my token Instruction { (N|S|E|W|L|R|F) (\d+) }; +if $part == 1 { + ... +} elsif $part == 2 { + ... +} +... +#+END_SRC + +For part 1, =$facing= holds index that tells us the direction our ship is +facing. =@directions= holds all the possible directions the ship face. +Next we just follow the instructions for when the action is =N|S|E|W=. For +action "L" & "R", we have to perform some checks to wrap =$facing= around. + +=$facing= holds the index of =@directions= & that is why it needs to be +kept between 0 to 3. The for loop in "L" & "R" is for the number of time +the turning action needs to be performed. For example, if the value is +180 then we turn 2 times. + +"F" just handles how the ship goes forward according to which direction +it is in. +#+BEGIN_SRC raku +my Str @directions[4] = <E S W N>; +my Int $facing = 0; + +for @instructions -> $instruction { + if $instruction ~~ &Instruction -> $match { + given $match[0] { + when 'N' { @ship[1] += $match[1]; } + when 'S' { @ship[1] -= $match[1]; } + when 'E' { @ship[0] += $match[1]; } + when 'W' { @ship[0] -= $match[1]; } + when 'L' { + for 1..($match[1] / 90).Int { + if $facing == 0 { + $facing = 3; + } else { + $facing -= 1; + } + } + } + when 'R' { + for 1..($match[1] / 90).Int { + if $facing == 3 { + $facing = 0; + } else { + $facing += 1; + } + } + } + when 'F' { + given @directions[$facing] { + when 'N' { @ship[1] += $match[1]; } + when 'S' { @ship[1] -= $match[1]; } + when 'E' { @ship[0] += $match[1]; } + when 'W' { @ship[0] -= $match[1]; } + } + } + } + } +} +#+END_SRC + +For solution we just print the sum of numbers in =@ship=, their absolute +values are considered. +#+BEGIN_SRC raku +say "Part $part: ", [+] @ship.map(*.abs); +#+END_SRC +** Part 2 +For part 2, we define =@waypoint= which will hold the position of the +waypoint. =N|S|E|W= is modified according to the new rules, it'll update +the position of waypoint now instead of the ship. + +"L" & "R" now rotate the waypoint in respective directions. And "F" +moves the ship forward according to the new rules. +#+BEGIN_SRC raku +# east/west, north/south. east/north are positive. +my Int @waypoint[2] = 10, 1; + +for @instructions -> $instruction { + if $instruction ~~ &Instruction -> $match { + given $match[0] { + when 'N' { @waypoint[1] += $match[1]; } + when 'S' { @waypoint[1] -= $match[1]; } + when 'E' { @waypoint[0] += $match[1]; } + when 'W' { @waypoint[0] -= $match[1]; } + when 'L' { + for 1..($match[1] / 90).Int { + @waypoint = -@waypoint[1], @waypoint[0]; + } + } + when 'R' { + for 1..($match[1] / 90).Int { + @waypoint = @waypoint[1], -@waypoint[0]; + } + } + when 'F' { + @ship[0] += @waypoint[0] * $match[1]; + @ship[1] += @waypoint[1] * $match[1]; + } + } + } +} +#+END_SRC diff --git a/2020/day-12/day-12.raku b/2020/day-12/day-12.raku new file mode 100755 index 0000000..4e66caa --- /dev/null +++ b/2020/day-12/day-12.raku @@ -0,0 +1,83 @@ +#!/usr/bin/env raku + +unit sub MAIN ( + Int $part where * == 1|2 = 1 #= part to run (1 or 2) +); + +my @instructions = "input".IO.lines; + +# east/west, north/south. east/north are positive. +my Int @ship[2] = 0, 0; + +my token Instruction { (N|S|E|W|L|R|F) (\d+) }; +if $part == 1 { + my Str @directions[4] = <E S W N>; + my Int $facing = 0; + + for @instructions -> $instruction { + if $instruction ~~ &Instruction -> $match { + given $match[0] { + when 'N' { @ship[1] += $match[1]; } + when 'S' { @ship[1] -= $match[1]; } + when 'E' { @ship[0] += $match[1]; } + when 'W' { @ship[0] -= $match[1]; } + when 'L' { + for 1..($match[1] / 90).Int { + if $facing == 0 { + $facing = 3; + } else { + $facing -= 1; + } + } + } + when 'R' { + for 1..($match[1] / 90).Int { + if $facing == 3 { + $facing = 0; + } else { + $facing += 1; + } + } + } + when 'F' { + given @directions[$facing] { + when 'N' { @ship[1] += $match[1]; } + when 'S' { @ship[1] -= $match[1]; } + when 'E' { @ship[0] += $match[1]; } + when 'W' { @ship[0] -= $match[1]; } + } + } + } + } + } +} elsif $part == 2 { + # east/west, north/south. east/north are positive. + my Int @waypoint[2] = 10, 1; + + for @instructions -> $instruction { + if $instruction ~~ &Instruction -> $match { + given $match[0] { + when 'N' { @waypoint[1] += $match[1]; } + when 'S' { @waypoint[1] -= $match[1]; } + when 'E' { @waypoint[0] += $match[1]; } + when 'W' { @waypoint[0] -= $match[1]; } + when 'L' { + for 1..($match[1] / 90).Int { + @waypoint = -@waypoint[1], @waypoint[0]; + } + } + when 'R' { + for 1..($match[1] / 90).Int { + @waypoint = @waypoint[1], -@waypoint[0]; + } + } + when 'F' { + @ship[0] += @waypoint[0] * $match[1]; + @ship[1] += @waypoint[1] * $match[1]; + } + } + } + } +} + +say "Part $part: ", [+] @ship.map(*.abs); diff --git a/2020/day-12/input b/2020/day-12/input new file mode 100644 index 0000000..c64cbfd --- /dev/null +++ b/2020/day-12/input @@ -0,0 +1,770 @@ +R90 +F58 +S2 +E4 +F28 +W3 +N2 +F25 +E1 +F24 +W2 +F91 +S3 +F83 +L90 +F24 +R90 +N3 +R90 +F5 +W5 +E1 +S1 +E5 +F47 +F83 +N1 +F64 +W2 +R90 +S1 +R180 +N2 +R180 +S3 +F35 +E2 +S3 +W2 +R270 +F57 +E5 +F100 +N3 +L90 +F70 +E5 +L90 +F65 +L90 +S2 +W5 +F73 +L90 +E3 +R90 +W2 +S2 +L180 +E4 +W3 +R90 +E2 +F18 +N4 +W5 +R90 +S1 +F55 +W2 +L90 +S1 +L180 +E4 +N1 +R90 +F31 +N5 +E4 +R90 +W4 +F18 +W4 +N2 +L90 +F6 +N3 +L180 +F89 +R90 +N4 +L180 +S4 +W1 +F87 +N1 +F80 +E4 +R90 +N4 +F38 +E5 +F74 +S4 +R180 +S1 +L90 +W1 +F88 +S1 +F42 +S1 +R90 +F2 +R90 +E2 +S1 +F57 +E1 +F53 +R180 +F97 +W2 +R90 +F70 +R180 +W1 +R180 +W5 +E5 +N1 +E5 +F63 +N3 +F24 +L90 +S5 +W5 +R90 +W4 +F27 +R90 +E2 +L180 +E4 +F16 +L90 +F47 +S3 +E1 +S2 +L90 +W5 +F80 +E4 +F10 +N5 +E3 +N4 +W2 +L90 +E1 +F83 +R180 +S4 +L90 +E1 +F94 +N2 +R90 +S5 +L180 +E1 +F40 +E5 +L180 +W5 +F57 +E1 +N5 +W5 +F62 +L180 +W3 +F12 +E4 +F93 +R270 +F8 +S3 +W3 +L90 +W1 +N1 +E4 +L90 +E2 +S2 +E1 +L270 +E5 +N5 +F81 +L90 +W5 +F82 +E5 +L90 +F24 +F3 +F14 +L180 +N5 +E1 +F11 +R90 +F22 +L90 +S1 +F82 +S4 +F38 +L90 +F31 +R180 +W4 +F88 +E3 +R90 +N5 +F9 +S3 +W4 +L90 +W5 +R90 +F5 +S4 +F91 +N4 +S4 +W4 +S4 +F78 +N2 +F67 +L180 +N3 +R90 +F65 +N2 +E1 +F46 +E2 +L180 +S4 +E2 +F98 +L90 +W2 +N1 +E3 +F7 +S4 +F90 +S2 +W3 +R90 +F30 +E4 +F2 +L90 +F17 +E4 +R90 +F94 +N3 +E5 +R180 +S4 +F76 +E2 +F94 +R90 +N5 +W2 +F89 +W1 +F83 +N5 +W5 +F62 +S1 +W4 +N5 +E2 +R90 +F14 +R90 +N5 +W4 +R180 +E2 +R90 +L90 +F67 +N4 +L90 +E4 +F93 +W5 +F85 +L180 +F45 +W2 +F78 +N3 +F90 +L90 +W1 +S2 +L90 +S5 +E5 +F82 +S4 +F36 +E5 +L90 +E1 +F13 +S2 +E3 +F65 +L90 +E3 +E4 +F1 +W5 +S3 +F14 +L90 +F47 +L90 +S3 +W4 +F18 +E1 +N3 +E5 +F58 +E5 +S1 +W2 +F48 +W5 +F65 +N5 +E1 +N3 +R90 +N2 +L90 +N4 +F21 +R90 +F58 +W1 +F7 +R90 +E4 +N5 +F47 +W4 +L90 +N4 +R90 +E1 +L180 +F8 +E3 +W4 +F41 +E3 +S5 +E5 +S3 +E3 +F14 +N4 +R90 +W3 +L90 +E5 +R180 +W4 +S1 +N2 +F93 +L90 +F41 +R180 +F37 +R90 +E1 +L180 +N5 +F96 +W3 +R90 +E1 +F88 +S2 +E2 +L90 +N2 +W4 +F34 +E4 +F69 +L90 +N3 +F18 +W3 +S4 +F44 +E2 +L90 +N2 +F55 +R90 +E1 +L90 +S5 +E2 +N3 +L90 +N1 +F55 +W5 +N2 +E2 +F20 +S2 +W5 +S1 +W5 +R180 +F100 +F44 +S2 +L90 +E3 +F98 +N3 +R90 +W4 +F14 +N2 +F87 +W5 +F12 +L180 +S2 +W1 +N1 +W1 +R90 +L180 +F64 +E2 +F41 +L90 +F20 +R270 +F91 +N4 +L180 +F28 +W4 +F40 +R90 +F40 +F36 +E3 +L270 +F76 +L90 +N2 +F15 +N5 +E4 +L180 +S1 +R90 +E1 +F81 +R90 +F96 +N1 +E5 +R90 +S5 +L90 +S1 +S4 +R90 +F30 +E1 +N5 +E2 +S3 +F97 +N3 +R90 +N1 +R90 +E3 +R180 +E3 +F8 +R90 +W2 +F27 +L90 +N5 +W3 +L90 +E5 +R180 +S1 +L90 +F51 +S4 +L180 +N1 +W4 +F71 +W2 +R90 +E4 +F29 +E4 +L90 +L90 +F68 +W2 +F57 +E3 +R90 +S2 +F94 +W4 +S2 +L180 +E3 +N2 +F52 +E3 +S1 +S5 +R90 +E1 +F35 +W3 +F53 +R270 +E3 +F81 +S2 +L90 +W4 +F86 +N5 +E4 +R90 +N5 +F99 +L180 +F65 +R90 +S2 +W3 +F33 +E3 +R270 +F34 +E1 +F56 +S2 +E5 +R180 +N2 +E3 +N3 +F30 +N2 +F22 +E5 +F10 +N2 +F16 +N1 +F31 +R90 +E2 +F78 +E4 +R180 +S3 +R90 +F80 +E5 +S1 +F49 +E1 +S2 +E4 +N4 +R90 +F9 +W1 +E4 +N3 +N5 +E4 +L90 +S5 +E2 +R90 +F74 +R180 +N2 +F98 +S2 +W4 +W4 +F73 +E2 +N4 +E1 +F25 +S2 +E5 +L90 +F96 +N2 +E3 +N3 +F16 +S5 +L90 +F43 +S2 +R90 +S1 +F46 +S3 +F82 +S5 +S4 +E5 +F58 +R90 +F51 +R90 +N4 +L90 +W3 +S4 +R90 +F15 +E1 +S4 +W3 +S2 +W1 +R90 +F76 +S1 +L180 +F5 +R180 +E1 +L180 +W3 +F47 +W4 +F68 +E5 +F75 +W3 +N1 +R90 +S1 +W5 +R90 +E2 +F78 +W2 +L90 +F24 +W5 +R90 +F75 +E1 +F35 +E5 +R90 +F57 +L180 +S1 +L90 +F90 +R180 +F63 +S3 +R180 +W3 +F79 +N5 +E4 +F81 +E3 +F6 +R90 +E4 +L90 +W5 +L180 +W2 +S4 +F26 +L90 +E5 +S3 +L90 +F3 +L90 +S2 +R90 +F55 +W5 +S1 +E3 +F63 +L180 +N2 +E2 +L90 +S4 +E3 +F18 +W4 +N2 +W5 +R90 +E5 +L90 +F96 +N3 +F7 +N1 +F87 +R90 +F53 +R90 +W5 +S3 +F94 |