-
Notifications
You must be signed in to change notification settings - Fork 0
/
AoC2017_03.jl
109 lines (92 loc) · 2.38 KB
/
AoC2017_03.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
101
102
103
104
105
106
107
108
109
#! /usr/bin/env julia
#
include("aoc_main.jl")
if abspath(PROGRAM_FILE) == @__FILE__
include("aocd.jl")
using .Aocd
end
module AoC2017_03
include("aoc.jl")
struct HeadingsAndPeriods
periods::Vector{Int}
headings::Vector{Tuple{Int,Int}}
HeadingsAndPeriods() = new([1, 1, 2, 2],
[Heading_E, Heading_N, Heading_W, Heading_S])
end
function getHeadingAndPeriod(headingsAndPeriods::HeadingsAndPeriods, t::Int)
idx = t % 4 + 1
period = headingsAndPeriods.periods[idx]
headingsAndPeriods.periods[idx] = period + 2
heading = headingsAndPeriods.headings[idx]
return heading, period
end
mutable struct Coordinate
x::Int
y::Int
j::Int
k::Int
headingsAndPeriods::HeadingsAndPeriods
heading
period::Int
end
Coordinate() = begin
c = Coordinate(0, 0, 0, 0, HeadingsAndPeriods(), nothing, 0)
c.heading, c.period = getHeadingAndPeriod(c.headingsAndPeriods, 0)
return c
end
function next(c::Coordinate)
if c.j == c.period
c.k += 1
c.heading, c.period = getHeadingAndPeriod(c.headingsAndPeriods, c.k)
c.j = 0
end
c.x += c.heading[1]
c.y += c.heading[2]
c.j += 1
return c
end
function _parse(input)
@assert length(input) == 1
return parse.(Int, input[1])
end
function part1(input)
square::Int = _parse(input)
square == 1 && return 0
i::Int = 1
c::Coordinate = Coordinate()
while i < square
i += 1
c = next(c)
i == square && return abs(c.x) + abs(c.y)
end
@assert false
end
function part2(input)
square::Int = _parse(input)
square == 1 && return 1
squares::Dict{Tuple{Int,Int},Int} = Dict((0, 0) => 1)
c::Coordinate = Coordinate()
while true
c = next(c)
value::Int = 0
for (Δx, Δy) in OCTANTS
neighbour = (c.x + Δx, c.y + Δy)
value += haskey(squares, neighbour) ? squares[neighbour] : 0
end
squares[(c.x, c.y)] = value
value > square && return value
end
end
function samples()
@assert part1(("1",)) == 0
@assert part1(("12",)) == 3
@assert part1(("23",)) == 2
@assert part1(("1024",)) == 31
@assert part2(("1",)) == 1
@assert part2(("2",)) == 4
@assert part2(("3",)) == 4
@assert part2(("4",)) == 5
@assert part2(("5",)) == 10
end
end # module AoC2017_03
aoc_main(@__FILE__, ARGS, 2017, 3)