Day 10 Part 2

This commit is contained in:
Adam Millerchip 2020-12-11 00:28:41 +09:00
parent a5b418cd44
commit c5745fbaaa
5 changed files with 170 additions and 12 deletions

View file

@ -2,7 +2,7 @@
My (attempted) solutions to [Advent of Code 2020](https://adventofcode.com/2020) in Elixir.
<img width="975" alt="image" src="https://user-images.githubusercontent.com/498229/101746064-b0663000-3b0e-11eb-81bd-92597dba329e.png">
<img width="975" alt="image" src="https://user-images.githubusercontent.com/498229/101786711-97c33d80-3b41-11eb-831a-d6a9b3670f30.png">
## Strategy

View file

@ -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.

31
day10/day10part2.exs Normal file
View file

@ -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()

104
day10/input Normal file
View file

@ -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

View file

@ -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