From c5745fbaaa4732c74d251c56f08dce16e0860e39 Mon Sep 17 00:00:00 2001 From: Adam Millerchip Date: Fri, 11 Dec 2020 00:28:41 +0900 Subject: [PATCH] Day 10 Part 2 --- README.md | 2 +- day10/README | 42 +++++++++++++---- day10/day10part2.exs | 31 ++++++++++++ day10/input | 104 +++++++++++++++++++++++++++++++++++++++++ template/dayNpart1.exs | 3 +- 5 files changed, 170 insertions(+), 12 deletions(-) create mode 100644 day10/day10part2.exs create mode 100644 day10/input diff --git a/README.md b/README.md index 2b3af66..353ae89 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ My (attempted) solutions to [Advent of Code 2020](https://adventofcode.com/2020) in Elixir. -image +image ## Strategy diff --git a/day10/README b/day10/README index 08e40b4..d5bb337 100644 --- a/day10/README +++ b/day10/README @@ -5,7 +5,7 @@ Day 10 Notes +--------+ $ elixir day10part1.exs -**solved - will add answer after part 2 is complete** +2450 Thoughts: @@ -15,23 +15,47 @@ implementing exactly what the instructions say. In this case, we just need to sort the data, and compute the difference between all the pairs. -+-------------------+ -| Part 2 [UNSOLVED] | -+-------------------+ ++--------+ +| Part 2 | ++--------+ $ elixir day10part2.exs -... +32396521357312 Thoughts: -So far defeated on this one. I'm obviously missing a fundamental trick. +Fudge me this took me a long time (hours, including a walk in the park...) -I went down a massive rabbit hold calculating combinations, which didn't pay off. -Will leave this for now, and maybe come back to it later. +I spent far too long trying to find a mathematical answer based on combinations, and went down +another rabbit hole identifying the "removable" items and then trying to calculate the answer +based on that information. +Turns out the trick I was missing is graph theory. + +Finally, after drawing out the example on paper, I realised that the number of combinations +forms a directed graph, where the weight of each node inherits the weight of all its parents. +For the example case (excuse my ascii drawing skills): + +0(1)-1(1)-4(1)-5(1)-| + | ` | | + |---6(2) | + | | | + |---7(4)-| + | + 10(4)-11(4) + ` | + 12(8)-18(8)-19(8) + +So just need to make an algorithm that builds this graph, by iterating the sorted list +and checking the next 3 elements, keeping track of the weights as we go. It's actually simpler +than that, because we don't need to keep the connections around, just the weightings for each node. + +Finally, the weight of the max joltage adapter is the answer. +------------------+ | Overall Thoughts | +------------------+ -Not committing the input for now, in case somebody decides to @ me my answer or something. +Part 1 was very easy, part 2 was fiendish. Glad this wasn't an interview question. Sometimes my +brain just doesn't process certain types of problem. This was one of them. Once I made the +connection to a weighted graph it was fine. diff --git a/day10/day10part2.exs b/day10/day10part2.exs new file mode 100644 index 0000000..a63e4f0 --- /dev/null +++ b/day10/day10part2.exs @@ -0,0 +1,31 @@ +defmodule Day10Part2 do + def run do + File.read!("input") + |> String.split("\n", trim: true) + |> Enum.map(&String.to_integer/1) + |> count_arrangements() + |> IO.puts() + end + + def count_arrangements(list), do: count_arrangements(%{0 => 1}, [0 | Enum.sort(list)]) + + def count_arrangements(arrs_to, [last]), do: arrs_to[last] + + def count_arrangements(arrs_to, [current | rest]) do + rest + |> Enum.take(3) + |> count_reachable(current, arrs_to) + |> count_arrangements(rest) + end + + def count_reachable([], _a, arrs_to), do: arrs_to + + def count_reachable([b | rest], a, arrs_to) when b - a <= 3 do + arrs_to = Map.update(arrs_to, b, arrs_to[a], &(&1 + arrs_to[a])) + count_reachable(rest, a, arrs_to) + end + + def count_reachable([_b | rest], a, arrs_to), do: count_reachable(rest, a, arrs_to) +end + +Day10Part2.run() diff --git a/day10/input b/day10/input new file mode 100644 index 0000000..c472cf1 --- /dev/null +++ b/day10/input @@ -0,0 +1,104 @@ +2 +49 +78 +116 +143 +42 +142 +87 +132 +86 +67 +44 +136 +82 +125 +1 +108 +123 +46 +37 +137 +148 +106 +121 +10 +64 +165 +17 +102 +156 +22 +117 +31 +38 +24 +69 +131 +144 +162 +63 +171 +153 +90 +9 +107 +79 +7 +55 +138 +34 +52 +77 +152 +3 +158 +100 +45 +129 +130 +135 +23 +93 +96 +103 +124 +95 +8 +62 +39 +118 +164 +172 +75 +122 +20 +145 +14 +112 +61 +43 +141 +30 +85 +101 +151 +29 +113 +94 +68 +58 +76 +97 +28 +111 +128 +21 +11 +163 +161 +4 +168 +157 +27 +72 diff --git a/template/dayNpart1.exs b/template/dayNpart1.exs index a8a24f6..7c5faef 100644 --- a/template/dayNpart1.exs +++ b/template/dayNpart1.exs @@ -1,8 +1,7 @@ defmodule DayREPLACE_MEPart1 do def run do File.read!("input") - |> String.trim() - |> String.split("\n") + |> String.split("\n", trim: true) end end