summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--2020/day-12/README.org226
-rwxr-xr-x2020/day-12/day-12.raku83
-rw-r--r--2020/day-12/input770
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