summary refs log tree commit diff stats
path: root/2020/day-09/README.org
diff options
context:
space:
mode:
Diffstat (limited to '2020/day-09/README.org')
-rw-r--r--2020/day-09/README.org179
1 files changed, 179 insertions, 0 deletions
diff --git a/2020/day-09/README.org b/2020/day-09/README.org
new file mode 100644
index 0000000..db1eeab
--- /dev/null
+++ b/2020/day-09/README.org
@@ -0,0 +1,179 @@
+#+SETUPFILE: ~/.emacs.d/org-templates/level-3.org
+#+HTML_LINK_UP: ../../index.html#2020
+#+OPTIONS: toc:1
+#+EXPORT_FILE_NAME: index
+#+TITLE: Day 09 - Encoding Error
+
+* Puzzle
+- This puzzle is taken from: https://adventofcode.com/2020/day/9
+
+With your neighbor happily enjoying their video game, you turn your
+attention to an open data port on the little screen in the seat in front
+of you.
+
+Though the port is non-standard, you manage to connect it to your
+computer through the clever use of several paperclips. Upon connection,
+the port outputs a series of numbers (your puzzle input).
+
+The data appears to be encrypted with the eXchange-Masking Addition
+System (XMAS) which, conveniently for you, is an old cypher with an
+important weakness.
+
+XMAS starts by transmitting a preamble of 25 numbers. After that, each
+number you receive should be the sum of any two of the 25 immediately
+previous numbers. The two numbers will have different values, and there
+might be more than one such pair.
+
+For example, suppose your preamble consists of the numbers 1 through 25
+in a random order. To be valid, the next number must be the sum of two
+of those numbers:
+
+- 26 would be a valid next number, as it could be 1 plus 25 (or many
+  other pairs, like 2 and 24).
+- 49 would be a valid next number, as it is the sum of 24 and 25.
+- 100 would not be valid; no two of the previous 25 numbers sum to 100.
+- 50 would also not be valid; although 25 appears in the previous 25
+  numbers, the two numbers in the pair must be different.
+
+Suppose the 26th number is 45, and the first number (no longer an
+option, as it is more than 25 numbers ago) was 20. Now, for the next
+number to be valid, there needs to be some pair of numbers among 1-19,
+21-25, or 45 that add up to it:
+
+- 26 would still be a valid next number, as 1 and 25 are still within
+  the previous 25 numbers.
+- 65 would not be valid, as no two of the available numbers sum to it.
+- 64 and 66 would both be valid, as they are the result of 19+45 and
+  21+45 respectively.
+
+Here is a larger example which only considers the previous 5 numbers
+(and has a preamble of length 5):
+#+BEGIN_SRC
+35
+20
+15
+25
+47
+40
+62
+55
+65
+95
+102
+117
+150
+182
+127
+219
+299
+277
+309
+576
+#+END_SRC
+
+In this example, after the 5-number preamble, almost every number is the
+sum of two of the previous 5 numbers; the only number that does not
+follow this rule is 127.
+
+The first step of attacking the weakness in the XMAS data is to find the
+first number in the list (after the preamble) which is not the sum of
+two of the 25 numbers before it. What is the first number that does not
+have this property?
+** Part 2
+The final step in breaking the XMAS encryption relies on the invalid
+number you just found: you must find a contiguous set of at least two
+numbers in your list which sum to the invalid number from step 1.
+
+Again consider the above example:
+#+BEGIN_SRC
+35
+20
+15
+25
+47
+40
+62
+55
+65
+95
+102
+117
+150
+182
+127
+219
+299
+277
+309
+576
+#+END_SRC
+
+In this list, adding up all of the numbers from 15 through 40 produces
+the invalid number from step 1, 127. (Of course, the contiguous set of
+numbers in your actual list might be much longer.)
+
+To find the encryption weakness, add together the smallest and largest
+number in this contiguous range; in this example, these are 15 and 47,
+producing 62.
+
+What is the encryption weakness in your XMAS-encrypted list of numbers?
+* Solution
+Second part is dependent on the first part so we find the invalid number
+in all cases. =%invalid= stores the invalid number along with it's index.
+We check all possible combinations.
+
+I'm too tired to explain this in detail, maybe I'll add explanation
+later. Also, the solution isn't good.
+#+BEGIN_SRC raku
+my @numbers = "input".IO.lines>>.Int;
+my Int $solution;
+
+my Int $preamble_length = 25;
+my Int %invalid;
+
+MAIN: for @numbers.kv -> $idx, $num {
+    next if $idx < $preamble_length;
+
+    my @preamble = @numbers[$idx - $preamble_length..$idx - 1].sort;
+
+    my Bool $valid;
+    while pop @preamble -> $num_1 {
+        my $diff = $num - $num_1;
+        for @preamble -> $num_2 {
+            if $num_2 == $diff {
+                $valid = True;
+                next MAIN;
+            }
+        }
+    }
+
+    unless $valid {
+        %invalid<num> = $num;
+        %invalid<idx> = $idx;
+        $solution = %invalid<num> if $part == 1;
+        last MAIN;
+    }
+}
+
+if $part == 2 {
+    ...
+}
+
+say "Part $part: ", $solution;
+#+END_SRC
+** Part 2
+We brute force the second part too.
+#+BEGIN_SRC raku
+my @set = @numbers[0..%invalid<idx> - $preamble_length - 1];
+
+PART2: for @set.elems - 1 ... 0 -> $idx_1 {
+    for @set.elems - 1 ... 0 -> $idx_2 {
+        my $sum = [+] @set[$idx_1..$idx_2];
+        if $sum == %invalid<num> {
+            my @tmp = @set[$idx_1..$idx_2].sort;
+            $solution = @tmp[0] + @tmp[*-1];
+            last PART2;
+        }
+    }
+}
+#+END_SRC