-
Notifications
You must be signed in to change notification settings - Fork 0
/
14.jl
100 lines (86 loc) · 2.34 KB
/
14.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
using Transducers
# using Folds
using Profile
using DataStructures
function slurp_file(filename)
lines = readlines(filename)
template = collect(lines[1])
rules = split.(lines[3:end], " -> ")
template, rules
end
template, rules = slurp_file("14eg.txt")
function rules_to_f(rules)
mapping = DefaultDict(Dict)
for (pair, to_insert) in rules
left, right = collect(pair)
mapping[left][right] = only(to_insert)
end
function (left, right)
if haskey(mapping, left) && haskey(mapping[left], right)
mapping[left][right]
else
end
end
end
f = rules_to_f(rules)
function insertions(s, rule_f)
result = s |> Consecutive(2, 1) |> MapCat(rule_f) |> collect
push!(result, s[length(s)])
result
end
function insertions2(s, rule_f)
left = s[1]
result = Vector()
for right in s[2:end]
push!(result, left)
to_insert = rule_f(left, right)
if !isnothing(to_insert)
push!(result, to_insert)
end
left = right
end
push!(result, s[end])
result
end
insertions2(template, f)
insertions2(template, f) == collect("NCNBCHB")
function solve(filename, steps)
template, rules = slurp_file(filename)
rule_f = rules_to_f(rules)
for c = 1:steps
template = insertions2(template, rule_f)
end
vals = values(counter(template))
max(vals...) - min(vals...)
end
solve1(filename) = solve(filename, 10)
solve1("14.txt") == 2975
to_pair_counts(template) = counter(collect(Consecutive(2,1)(template)))
function to_letter_counts(counts)
result = counter(Char)
for ((l,r), count) in counts
result[l] += count
result[r] += count
end
map!(x -> iseven(x) ? x/2 : (x+1)/2, values(result))
result
end
function solve2(filename, num_steps)
template, rules = slurp_file(filename)
rule_f = rules_to_f(rules)
counts = to_pair_counts(template)
for c = 1:num_steps
new_counts = counter(Tuple{Char, Char})
for ((l,r), count) in counts
new = rule_f(l,r)
new_counts[(l, new)] += count
new_counts[(new, r)] += count
end
counts = new_counts
end
letter_counts = to_letter_counts(counts)
vals = values(letter_counts)
max(vals...) - min(vals...)
end
solve2("14.txt", 10) == 2975
solve2("14.txt", 40)