-
Notifications
You must be signed in to change notification settings - Fork 1
/
day22.jl
72 lines (65 loc) · 1.97 KB
/
day22.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
module Day22
using AdventOfCode2020
function day22(input::String = readInput(joinpath(@__DIR__, "..", "data", "day22.txt")))
cards = parse_input(input)
p1 = part1!(deepcopy(cards))
p2 = part2!(deepcopy(cards), 1)
return [p1, p2]
end
function parse_input(input::String)
cards = Array{Array{Int,1},1}()
for (i, playerline) in enumerate(split(input, "\n\n"))
push!(cards, [])
for line in split(rstrip(playerline), "\n")[2:end]
push!(cards[i], parse(Int, line))
end
end
return cards
end
function part1!(cards::Array{Array{Int,1},1})
while !isempty(cards[1]) && !isempty(cards[2])
cp1 = popfirst!(cards[1])
cp2 = popfirst!(cards[2])
if cp1 > cp2
push!(cards[1], cp1, cp2)
else
push!(cards[2], cp2, cp1)
end
end
for i = 1:2
j = mod1(i + 1, 2)
isempty(cards[i]) && return cards[j] .* (length(cards[j]):-1:1) |> sum
end
end
function part2!(cards::Array{Array{Int,1},1}, level::Int)
state1, state2 = Set{Array{Int,1}}(), Set{Array{Int,1}}()
while true
(cards[1] in state1 || cards[2] in state2) && return 1
push!(state1, copy(cards[1]))
push!(state2, copy(cards[2]))
cp1 = popfirst!(cards[1])
cp2 = popfirst!(cards[2])
if all(length.(cards) .>= (cp1, cp2))
rw = part2!([deepcopy(cards[1][1:cp1]), deepcopy(cards[2][1:cp2])], level + 1)
else
if cp1 > cp2
rw = 1
else
rw = 2
end
end
if rw == 1
push!(cards[1], cp1, cp2)
elseif rw == 2
push!(cards[2], cp2, cp1)
end
if any(isempty.(cards))
for i = 1:2
j = mod1(i + 1, 2)
isempty(cards[i]) && level == 1 && return cards[j] .* (length(cards[j]):-1:1) |> sum
isempty(cards[i]) && return j
end
end
end
end
end # module