Skip to content

Commit fc88780

Browse files
committed
Solve 2016/11
1 parent 30daad3 commit fc88780

4 files changed

Lines changed: 119 additions & 0 deletions

File tree

lib/2016/day_11.ex

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
defmodule AdventOfCode.Y2016.Day11 do
2+
@moduledoc """
3+
--- Day 11: Radioisotope Thermoelectric Generators ---
4+
Problem Link: https://adventofcode.com/2016/day/11
5+
Difficulty: l
6+
Tags: simulation graph state-space manual-parse
7+
"""
8+
alias Yog.Traversal.Implicit
9+
10+
def run(_input \\ "") do
11+
# Manual parse based on 2016_11.txt
12+
# Floor 1: strontium(S) G,M, plutonium(P) G,M
13+
# Floor 2: thulium(T) G, ruthenium(R) G,M, curium(C) G,M
14+
# Floor 3: thulium(T) M
15+
# Floor 4: -
16+
# State: {elevator_floor, sorted_pairs} where pair = {m_floor, g_floor}
17+
p1_initial = {1, sort_pairs([{1, 1}, {1, 1}, {3, 2}, {2, 2}, {2, 2}])}
18+
19+
# Part 2: add Elerium and Dilithium pairs on floor 1
20+
p2_initial = {1, sort_pairs([{1, 1}, {1, 1} | elem(p1_initial, 1)])}
21+
22+
{solve(p1_initial), solve(p2_initial)}
23+
end
24+
25+
defp solve(initial_state) do
26+
Implicit.implicit_fold(
27+
from: initial_state,
28+
using: :breadth_first,
29+
initial: nil,
30+
successors_of: fn state -> generate_successors(state) end,
31+
with: fn
32+
_acc, {4, pairs}, meta ->
33+
if Enum.all?(pairs, fn {m, g} -> m == 4 and g == 4 end) do
34+
{:halt, meta.depth}
35+
else
36+
{:continue, nil}
37+
end
38+
39+
_acc, _state, _meta ->
40+
{:continue, nil}
41+
end
42+
)
43+
end
44+
45+
defp generate_successors({floor, pairs}) do
46+
# Pruning: Don't go back down to empty floors
47+
lowest_occupied =
48+
Enum.find(1..4, fn f ->
49+
Enum.any?(pairs, fn {m, g} -> m == f or g == f end)
50+
end) || 4
51+
52+
next_floors = for f <- [floor - 1, floor + 1], f in 1..4, f >= lowest_occupied, do: f
53+
54+
items =
55+
for {pair, idx} <- Enum.with_index(pairs),
56+
type <- [:m, :g],
57+
item_floor(pair, type) == floor,
58+
do: {idx, type}
59+
60+
one_item = for item <- items, do: [item]
61+
two_items = for i1 <- items, i2 <- items, i1 < i2, do: [i1, i2]
62+
63+
for nf <- next_floors,
64+
load <- one_item ++ two_items,
65+
new_pairs = move(pairs, nf, load),
66+
valid?(new_pairs),
67+
do: {nf, sort_pairs(new_pairs)}
68+
end
69+
70+
defp item_floor({m, _g}, :m), do: m
71+
defp item_floor({_m, g}, :g), do: g
72+
73+
defp move(pairs, next_floor, items_to_move) do
74+
Enum.reduce(items_to_move, pairs, fn {idx, type}, acc ->
75+
List.update_at(acc, idx, fn {m, g} ->
76+
if type == :m, do: {next_floor, g}, else: {m, next_floor}
77+
end)
78+
end)
79+
end
80+
81+
defp sort_pairs(pairs), do: Enum.sort(pairs)
82+
83+
defp valid?(pairs) do
84+
Enum.all?(1..4, fn floor ->
85+
has_generator = Enum.any?(pairs, fn {_m, g} -> g == floor end)
86+
87+
if has_generator do
88+
Enum.all?(pairs, fn {m, g} ->
89+
if m == floor, do: g == floor, else: true
90+
end)
91+
else
92+
true
93+
end
94+
end)
95+
end
96+
end

priv/input_files/2016_11.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
The first floor contains a strontium generator, a strontium-compatible microchip, a plutonium generator, and a plutonium-compatible microchip.
2+
The second floor contains a thulium generator, a ruthenium generator, a ruthenium-compatible microchip, a curium generator, and a curium-compatible microchip.
3+
The third floor contains a thulium-compatible microchip.
4+
The fourth floor contains nothing relevant.

test/2016/day_11_test.exs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
defmodule AdventOfCode.Y2016.Day11Test do
2+
@moduledoc false
3+
4+
use ExUnit.Case, async: true
5+
@moduletag :y1611
6+
7+
alias AdventOfCode.Y2016.Day11, as: Solution
8+
9+
test "Year 2016, Day 11 run/1" do
10+
assert Solution.run() == {37, 61}
11+
end
12+
end

wiki/tags/manual-parse.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Tag: `manual-parse`
2+
3+
[← Tags Index](index.md) | [← Home](../../README.md)
4+
5+
| Year | Day | Title | Difficulty | Other Tags | Source |
6+
|------|:---:|-------|:----------:|------------|--------|
7+
| 2016 | [11](https://adventofcode.com/2016/day/11) | [Radioisotope Thermoelectric Generators](https://adventofcode.com/2016/day/11) | 🔴 | [simulation](simulation.md), [graph](graph.md), [state-space](state-space.md) | [day_11.ex](../../lib/2016/day_11.ex) |

0 commit comments

Comments
 (0)