Skip to content

Commit 2ffb40e

Browse files
committed
Add Days 6 to 8
1 parent 750c5d8 commit 2ffb40e

File tree

6 files changed

+2840
-0
lines changed

6 files changed

+2840
-0
lines changed

06.exs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
defmodule Puzzle do
2+
def cycles_to_loop(""), do: 0
3+
def cycles_to_loop(data) do
4+
initial_banks = init_banks(data)
5+
cycles_to_loop_(initial_banks)
6+
end
7+
8+
def loop_size(""), do: 0
9+
def loop_size(data) do
10+
initial_banks = init_banks(data)
11+
loop_size_(initial_banks)
12+
end
13+
14+
def reallocate(banks) do
15+
{blocks, idx, banks} = pop_max(banks)
16+
17+
distribute(banks, blocks, idx + 1)
18+
end
19+
20+
defp init_banks(data) do
21+
data
22+
|> String.split(~r{\s}, trim: true)
23+
|> Enum.map(&String.to_integer/1)
24+
end
25+
26+
defp cycles_to_loop_(banks, cache \\ MapSet.new) do
27+
if MapSet.member?(cache, banks) do
28+
0
29+
else
30+
updated_banks = reallocate(banks)
31+
updated_cache = MapSet.put(cache, banks)
32+
33+
1 + cycles_to_loop_(updated_banks, updated_cache)
34+
end
35+
end
36+
37+
defp loop_size_(banks, step \\ 0, cache \\ Map.new) do
38+
join_step = Map.get(cache, banks)
39+
40+
if join_step do
41+
step - join_step
42+
else
43+
updated_banks = reallocate(banks)
44+
updated_cache = Map.put(cache, banks, step)
45+
46+
loop_size_(updated_banks, step + 1, updated_cache)
47+
end
48+
end
49+
50+
@spec pop_max(List.t) :: {number, number, List.t}
51+
defp pop_max(banks) do
52+
{blocks, idx} =
53+
banks
54+
|> Enum.with_index
55+
|> Enum.max_by(fn {b, _} -> b end)
56+
57+
updated_banks = List.replace_at(banks, idx, 0)
58+
59+
{blocks, idx, updated_banks}
60+
end
61+
62+
@spec distribute(List.t, number, number) :: List.t
63+
defp distribute(banks, 0, _), do: banks
64+
defp distribute(banks, blocks, cursor) do
65+
cursor = if cursor >= length(banks), do: 0, else: cursor
66+
67+
updated_banks = List.update_at(banks, cursor, &(&1 + 1))
68+
69+
distribute(updated_banks, blocks - 1, cursor + 1)
70+
end
71+
end
72+
73+
mode = List.first(System.argv)
74+
75+
if mode == "test" do
76+
ExUnit.start()
77+
78+
defmodule PuzzleTest do
79+
use ExUnit.Case
80+
81+
describe "cycles_to_loop(data)" do
82+
test "returns 5" do
83+
data = "0 2 7 0"
84+
cycles = Puzzle.cycles_to_loop(data)
85+
assert cycles == 5
86+
end
87+
end
88+
89+
describe "loop_size(data)" do
90+
test "returns 4" do
91+
data = "0 2 7 0"
92+
cycles = Puzzle.loop_size(data)
93+
assert cycles == 4
94+
end
95+
end
96+
97+
describe "reallocate(banks)" do
98+
test "works" do
99+
banks = [0, 2, 7, 0]
100+
next_banks = Puzzle.reallocate(banks)
101+
assert next_banks == [2, 4, 1, 2]
102+
end
103+
end
104+
end
105+
else
106+
data = "06.txt" |> File.read! |> String.trim_trailing
107+
cycles = Puzzle.cycles_to_loop(data)
108+
IO.puts "The number of cycles: #{cycles}"
109+
110+
loop = Puzzle.loop_size(data)
111+
IO.puts "The size of the loop: #{loop}"
112+
end

06.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0 5 10 0 11 14 13 4 11 8 8 7 1 4 12 11

0 commit comments

Comments
 (0)