Compare commits

..

15 Commits

Author SHA1 Message Date
Bryce Allen
4d8a104945 day11 p2 2022-12-11 16:27:42 -05:00
Bryce Allen
298d0c3439 day11 p1 2022-12-11 16:01:08 -05:00
Bryce Allen
94c6ccb87b day10 p2 2022-12-11 13:18:24 -05:00
Bryce Allen
4191470b86 day10 p1 2022-12-11 12:00:50 -05:00
Bryce Allen
1c77865ad3 day9: better ascii map for debug 2022-12-10 14:18:17 -05:00
Bryce Allen
516ba0c389 day9: use point array instead of knot pairs
more efficient way to model > 2 knots
2022-12-09 13:56:38 -05:00
Bryce Allen
e026efdce4 day9 p2 2022-12-09 13:40:02 -05:00
Bryce Allen
93411e9cc5 day9 p1 2022-12-09 12:54:29 -05:00
Bryce Allen
ba9b4b91d1 add day8 2022-12-08 12:58:37 -05:00
Bryce Allen
d287410094 add day5 2022-12-07 19:09:15 -05:00
Bryce Allen
764c2e4942 add day4 2022-12-07 18:08:03 -05:00
Bryce Allen
2b722205d2 add day7 2022-12-07 16:15:56 -05:00
Bryce Allen
7100955ccb day6 2022-12-06 18:26:06 -05:00
Bryce Allen
416868be92 add day3 2022-12-06 15:46:25 -05:00
Bryce Allen
eb392d45b2 day1: std input name, refactor jl 2022-12-02 14:50:08 -05:00
32 changed files with 6354 additions and 22 deletions

View File

@@ -1,30 +1,48 @@
#!/usr/bin/env julia
infile = size(ARGS, 1) > 0 ? ARGS[1] : "day1input.txt"
Ns = size(ARGS, 1) > 1 ? ARGS[2] : "1"
println("infile = ", infile)
using Test
N = parse(Int64, Ns)
function elf_max_calories(infile)
max_calories = zeros(Int64, 3)
elf_calories = 0
max_calories = zeros(Int64, N)
elf_calories = 0
i = 1
io = open(infile, "r")
for line in eachline(io)
global i, max_calories, max_elf_idx, elf_calories
if length(line) == 0
open(infile, "r") do io
for line in eachline(io)
if length(line) == 0
if elf_calories > max_calories[1]
max_calories[1] = elf_calories
sort!(max_calories)
end
elf_calories = 0
continue
end
snack_calories = parse(Int64, line)
elf_calories += snack_calories
end
if elf_calories > max_calories[1]
max_calories[1] = elf_calories
sort!(max_calories)
end
i += 1
elf_calories = 0
continue
end
snack_calories = parse(Int64, line)
elf_calories += snack_calories
return (max_calories[end], sum(max_calories))
end
println(max_calories)
println(sum(max_calories))
function test()
@testset "elf snacks" verbose=true begin
@test elf_max_calories("example.txt") == (24000, 45000)
@test elf_max_calories("input.txt") == (69206, 197400)
end
end
function main()
if size(ARGS, 1) == 0
test()
else
infile = ARGS[1]
println("infile = ", infile)
println("snack calories: ", elf_max_calories(infile))
end
end
main()

View File

@@ -46,13 +46,13 @@ where P: AsRef<Path>, {
}
fn main() {
aoc_day1("day1input.txt", 1);
aoc_day1("input.txt", 1);
}
#[test]
fn day1input() {
assert_eq!(aoc_day1("day1input.txt", 1), 69206);
assert_eq!(aoc_day1("day1input.txt", 3), 197400);
assert_eq!(aoc_day1("input.txt", 1), 69206);
assert_eq!(aoc_day1("input.txt", 3), 197400);
}
#[test]

104
day10/day10.jl Normal file
View File

@@ -0,0 +1,104 @@
#!/usr/bin/env julia
using Test
mutable struct Instruction
cycles :: UInt
add :: Int
end
function parse_instruction_line(line)
parts = split(line, limit=2)
if parts[1] == "noop"
return Instruction(1, 0)
elseif parts[1] == "addx"
return Instruction(2, parse(Int, parts[2]))
else
throw(DomainError("Unknown instruction: " * line))
end
end
function signal_strength_sum(io; end_cycle=220)
X :: Int = 1
cycle :: Int = 1
signal_strength_sum :: Int = 0
next_test_cycle = 20
for line in eachline(io)
if mod(cycle - 20, 40) == 0 && cycle <= end_cycle
println(cycle, " ", X)
signal_strength_sum += cycle * X
next_test_cycle += 40
end
inst = parse_instruction_line(line)
new_cycle = cycle + inst.cycles
if new_cycle > next_test_cycle
signal_strength_sum += next_test_cycle * X
next_test_cycle += 40
end
cycle = new_cycle
X += inst.add
end
println("last inst cycle ", cycle)
signal_strength_sum += X * sum(filter(x -> x >= cycle, 20:40:end_cycle))
return signal_strength_sum
end
function get_crt(io; end_cycle=240)
X :: Int = 2 # Note: add 1 to simplify 1-based indexing
pending_instruction :: Union{Instruction, Nothing} = nothing
screen = fill('.', (Int(ceil(end_cycle / 40)), 40))
nrows, ncols = size(screen)
for i in 1:nrows
for j in 1:ncols
if abs(X - j) <= 1
screen[i, j] = "#"[1]
else
screen[i, j] = '.'
end
if pending_instruction === nothing
if eof(io)
continue
end
inst = parse_instruction_line(readline(io))
pending_instruction = inst
end
pending_instruction.cycles -= 1
if pending_instruction.cycles == 0
X += pending_instruction.add
pending_instruction = nothing
end
end
end
return join(reduce(*, screen, dims=2, init=""), "\n")
end
function test()
@testset "signal strength sum" verbose=true begin
@test signal_strength_sum("example.txt") == 13140
@test signal_strength_sum("input.txt") == 13220
end
@testset "crt test" verbose=true begin
open("example.txt") do io
@test get_crt(io) == chomp(read("example_crt.txt", String))
end
open("input.txt") do io
@test get_crt(io) == chomp(read("input_crt.txt", String))
end
end
end
function main()
if size(ARGS, 1) == 0
test()
else
infile = ARGS[1]
println("infile = ", infile)
println("signal strength sum = ", signal_strength_sum(infile))
open(infile, "r") do io
println(get_crt(io))
end
end
end
main()

146
day10/example.txt Normal file
View File

@@ -0,0 +1,146 @@
addx 15
addx -11
addx 6
addx -3
addx 5
addx -1
addx -8
addx 13
addx 4
noop
addx -1
addx 5
addx -1
addx 5
addx -1
addx 5
addx -1
addx 5
addx -1
addx -35
addx 1
addx 24
addx -19
addx 1
addx 16
addx -11
noop
noop
addx 21
addx -15
noop
noop
addx -3
addx 9
addx 1
addx -3
addx 8
addx 1
addx 5
noop
noop
noop
noop
noop
addx -36
noop
addx 1
addx 7
noop
noop
noop
addx 2
addx 6
noop
noop
noop
noop
noop
addx 1
noop
noop
addx 7
addx 1
noop
addx -13
addx 13
addx 7
noop
addx 1
addx -33
noop
noop
noop
addx 2
noop
noop
noop
addx 8
noop
addx -1
addx 2
addx 1
noop
addx 17
addx -9
addx 1
addx 1
addx -3
addx 11
noop
noop
addx 1
noop
addx 1
noop
noop
addx -13
addx -19
addx 1
addx 3
addx 26
addx -30
addx 12
addx -1
addx 3
addx 1
noop
noop
noop
addx -9
addx 18
addx 1
addx 2
noop
noop
addx 9
noop
noop
noop
addx -1
addx 2
addx -37
addx 1
addx 3
noop
addx 15
addx -21
addx 22
addx -6
addx 1
noop
addx 2
addx 1
noop
addx -10
noop
noop
addx 20
addx 1
addx 2
addx 2
addx -6
addx -11
noop
noop
noop

6
day10/example_crt.txt Normal file
View File

@@ -0,0 +1,6 @@
##..##..##..##..##..##..##..##..##..##..
###...###...###...###...###...###...###.
####....####....####....####....####....
#####.....#####.....#####.....#####.....
######......######......######......####
#######.......#######.......#######.....

137
day10/input.txt Normal file
View File

@@ -0,0 +1,137 @@
noop
noop
addx 5
addx 3
addx -2
noop
addx 5
addx 4
noop
addx 3
noop
addx 2
addx -17
addx 18
addx 3
addx 1
noop
addx 5
noop
addx 1
addx 2
addx 5
addx -40
noop
addx 5
addx 2
addx 3
noop
addx 2
addx 3
addx -2
addx 2
addx 2
noop
addx 3
addx 5
addx 2
addx 3
addx -2
addx 2
addx -24
addx 31
addx 2
addx -33
addx -6
addx 5
addx 2
addx 3
noop
addx 2
addx 3
noop
addx 2
addx -1
addx 6
noop
noop
addx 1
addx 4
noop
noop
addx -15
addx 20
noop
addx -23
addx 27
noop
addx -35
addx 1
noop
noop
addx 5
addx 11
addx -10
addx 4
addx 1
noop
addx 2
addx 2
noop
addx 3
noop
addx 3
addx 2
noop
addx 3
addx 2
addx 11
addx -4
addx 2
addx -38
addx -1
addx 2
noop
addx 3
addx 5
addx 2
addx -7
addx 8
addx 2
addx 2
noop
addx 3
addx 5
addx 2
addx -25
addx 26
addx 2
addx 8
addx -1
addx 2
addx -2
addx -37
addx 5
addx 3
addx -1
addx 5
noop
addx 22
addx -21
addx 2
addx 5
addx 2
addx 13
addx -12
addx 4
noop
noop
addx 5
addx 1
noop
noop
addx 2
noop
addx 3
noop
noop

6
day10/input_crt.txt Normal file
View File

@@ -0,0 +1,6 @@
###..#..#..##..#..#.#..#.###..####.#..#.
#..#.#..#.#..#.#.#..#..#.#..#.#....#.#..
#..#.#..#.#..#.##...####.###..###..##...
###..#..#.####.#.#..#..#.#..#.#....#.#..
#.#..#..#.#..#.#.#..#..#.#..#.#....#.#..
#..#..##..#..#.#..#.#..#.###..####.#..#.

115
day11/day11.jl Normal file
View File

@@ -0,0 +1,115 @@
#!/usr/bin/env julia
using Test
mutable struct Monkey
index :: UInt
items :: Vector{Int}
op :: Function
op_value :: Int
test_divisor :: Int
test_result :: NTuple{2, UInt}
inspected :: Int
end
function parse_monkey(text)
lines = split(text, '\n')
# Monkey 0:
match_index = match(r"Monkey (\d+):", lines[1])
index = parse(UInt, match_index.captures[1])
# Starting items: 79, 98
match_items = match(r" *Starting items: (.*)", lines[2])
items_list = split(match_items.captures[1], ", ")
items = parse.(Int, items_list)
# Operation: new = old * 19
match_op = match(r" *Operation: new = old (.) (old|\d+)", lines[3])
if match_op.captures[1] == "+"
op = +
elseif match_op.captures[1] == "*"
op = *
else
throw(DomainError("Unknown op: " * match_op.captures[1]))
end
if match_op.captures[2] == "old"
op = ^
op_value = 2
else
op_value = parse(Int, match_op.captures[2])
end
# Test: divisible by 13
match_test = match(r" *Test: divisible by (\d+)", lines[4])
test_divisor = parse(Int, match_test.captures[1])
# If true: throw to monkey 1
# If false: throw to monkey 3
match_true = match(r" *If true: throw to monkey (\d+)", lines[5])
match_false = match(r" *If false: throw to monkey (\d+)", lines[6])
test_result = (parse(UInt, match_true.captures[1]) + 1,
parse(UInt, match_false.captures[1]) + 1)
return Monkey(index, items, op, op_value, test_divisor, test_result, 0)
end
function read_monkeys(infile)
open(infile) do io
monkey_strings = split(read(io, String), "\n\n")
return parse_monkey.(monkey_strings)
end
end
function simian_shenanigans(monkeys :: Vector{Monkey}; part=1)
modulus = prod(m.test_divisor for m in monkeys)
for m in monkeys
for item in m.items
new_value = m.op(item, m.op_value)
if part == 1
new_value = Int(floor(new_value / 3))
else
new_value = mod(new_value, modulus)
end
new_monkey = (mod(new_value, m.test_divisor) == 0
? m.test_result[1] : m.test_result[2])
push!(monkeys[new_monkey].items, new_value)
m.inspected += 1
end
empty!(m.items)
end
end
function monkey_business(monkeys; rounds=20, part=1)
for _ in 1:rounds
simian_shenanigans(monkeys, part=part)
end
return prod(sort([m.inspected for m in monkeys])[end-1:end])
end
function test()
@testset "monkey business 1" verbose=true begin
@test monkey_business(read_monkeys("example.txt")) == 10605
@test monkey_business(read_monkeys("input.txt")) == 64032
end
@testset "monkey business 2" verbose=true begin
@test monkey_business(
read_monkeys("example.txt"), rounds=10000, part=2) == 2713310158
@test monkey_business(
read_monkeys("input.txt"), rounds=10000, part=2) == 12729522272
end
end
function main()
if size(ARGS, 1) == 0
test()
else
infile = ARGS[1]
println("infile = ", infile)
monkeys = read_monkeys(infile)
display(monkeys)
println()
println("monkey business 1 ",
monkey_business(monkeys, rounds=20, part=1))
monkeys = read_monkeys(infile)
println("monkey business 2 ",
monkey_business(monkeys, rounds=10000, part=2))
end
end
main()

27
day11/example.txt Normal file
View File

@@ -0,0 +1,27 @@
Monkey 0:
Starting items: 79, 98
Operation: new = old * 19
Test: divisible by 23
If true: throw to monkey 2
If false: throw to monkey 3
Monkey 1:
Starting items: 54, 65, 75, 74
Operation: new = old + 6
Test: divisible by 19
If true: throw to monkey 2
If false: throw to monkey 0
Monkey 2:
Starting items: 79, 60, 97
Operation: new = old * old
Test: divisible by 13
If true: throw to monkey 1
If false: throw to monkey 3
Monkey 3:
Starting items: 74
Operation: new = old + 3
Test: divisible by 17
If true: throw to monkey 0
If false: throw to monkey 1

55
day11/input.txt Normal file
View File

@@ -0,0 +1,55 @@
Monkey 0:
Starting items: 83, 88, 96, 79, 86, 88, 70
Operation: new = old * 5
Test: divisible by 11
If true: throw to monkey 2
If false: throw to monkey 3
Monkey 1:
Starting items: 59, 63, 98, 85, 68, 72
Operation: new = old * 11
Test: divisible by 5
If true: throw to monkey 4
If false: throw to monkey 0
Monkey 2:
Starting items: 90, 79, 97, 52, 90, 94, 71, 70
Operation: new = old + 2
Test: divisible by 19
If true: throw to monkey 5
If false: throw to monkey 6
Monkey 3:
Starting items: 97, 55, 62
Operation: new = old + 5
Test: divisible by 13
If true: throw to monkey 2
If false: throw to monkey 6
Monkey 4:
Starting items: 74, 54, 94, 76
Operation: new = old * old
Test: divisible by 7
If true: throw to monkey 0
If false: throw to monkey 3
Monkey 5:
Starting items: 58
Operation: new = old + 4
Test: divisible by 17
If true: throw to monkey 7
If false: throw to monkey 1
Monkey 6:
Starting items: 66, 63
Operation: new = old + 6
Test: divisible by 2
If true: throw to monkey 7
If false: throw to monkey 5
Monkey 7:
Starting items: 56, 56, 90, 96, 68
Operation: new = old + 7
Test: divisible by 3
If true: throw to monkey 4
If false: throw to monkey 1

70
day3/day3.jl Normal file
View File

@@ -0,0 +1,70 @@
#!/usr/bin/env julia
using Test
function priority(char)
v = Int(char)
if v <= Int('Z')
return v - Int('A') + 27
else
return v - Int('a') + 1
end
end
function rucksack_errors(infile)
psum = 0
open(infile, "r") do io
for line in eachline(io)
n = length(line)
a = Set{Int32}()
b = Set{Int32}()
for c in line[1:Int(n/2)]
push!(a, priority(c))
end
for c in line[Int(n/2)+1:n]
push!(b, priority(c))
end
psum += pop!(intersect(a, b))
end
end
return psum
end
function rucksack_badges(infile)
psum = 0
open(infile, "r") do io
for lines in Iterators.partition(eachline(io), 3)
all = intersect!(Set(lines[1]), Set(lines[2]), Set(lines[3]))
psum += priority(pop!(all))
end
end
return psum
end
function test()
@testset "elf rucksack errors" verbose=true begin
@test rucksack_errors("example.txt") == 157
@test rucksack_errors("input.txt") == 8394
end
@testset "elf rucksack badges" verbose=true begin
@test rucksack_badges("example.txt") == 70
@test rucksack_badges("input.txt") == 2413
end
end
function main()
if size(ARGS, 1) == 0
test()
else
infile = ARGS[1]
println("infile = ", infile)
println("error priority sum: ", rucksack_errors(infile))
end
end
main()

6
day3/example.txt Normal file
View File

@@ -0,0 +1,6 @@
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw

300
day3/input.txt Normal file
View File

@@ -0,0 +1,300 @@
gtZDjBcmpcDgpZcmmbgtdtqmCGVCGGsvhCFCCqvmCMMM
JrhfzfLTNfJhPnhQnfzHfCFFQFSGvMFCGQFsQSMSVs
TllTRrfNNlfzwhtZBZgtRDBp
vMdwjZdjwjvjdTZZvCcQMGnQMQcbcgLLCL
rsVhfmssPWzDVGCLJSbCgPLSQG
lfWNDHDgfszFRTFtwwNjdv
GLPqVqdVGCLCdczjMjzMfzld
JnWQvJDmvWBtlMzhrzfHQgcz
tDtJDDDDtWRRmBwJwWtpPRsGCGScLPGSqspNCS
ChVzZzfNDzNJmBQfjjJfmH
MrTMPMncGMJvPPvPWTbrMWvgmBgQwgdpwmdpdpjwpHQcdw
SPvvvbqrFvMvZzJzsFVzVJNV
mvBbvMFqbMMVVmtCBHpDdDPTDspdNWPDVP
zjSfftcQtwtSfQSpNDppsNsjPNdRPP
fgfStJShrgvvCLLv
GmFnNNwbFFbhQQGQnGwwwfBgnMMqVDBZVVBMfMVzVz
vWzRRHzTHcgfZDVfBgfH
SSTvrvRcPpcvjFGwNGbNpbwQwz
FFgbZZFZgFmpstLgmbtzqNrwVPlMPlSWWrMPNp
QQhTvjhcvjjvTcTcTfCcSRwwWzwzPMrzWNNWVVhwrwWq
GRQBfCRnGGTcDvBfGvffCCjnFZtFFgStJLbLHbFLJZdgmd
pppdjcrMMRDJLJdRcwRDrwssqHGGDHsZHHsvBVtvmVHV
nlCFWzGzzQFlSlhGWnPzFbSsBZmsssmVVmsBvnHqvNVqqm
lFTTTCSQSTrdGJJLJG
jpsGMgsmghQwQsMmhlQshjtTNTRTnFqRWnnqRfFnnt
SLBCHrcvZHbSvSZrSvSWnfvVNvftVlFRTqnRTq
JrzdZbBcHBCrrlHrrSsMgmGpJPDPQmpgQgPG
cmcZHgwgMgHSLmtjLfWPNNrWBNfffp
JTqGTsClHslVVRVCVGVJGnBrjdnnrdBNvjPNBNBrWvnW
VVlQlqTFJlzzlsVGsRCZMthHDbwbFhgcbwHchg
qgZjgjjbssqgsjlNqjhTtdrfQdTdWLLnDVfHtHWd
zcGMBDDzcLnztfQQQz
JSppJcBScMmMFFBRCpRCMmGlggvjhbhlNlglwbslCZjhDZ
hvhmqcqwwcTBvvwQnRQnRnTRFzFzQz
jWLPPtPsgMtpdLMLWllpgLLQFQhFJjnVrzFrVFhnRzJJrJ
WPWffgtSdspdhSMdlSdtfBbHmSvqbNBCCmcBmcvcCH
frVcrVcggfSZJfbbJvBd
hwWQnwhWQmQmThTSsdvvSMBTBzcb
wGnFFCGlQwntGtCtwntwDmFwRgLrHqNRqqcNNgRrHHLggCjp
wRSwwHDMsRGHvNBNjTgvjgJD
mcLcFCclWQWQpPQWVQcQcvvNJjrNBTrvgJgBvTRvCg
VFPbQLchQLSRfbMtdHGH
lfVrhnlRRqrJZVDJdHSWCvJCJSbj
BFsgcgMNNQgSvbfCff
ffNPcMtzqPlnmRGh
ZJplFmRJmWRJRWmTJCvtTtnLCtndCqtqnr
SQsVPQHBQZNSNSLCfSLrcLcrrr
VMjPjbNMDsVHmRllmZpZWmjh
LcTLRbJhhdhLJbbclfVvfWQVWFRWFFfq
rZNttSNvtgsPPFsqBFPWQF
HGCSmHrrwNnHGMLpDhbzzpmJJv
VlSWzRtWSJqWdfhdqBdF
mTDHsmmmcHpgrCgCrTsMMtqfsFNsZqfdMZMNbd
TDcpvrpHCprCpHrmcQvTHgTQzSnLJnPPJlLzwJtRVJwLjJ
vZSWZJZJFvhZldZHdvvlphZSNGNnmzwCPNHNHGNrrRHGCPmP
bjfgcbjTQTFQBnGRRBCBNwBnCz
csqscsbssQLsgQcLgLQLQTQpFdlhdvdZdpZWhJplShWWtq
QgQvHnfflfBwQCfwlfglnQQccNcRqGGcjmcsGjddwdzsJc
DhZbTLZTDMVTsRzsqsRjszTz
FSZVtMLMMWbSgqSvPQlnpH
MMPllnnBmfSHvBgCLf
whZjGRJdjcNjjhRjCvgCfbSvCZLHfpZs
RRWGWwNRWwhwclmrgFmngFPMWm
VVHQGDGDGsdRrmZBQZRCVHZCNcSTTPMwwvTTwSSNqBqvgMvN
nfhdLfjFnJpblLbJjWhtnjWPScNnwSTPTPqTvgngNNvSvS
fpWljtpLjflfLfzlhZGQHZQVddHrrQRDRz
VCHCjwCwMSZSqQzhhQqcWZJD
GGGrFFgNRNNgmfnTdgmWQpczvPvQPWQJGDpzzc
lgTttRTgmfNRntrTTngrCbjCwJCHjLBBHlMVMsbB
szgPPlCblggVszhLmzvcvNrqpjNqmrqqpGvG
wBQDtBfQDtFvLjjctLqTMr
ZFWWdDLQFwSfDSBSQQBWnnnQVdbhgRVbsHzsshbClzzCVggb
VpVsHVcqcMVMMNHpsspstbMqzBztJZTBBfJfzTvZfvWJWSTv
mDDQgCQQQHdrwgSvZSmJJZvWfJJf
drCjggDlPdgrlbjNcnhcHsbpsj
cNNDRRpDcNcTpppsqHLQGLfRLvHzLH
lFntJjtbFFlsmsjvnGqHWLfhfqzzQh
sgPbjBJtPgbPJblblJgbgbwdBTwDCwpwrdZZVcCcDppc
GGclMjLnnjCMchcChLMLcnnzRFJDZJSRSzzzzDSShszPRS
VHgFQgwVwfNNpQVfHzQsPPPJDbmZbJDJbS
HfNVWdHVvgHgVWVNppNWVHwTlvBFcClBCjcTLTlBnnLrTL
GTLdlJhffQwDRvWLrp
HVZVNjjsPqzNjNNmNgDWMrRQpWvWRHrDHBWp
VCqVzjPjCpVqCVPCsbctcnblcGlTbGnlbFJf
flHdfdBNdZcflBMjqMjBNfZQhvJbGvqvsshJQsJCJDWvvD
gFTzRRpzRTwbgbLmtCvsJhWsChrWCrtWCC
VzzzFbVRLPznmRBffPNBHNMdlZfl
FFFMwCqJFFmrRwgnbLrL
GpjGpQHQpfjdjDRnLrbrRQmJzzgg
BphfhDcNcHNvPBvSqJMWJS
NndbWpDBNbjvWLZqWsWQ
JPFFTSPfgcMgftQQGjvTmsGqzssG
gPgcfcVFgcHqSqVhbBCHlpbbpDlhDD
FSdfWFTTBnjsDCjsmrrT
pQzLRVLppLGcQjqbmVDJsChCvCbVsm
qHLRGqqZzGjLqBNMFdnHlNlBFN
DjqbfBTchDjqqCjjCTWNTbdzSVzGZQGBwZnQnVwpSSnQ
ssJlPrtvMsRLrrJQGNZJSpZpGzSG
rlFssHsvPRPMvFmtHvtqjhTgjbqhWqNmNqgDNh
vcpnRqwwLLbvvcGpDQWDFSCgMrWWQWRR
gtNfBfllrFlHrlrl
ZPzftBmsNBNBPJBZPmZPNtmPdGLsqbwqpqcndVLLGpVGvqgV
vRBfQqqBQPfbrFvPBvPbhLDVDVDQZVVtZtlWLLLt
jcJmFFwnhJVZLWVl
sHTcmNNHzncmcjmdsBCrBCPCrBBqCFrqzb
bbZRnGmNnBGGMNRTgCmWWGGSrvSvFHvzFvFQDF
LjwphpdPdLpLJVqfJrQzDzfrvQHSvDcQrQ
DJphdwDsnmbZsTZM
rdNrZNBSzSztnNzWCcNpHlMwlwHWlM
QqLGLJvLjtvQWhgHgchHwHJw
GtjTGtDRqvfLRGnrzsmZmfrVFBrV
TdMhZrTTNvwphcLL
WnnmffmDWnWPsPCJNpNcpNVNQp
fsjbWfFFfnmmDsFDnnflSSdczlMdTHTzTTRRBdtT
cMcPcMcwgWJMjWWhFWCCQCmqCFdh
bSLVLblnNnLbVfnsbSbCChSQdChptpdqZrmCmZ
DLGNfnGVDNDHbfzjRcRgqHMRBJPc
HVFVlVHjzjjlCJjHjCjnvDrggrgLdqzddMqrzz
SSfBTmtNdLqngvrm
TwnNfPWWpBSBNtTHZCGlPHCQJHZHPV
prvccpFQpMcQBwsvssshdwSTPD
qbGHVbNJGqwdPgDrTsDJ
fGbGqqlGGHflqLlzZBBrRcrtrZlp
fCSPhltMBmPmbdgd
DjvJJscvTsHHDbWzBWsWbdwgLB
VVHDZvTppRcJVFFppvvRJDJqMSGqCtZdthttrnthSZMGCr
ZcSrSdrhDjBDDCmZdZmZjhwVHwqVVsMwgswVVwMfhw
PNvzTPNbnzcPbGQNJTvqwsWgVgVMMWpQqwgHpp
JTPGPTzNttnbRTPlPtNNRlFrFmBcmDljjmBFSCmLZZBr
mNvRRCVMtNRdFNtMtBHHprpHgJgJWwpBnprg
LZDDlSLlTslDfbcpJJWndwcscnwr
qdZZGSDhMVRCGtmC
VGFjjgBShGdGzQczcGRG
MppqCDfCMwfLDfvNmrtWstRcMPzRMRsRsPQS
NwDCffLppbqqrqvTBngSbnBHglZllH
vdllJVDzmVDVqvvWvdqJlcWrCsfCsfSSsSJfCSfQQCCbCQ
jnTHZPZHMjZhMjTpHgMpgnbNqBstnfrtSSrBSNssCrfN
LHLTFLjTMTTTwjHhpHTcwmDcWVDlvRDmvqwWlW
rqQsSStdmsdLqlNNPGlGlV
FpFpzJNTcHzRHRHlGwFVLFBLFGVvlw
WCCjWRNJTJWhQhbhrbnd
jsQjfrRTRwzSsRTgNchlnlhqcnlQmQ
dFDtdFBDddHLJpVpHHtVbtHFCWlWlGlNlmGggNqgglmcchqb
dLDHMVdLtBBDBFVJBFthtJHRTvsMSvsTrTSRvPPjPzSwRP
CSPpSrLlrlPrPchLnSlbDbbRttDVhbGRDDJRtD
fzfvmzTMmfsFszsHZsHMHVfwtbjBDDGjtRBjQQGGJb
HmvmTFmqmTsHqzzzzdTsMMScndccdLppnLCSPcCLrVgr
pfMflRnfrnjrpjnFzDpfDMmMLRTLZVTgLsvdZgLLZHSVWZRd
tBGNhwPGcNBBWwZddsSTTPgVLPdT
JwthtwbbhNBQhwhbBCrzpnprnWnprlzWlClD
PPnZZjnFNDjlJJhtMddfTTdD
QGLHFWvQJtzfpvCt
swqSmmQWLQwFWLwwRcqNNBnnbgPqbPNbglVZ
GCLSjjZGZhpvGtBgjJlnJDhhJMVDPnJlJP
mNtQQwNzQRHWdJHnPTsddlln
zQrfmbtNbcQcrzmrRBZqBcvpjSGLZGLZBB
zGNzgsjDssvNbPlWJfJq
RLMVSRMLhCLZSMZHDSJWvpcqfbfhvpJqcWPv
dMVHLFHLZMLRLLFRHHHVZMgDTntgstGwznzGGnzjDFwG
wCLCHLBwzBtQRLHLbNFFfdqdDqVrVfBN
JGvljmgGZvMlfDRRnnnZnfND
GppRlgJlSllSgjMsmllpTjcCLczWztPWPwwwzWThtcQh
WvHbvvWnFHszDRSltcCctCFD
gCmJmCCPTPqpgrZtjdRtDRplcSjS
rJJrQPPJQmrmrhGTznCfLMMbfvWfbCWQ
TqBWtTbFBNNRRtwQpJJvvvZPpTSQ
fRMfsMssrGhSmMwSQvvZJm
VggcVlsCgHnVFnndbbnR
NdrSSWBNPPSWWHPPlwlLZHLZLMhjlLLH
pVptMTgVTzLwZTzlbF
qsRmRJtsMvMqgqgRvCdcSrWSPcWrDmmdBN
nbJnfqWcmCMnSBSHwzWBsHHz
dVpdvdppdptppDlvlHcczSgNcgww
VGTdTVtGtRLFPTDbcfCmmcCQJQjcrT
VTjrjrjTlTjQMdpGrWMSHvSG
wnNJbDmttnwnhNwcJmNGdvWvMSfvMfhSSppSdp
JznFnNsGnzzGFDJsFNmLgVVQZBlLZjQTLTjTls
hpngHwcpWHgjjfhzTJBfBB
RFFbFlQlSdRsbRQQMGPRGdSGjBvvNTvzZMBvjzBBTJTvMBBT
GPSSPDDDFzGlGGRzLzGGPRWqnprcgCHwCHpwHWVcncLV
LLlLGffQLPRThRwP
MpZjbmznWqmqZznmzmpZqZnMRgPBCTPfgRTTwTjhwBPPghjP
VnZpMsMMJnWsmnJpJmzrtFlGQFrHGvSvfHStNV
MQqHMQPnqmpDdTLLRnDjsj
NGFzwgtLBtFFGrrCtzgfgCNgSsdTDSSTsdssjDdSlZRjTSBs
zCwNLthfrbCgzzhqhmccJPhQHVmV
SndBVcgdqcRBRcdPBBcVcQTSSMLMlTssMNMWsHMsLQ
GmJvZvhqpvZtNwwWLTTLwMMm
JFJpzFGZqjvhGZcjBPcCBBPnnVBc
rJWbqTvwvJNbPDPPvLcZvPDp
QMnfBsjmFPLcHRDfPp
lQlMlmtFsMMBstljlnGhtMhmGNqJqTcWNNbWdGwdNNJCrTrq
LcjcNCQNQWDpRDjRTj
vWvszVVSsBGWsTJRFHRJTTSTRJ
vvGbtqbGVVBqtzbqvBdzVLWNLClwnwMLWlQNMfdPQP
TWBZsWrjzZzWBrBsrrsTLNNJvFnJVmlSFFQnGpmnSJJS
qdCggdqqqhhqwhRbCwbCPqhlJFPPGJQVvvvnpVVmPnnFvS
ffgCfghDqDdCsGWZjTsLrsfW
QzQSSQmzSsLQcLmrcsLzccgqCnwqCtZDnDnrZwgnqTTT
hFRHHRPRPMtWPGVPRlMljRPCgWBBDTgJBgnwqTZDBZDWDB
jPjPHRMjjvdjVFhdNfbsbbQfbcddmNtL
jJlTqMqJtdztJqzcSJSlTdSlprLsRRHwcRRrsrHbrnnRHsHL
VVVMWNNWmNmLnPLRHrLp
NGhfvvVWBNfNNCNCQTMqjzgTQBSSSqll
SSSRMRSRpnMRHLqWLfPlDGlGWldD
hbNtlmvrNrsVDWsGPfPfqG
jvbBNmvlJjRcCzHFppCJ
hhWWPjnBGBGnjqBWSnhhsNLllLNcLczJcqcTlLTlfl
FHvFFMHwdmvrDbwCbbvHwdHnZTMLzTNTczflJTZclzNLlLcJ
HdFFvdDvpCDdrnwrGhBQhWRRpsjQWWQW
sBsvtJtdRdjNbWWrTllqlNgg
nSZSnPPZzMSnSlScWWWgrVWCrqgrWMWr
lzSncQcLZLzlwDvtdDdFdFJJhHvJ
lpsTLDlTtFtlWHPDvvgPfgMrQQJM
zmNbzcNjzldjwmbdbhhjcjRgfwrgvMwMMSRJSvQQvrRf
ZhjqcjzNhmzNqBqNznmcWHplCFGnpCtFsGWHHWsH
ZPGQBFHFbhSrHqtfSrSr
nMdznzzMDTnjMQrMWtrMptplqpqS
wzjczJmccTJCmcVghZBJbPBQBbVh
wLLMJbqSBBnnJhbvbFSSRRlztTrHzrrrrd
QNNGVPjWPGVqltTHWCqCdH
sjNGmmGVGgQNGDVmsVpgqQVpMDhvbLwMffZfhZbLnfLLLZwb
gQLcQrMtBPdwSBsSlmBm
TfCpTJnTbfqgsgwgppsSzp
jVbvTnvWfJnJjjbfCjWWjrFPrLMtcDPgLMQQRtgZVF
gwpHvpgwngGHcnvNvgnmsqCzmMzlfqmmqzHHCm
JrdSLdBVPRDtRtPfPPzCJhjqmljzmmqszzsM
SWLDDtVdrZWtSBRZfRcwgFGnpNFpnTnWnTvT
rpcnHrwrhWccNZDDBBgBVCSW
nmzFRRjFmmJQNDJC
qznMlqGnzRtRGvqGFRPrdMhwTpTLfLcppLHp
wthvbmhmChWMRJLJzngZpzLLNC
SsdBVjSTjBdffBFfcSdVHfTrnDZGpQgNZHNnLZGpJngJGLng
sSdTcdVScdcrccjcrBPrBSjcvmRRwlWPhwmqtgWhMPtmMMqR
CJJBdBCrHdBhtRHctBQhRMrBwZpwZWNZNSNTwSNpQWpZsSSW
LVFnvnbDjLsDPsPqFFvPvDnTzSTwNwPZpSmpSpgmgZWNTW
LjlflbFjsvVlrHcrHtrfcChH
tVLJGNRtfBBNGBrfrbzmfhPsrsPC
DWWDQHQgllSFqFzcsJmzzSSzmrrs
MJFQDgMqnHlDvFdGNBNNZGNVVvjV
wnNwGCBBFNWBqjFBnLLGVDHhHmDPHvZTjTvTrPvD
bMbttVScMJQtdgSgstbJRSPmrTHmHmrmmSDZlrPrPDhv
cMbgpsbVbzbdRMRFWLqzBfLGwwwwfW
JpSnGSGpbGgsWWPHJrdfsT
MNsRqNNvMQDTLWHlffNHLN
qqmtRzRvCRRQDqjqjDmsmRpZwSZbcwbnCcCSBBnSSnnC
TWqlqpRqRptqlRhrmtGGzhbSrSdz
VgsBVMvgVZfZvPsMVNvfZfvVbSPdhFPFhbzLhJdGFJmLhhhL
QZgvZgvHwbwHbMsMRllRjDRDnQRqlRjl
fsPQwnHnHLLfnBBnwwGtjTGRWTWTWwhV
jblbdjZFDMbGllqTGTtVlq
gmdMgZMbjpZDcrrDgdmszsPLpQfpBPPnNQNLLz
HRsPPGMhLPMrnPchPSwStjbSttSvtHSqQw
dfsCfpCJVJCvdFBFwStwjj
gTNWmWfTNVZVJzZWpWJgTpfhnDrMnDclgDlDrDRnRcMLDs
ZQZQJMqdwmZvqfPmwRjpBBjHjnshnjtt
zcTPTLDTFWLGTrTSWPcDSSHjRlhRsDhHslslssBRljjj
TrNFLbTWrGNZvmvVQPQV
htfLgmtSLcTWNLcT
slbHlBBGbqRsblBHvdNJJcjFFNBTVWWWcn
bbQsHMMblHrMsGRqvQhwCTQCwtQCzSpfmS
zmqdphmFmSpTzhdqhFmwjjGbtcvDbcGGjllGQjSP
HJFrMCsVLrHRRMCNrVMVnctvstlGcQlPtGGjQtGlvP
RFLHLVWrNgVJzwzwfgffwdfp
vdMjSmMMpmMWhRpndRmZnhvHqLpGHcJGGGDLHHLGcfcLfc
lPBwwrsCgLFggcqqLW
TWszsWNBTNdmSRvjbZZT
zFlBGpzzzLLNjBwPcwwmcNPfWNQn
VHSHRJTJDSVVnmcVVPpWmpnf
DMZHHrDHHrJrrZrShZsHGbMBbFgGjGCgjpFlBzzb
FVMpsvTqvqMssVsWZSrqWFvwlGDGwQzwfwQQNLzDlwlZwf
hPbgBHhJJcJPwCwDpNllCCHC
pnjbBmjgbgmqtSmsTtsF
DHZHmfTmCfjDZHMZmzffHHnQwwTBdQwbSdBGBQwhBQTQww
cqstRFWNtLrNFwdVShlBSlhBRl
StJWpLptNWLtJcpqPrFHDjZzzvnDDHPCZjPvvz
hzffhGVGGhzRqTBLTqHL
sFFFsMQlwJMsmrBFSNHTHNqrTS
pbdsJMdJMJbwbmJJtbTtgnffGgVVChvD
FvJnFnCpQTddSSmFdFpPPsVhppDjBzjDVhDV
RgZMZbsgzlDPlhjb
cHHHRgRZgfHHZGZfHZcLLHrrCrmJCmddrsvdJsmvFFQG
dpJDdZwLnvdvFmFMmHjslMLH
CGCztgPhWCWhzzzNNPGfrrWfmbbsmmHjFHDMsbHMsjFPjbHm
rNQDGzzhCCfNrzrDzChTcZZvQcTRJpTwdvQpVc
VpvNGhGHGNhHbPsbVbvfFtLCzSCFSBsCFSFCLB
MlqJwTnrRRrRnMlQMHfHzHzWFWtmTzLWFC
ljZDDHqqjqRbpNhjNNgcgc
qrQtDzcQzbrcfdbqrQrthtscSsvpvnsSHpTpLpspmsSs
CVwNNVRNBSHsLSFBTv
CVVVNZjlVlGwlGlljNlWJVrrfqbPQQqHqJhhftbfDJqf
lpmrPDPDjPlmWrVzPztZwFjtFbBnRtZbbcRL
dnqJCCgQdNqbqRbRbBLt
QGhGddGCTdMHNTGgshgJhzvSmWWPSsnprpPzWzsWlr
hCJHTdJJNvTdSSNssjvfwgntwDgtgwDGCtZwtRRB
mbllFmFMFbMVWWLpbpZwwBZTZnnVwnTggtDB
MmzLQpFPTmPzHvfJNNzhNs
dzgBwzlgrrBrVLLlwLBgBlgRScDMMDDswMsHZRGDsZGZmM
HPfPbjCFJjCvfnnsjsDDcccmZsRSMc
hCvHfWPPnvJhPWpqNNhqLqzLqLLd

77
day4/day4.jl Normal file
View File

@@ -0,0 +1,77 @@
#!/usr/bin/env julia
using Test
function parse_line_ranges(line)
parts = split(line, ',')
ranges = Vector{UnitRange{Int64}}()
for p in parts
start, stop = split(p, '-', limit=2)
prange = UnitRange(parse(Int64, start), parse(Int64, stop))
push!(ranges, prange)
end
return ranges
end
function line_range_contained(line)
ranges = parse_line_ranges(line)
inter = intersect(ranges[1], ranges[2])
return (inter == ranges[1] || inter == ranges[2])
end
function line_range_overlap(line)
ranges = parse_line_ranges(line)
inter = intersect(ranges[1], ranges[2])
return length(inter) > 0
end
function count_range_contained(infile)
rsum = 0
open(infile, "r") do io
for line in eachline(io)
if line_range_contained(line)
rsum += 1
end
end
end
return rsum
end
function count_range_overlap(infile)
osum = 0
open(infile, "r") do io
for line in eachline(io)
if line_range_overlap(line)
osum += 1
end
end
end
return osum
end
function test()
@testset "elf cleaning contained" verbose=true begin
@test count_range_contained("example.txt") == 2
@test count_range_contained("input.txt") == 500
end
@testset "elf cleaning overlap" verbose=true begin
@test count_range_overlap("example.txt") == 4
@test count_range_overlap("input.txt") == 815
end
end
function main()
if size(ARGS, 1) == 0
test()
else
infile = ARGS[1]
println("infile = ", infile)
println("bad assignments: ", count_range_contained(infile))
end
end
main()

6
day4/example.txt Normal file
View File

@@ -0,0 +1,6 @@
2-4,6-8
2-3,4-5
5-7,7-9
2-8,3-7
6-6,4-6
2-6,4-8

1000
day4/input.txt Normal file

File diff suppressed because it is too large Load Diff

97
day5/day5.jl Normal file
View File

@@ -0,0 +1,97 @@
#!/usr/bin/env julia
using Test
function parse_stacks_line(line)
parts = Iterators.partition(line, 4)
return [s[2] for s in parts]
end
function read_stacks(io)
stacks = Vector{Vector{Char}}()
for line in eachline(io)
if isempty(line)
return stacks
end
if line[1:3] == " 1 "
continue
end
stacks_row = parse_stacks_line(line)
while length(stacks_row) > length(stacks)
push!(stacks, [])
end
for (i, c) in Iterators.enumerate(stacks_row)
if c == ' '
continue
end
pushfirst!(stacks[i], c)
end
end
return stacks
end
struct Move
count :: Int
from :: Int
to :: Int
end
function parse_move_line(line)
# move 1 from 2 to 1
parts = split(line)
return Move(parse(Int, parts[2]), parse(Int, parts[4]), parse(Int, parts[6]))
end
function read_apply_moves(stacks, io; rev::Bool = true)
for line in eachline(io)
move = parse_move_line(line)
if rev
for i in 1:move.count
push!(stacks[move.to], pop!(stacks[move.from]))
end
else
from_len = length(stacks[move.from])
from_range = UnitRange(from_len - move.count + 1, from_len)
append!(stacks[move.to], splice!(stacks[move.from], from_range))
end
end
return stacks
end
function operate_crane(infile; rev::Bool = true)
open(infile, "r") do io
stacks = read_stacks(io)
stacks2 = read_apply_moves(stacks, io, rev=rev)
return stacks2
end
end
function top_crates(stacks)
return join([last(s) for s in stacks])
end
function test()
@testset "elf crates 2000" verbose=true begin
@test top_crates(operate_crane("example.txt")) == "CMZ"
@test top_crates(operate_crane("input.txt")) == "QNHWJVJZW"
end
@testset "elf crates 2001" verbose=true begin
@test top_crates(operate_crane("example.txt", rev=false)) == "MCD"
@test top_crates(operate_crane("input.txt", rev=false)) == "BPCZJLFJW"
end
end
function main()
if size(ARGS, 1) == 0
test()
else
infile = ARGS[1]
println("infile = ", infile)
println("crates: ", read_stacks(infile))
stacks2 = operate_crane(infile)
println("after : ", stacks2)
println("top : ", top_crates(stacks2))
end
end
main()

9
day5/example.txt Normal file
View File

@@ -0,0 +1,9 @@
[D]
[N] [C]
[Z] [M] [P]
1 2 3
move 1 from 2 to 1
move 3 from 1 to 3
move 2 from 2 to 1
move 1 from 1 to 2

511
day5/input.txt Normal file
View File

@@ -0,0 +1,511 @@
[V] [T] [J]
[Q] [M] [P] [Q] [J]
[W] [B] [N] [Q] [C] [T]
[M] [C] [F] [N] [G] [W] [G]
[B] [W] [J] [H] [L] [R] [B] [C]
[N] [R] [R] [W] [W] [W] [D] [N] [F]
[Z] [Z] [Q] [S] [F] [P] [B] [Q] [L]
[C] [H] [F] [Z] [G] [L] [V] [Z] [H]
1 2 3 4 5 6 7 8 9
move 2 from 1 to 7
move 6 from 2 to 6
move 10 from 7 to 6
move 4 from 3 to 1
move 5 from 6 to 4
move 1 from 1 to 9
move 4 from 6 to 9
move 12 from 4 to 1
move 5 from 1 to 4
move 7 from 9 to 8
move 11 from 8 to 1
move 6 from 6 to 2
move 2 from 5 to 2
move 3 from 6 to 3
move 4 from 9 to 4
move 2 from 2 to 5
move 1 from 6 to 4
move 3 from 3 to 6
move 1 from 8 to 4
move 1 from 6 to 1
move 28 from 1 to 4
move 28 from 4 to 5
move 1 from 9 to 1
move 4 from 4 to 1
move 2 from 6 to 2
move 2 from 1 to 6
move 7 from 4 to 2
move 14 from 2 to 9
move 1 from 4 to 1
move 1 from 1 to 2
move 18 from 5 to 6
move 2 from 2 to 6
move 1 from 9 to 7
move 8 from 9 to 2
move 15 from 6 to 5
move 1 from 6 to 3
move 3 from 2 to 5
move 1 from 7 to 5
move 2 from 1 to 3
move 3 from 2 to 1
move 1 from 6 to 4
move 5 from 6 to 5
move 2 from 2 to 9
move 35 from 5 to 7
move 4 from 9 to 3
move 1 from 4 to 1
move 5 from 1 to 7
move 6 from 5 to 3
move 1 from 9 to 4
move 11 from 7 to 6
move 2 from 9 to 2
move 1 from 4 to 7
move 14 from 7 to 4
move 5 from 6 to 9
move 2 from 2 to 4
move 6 from 7 to 9
move 2 from 9 to 5
move 6 from 9 to 5
move 8 from 4 to 9
move 5 from 4 to 3
move 3 from 5 to 7
move 1 from 3 to 9
move 5 from 3 to 4
move 7 from 9 to 8
move 2 from 7 to 4
move 4 from 5 to 7
move 1 from 5 to 3
move 5 from 6 to 4
move 8 from 4 to 8
move 5 from 7 to 6
move 1 from 4 to 7
move 3 from 6 to 9
move 2 from 6 to 5
move 7 from 8 to 3
move 2 from 5 to 9
move 17 from 3 to 1
move 3 from 1 to 3
move 6 from 8 to 9
move 4 from 4 to 7
move 6 from 3 to 5
move 2 from 8 to 5
move 14 from 7 to 5
move 2 from 4 to 5
move 6 from 9 to 5
move 1 from 7 to 9
move 1 from 6 to 9
move 8 from 1 to 9
move 8 from 5 to 2
move 2 from 1 to 3
move 7 from 2 to 6
move 2 from 3 to 4
move 1 from 2 to 6
move 3 from 1 to 6
move 16 from 9 to 4
move 2 from 9 to 8
move 1 from 1 to 6
move 2 from 9 to 4
move 1 from 6 to 9
move 1 from 6 to 1
move 1 from 1 to 7
move 1 from 6 to 9
move 1 from 9 to 3
move 1 from 3 to 8
move 1 from 9 to 2
move 1 from 2 to 7
move 2 from 5 to 3
move 7 from 5 to 8
move 2 from 7 to 9
move 1 from 6 to 7
move 3 from 6 to 9
move 10 from 8 to 7
move 1 from 4 to 3
move 3 from 3 to 1
move 1 from 7 to 1
move 19 from 4 to 6
move 3 from 9 to 7
move 1 from 9 to 2
move 2 from 1 to 7
move 1 from 9 to 1
move 12 from 6 to 9
move 2 from 7 to 1
move 1 from 2 to 4
move 11 from 6 to 3
move 1 from 4 to 8
move 1 from 6 to 8
move 11 from 7 to 9
move 2 from 8 to 9
move 18 from 9 to 6
move 5 from 3 to 7
move 5 from 3 to 8
move 11 from 5 to 6
move 26 from 6 to 4
move 1 from 6 to 5
move 1 from 3 to 7
move 3 from 8 to 3
move 1 from 8 to 7
move 3 from 3 to 6
move 5 from 9 to 3
move 1 from 4 to 9
move 8 from 4 to 5
move 2 from 7 to 8
move 3 from 3 to 6
move 3 from 4 to 6
move 7 from 7 to 4
move 1 from 9 to 1
move 5 from 5 to 3
move 2 from 9 to 7
move 3 from 8 to 2
move 7 from 3 to 7
move 1 from 7 to 6
move 3 from 5 to 6
move 7 from 4 to 8
move 10 from 4 to 5
move 2 from 4 to 2
move 3 from 7 to 5
move 2 from 4 to 1
move 6 from 8 to 5
move 5 from 1 to 4
move 5 from 4 to 2
move 5 from 7 to 8
move 10 from 2 to 8
move 3 from 8 to 3
move 2 from 5 to 3
move 13 from 6 to 1
move 19 from 5 to 3
move 12 from 3 to 9
move 4 from 8 to 2
move 2 from 6 to 7
move 5 from 8 to 7
move 9 from 3 to 9
move 1 from 5 to 9
move 2 from 7 to 6
move 3 from 2 to 3
move 15 from 9 to 3
move 13 from 3 to 5
move 1 from 6 to 2
move 5 from 5 to 8
move 1 from 2 to 5
move 1 from 7 to 6
move 6 from 9 to 6
move 6 from 6 to 8
move 4 from 7 to 1
move 2 from 3 to 6
move 11 from 1 to 9
move 1 from 2 to 3
move 4 from 5 to 6
move 1 from 1 to 6
move 10 from 9 to 2
move 8 from 2 to 3
move 3 from 1 to 2
move 8 from 3 to 1
move 5 from 5 to 4
move 1 from 9 to 8
move 2 from 3 to 7
move 2 from 4 to 5
move 6 from 1 to 6
move 9 from 8 to 1
move 16 from 1 to 9
move 2 from 7 to 3
move 3 from 3 to 8
move 6 from 9 to 6
move 1 from 5 to 4
move 1 from 3 to 8
move 5 from 2 to 1
move 5 from 1 to 9
move 2 from 4 to 9
move 4 from 8 to 6
move 1 from 8 to 7
move 4 from 8 to 5
move 2 from 8 to 2
move 17 from 9 to 5
move 11 from 5 to 7
move 1 from 2 to 5
move 1 from 2 to 5
move 1 from 9 to 1
move 1 from 1 to 6
move 5 from 7 to 6
move 20 from 6 to 7
move 4 from 6 to 4
move 15 from 7 to 8
move 2 from 3 to 7
move 1 from 6 to 5
move 10 from 8 to 4
move 1 from 3 to 6
move 4 from 6 to 4
move 13 from 7 to 8
move 1 from 7 to 5
move 1 from 6 to 3
move 1 from 6 to 3
move 1 from 6 to 9
move 9 from 4 to 1
move 3 from 8 to 2
move 14 from 5 to 6
move 2 from 2 to 8
move 1 from 3 to 9
move 14 from 6 to 2
move 1 from 3 to 9
move 1 from 9 to 3
move 15 from 2 to 1
move 1 from 3 to 9
move 4 from 4 to 9
move 10 from 8 to 5
move 1 from 9 to 5
move 1 from 1 to 5
move 4 from 8 to 7
move 3 from 9 to 3
move 1 from 8 to 5
move 1 from 4 to 7
move 2 from 8 to 7
move 6 from 5 to 6
move 4 from 1 to 2
move 1 from 2 to 5
move 2 from 2 to 8
move 2 from 8 to 1
move 3 from 7 to 2
move 3 from 4 to 9
move 18 from 1 to 8
move 1 from 7 to 3
move 3 from 9 to 6
move 1 from 1 to 5
move 5 from 6 to 4
move 2 from 1 to 9
move 8 from 4 to 5
move 4 from 3 to 2
move 16 from 5 to 4
move 8 from 8 to 6
move 2 from 2 to 6
move 1 from 7 to 6
move 7 from 8 to 1
move 1 from 2 to 3
move 2 from 8 to 3
move 4 from 4 to 9
move 4 from 1 to 2
move 1 from 7 to 2
move 1 from 5 to 4
move 1 from 3 to 7
move 3 from 4 to 5
move 1 from 9 to 6
move 9 from 2 to 5
move 2 from 3 to 6
move 3 from 5 to 8
move 3 from 1 to 7
move 4 from 5 to 8
move 1 from 4 to 3
move 5 from 9 to 5
move 5 from 5 to 8
move 1 from 3 to 4
move 4 from 5 to 1
move 2 from 5 to 4
move 13 from 6 to 2
move 12 from 2 to 9
move 3 from 9 to 2
move 4 from 1 to 6
move 8 from 6 to 2
move 1 from 4 to 9
move 3 from 7 to 9
move 2 from 9 to 8
move 1 from 7 to 2
move 9 from 9 to 5
move 2 from 8 to 6
move 4 from 2 to 3
move 1 from 7 to 2
move 1 from 6 to 4
move 4 from 3 to 9
move 9 from 5 to 8
move 10 from 4 to 2
move 1 from 4 to 7
move 1 from 6 to 2
move 1 from 6 to 7
move 13 from 2 to 6
move 1 from 2 to 5
move 6 from 6 to 5
move 7 from 5 to 8
move 1 from 4 to 5
move 27 from 8 to 5
move 3 from 6 to 3
move 2 from 8 to 6
move 8 from 9 to 5
move 1 from 7 to 9
move 1 from 6 to 2
move 4 from 5 to 9
move 2 from 3 to 4
move 9 from 2 to 5
move 1 from 4 to 1
move 1 from 4 to 2
move 1 from 2 to 4
move 1 from 3 to 7
move 1 from 1 to 3
move 1 from 3 to 9
move 6 from 9 to 4
move 1 from 7 to 5
move 13 from 5 to 2
move 1 from 9 to 5
move 1 from 7 to 2
move 5 from 2 to 7
move 8 from 5 to 7
move 6 from 4 to 2
move 1 from 4 to 5
move 3 from 2 to 4
move 4 from 2 to 7
move 2 from 4 to 3
move 13 from 7 to 3
move 5 from 2 to 3
move 4 from 7 to 8
move 11 from 3 to 8
move 11 from 5 to 9
move 4 from 6 to 9
move 1 from 6 to 5
move 1 from 4 to 2
move 1 from 3 to 6
move 3 from 2 to 6
move 3 from 6 to 2
move 1 from 6 to 1
move 1 from 3 to 8
move 3 from 3 to 6
move 2 from 2 to 7
move 4 from 3 to 9
move 16 from 9 to 2
move 1 from 7 to 8
move 2 from 2 to 8
move 9 from 2 to 3
move 6 from 2 to 7
move 1 from 6 to 3
move 2 from 9 to 2
move 1 from 9 to 7
move 2 from 6 to 3
move 4 from 3 to 9
move 2 from 2 to 7
move 1 from 2 to 5
move 14 from 5 to 6
move 14 from 6 to 3
move 4 from 9 to 8
move 5 from 8 to 4
move 1 from 1 to 5
move 4 from 8 to 1
move 1 from 5 to 9
move 8 from 7 to 2
move 18 from 3 to 7
move 1 from 1 to 5
move 1 from 1 to 9
move 1 from 4 to 5
move 1 from 8 to 5
move 8 from 2 to 9
move 3 from 5 to 8
move 7 from 7 to 1
move 3 from 4 to 7
move 1 from 3 to 6
move 7 from 8 to 3
move 2 from 9 to 3
move 3 from 8 to 9
move 9 from 1 to 7
move 9 from 3 to 4
move 2 from 3 to 4
move 12 from 7 to 4
move 1 from 3 to 8
move 1 from 8 to 7
move 8 from 4 to 7
move 11 from 4 to 9
move 5 from 4 to 8
move 19 from 7 to 9
move 1 from 6 to 2
move 2 from 7 to 4
move 2 from 8 to 3
move 1 from 7 to 8
move 1 from 3 to 2
move 3 from 8 to 4
move 1 from 8 to 9
move 1 from 3 to 2
move 36 from 9 to 1
move 5 from 9 to 6
move 5 from 4 to 2
move 24 from 1 to 3
move 5 from 6 to 7
move 1 from 1 to 4
move 14 from 3 to 4
move 4 from 7 to 3
move 1 from 8 to 5
move 5 from 2 to 9
move 1 from 1 to 6
move 5 from 9 to 1
move 3 from 2 to 3
move 1 from 5 to 3
move 11 from 4 to 2
move 1 from 7 to 1
move 6 from 1 to 9
move 3 from 4 to 2
move 1 from 6 to 7
move 10 from 1 to 7
move 3 from 2 to 1
move 3 from 3 to 2
move 2 from 1 to 7
move 1 from 4 to 8
move 13 from 3 to 2
move 1 from 8 to 3
move 2 from 7 to 5
move 2 from 3 to 7
move 2 from 5 to 2
move 1 from 1 to 7
move 28 from 2 to 6
move 1 from 2 to 3
move 2 from 8 to 2
move 6 from 9 to 7
move 1 from 3 to 8
move 1 from 9 to 8
move 3 from 6 to 2
move 14 from 7 to 9
move 3 from 2 to 1
move 2 from 2 to 9
move 2 from 1 to 9
move 1 from 9 to 1
move 7 from 6 to 9
move 2 from 1 to 4
move 2 from 4 to 6
move 4 from 8 to 7
move 1 from 7 to 6
move 1 from 8 to 1
move 1 from 3 to 6
move 1 from 1 to 5
move 14 from 9 to 8
move 1 from 5 to 9
move 5 from 7 to 3
move 16 from 6 to 3
move 2 from 7 to 4
move 8 from 9 to 5
move 6 from 6 to 1
move 8 from 5 to 9
move 2 from 7 to 4
move 11 from 9 to 1
move 4 from 4 to 1
move 14 from 8 to 3
move 2 from 1 to 7
move 20 from 3 to 6
move 5 from 3 to 1
move 1 from 3 to 5
move 2 from 7 to 4
move 20 from 6 to 7
move 18 from 7 to 6
move 17 from 6 to 9
move 1 from 5 to 3
move 6 from 3 to 2
move 3 from 3 to 1
move 1 from 6 to 2
move 2 from 7 to 8
move 4 from 1 to 5
move 2 from 4 to 9
move 1 from 3 to 2
move 1 from 8 to 6
move 18 from 1 to 4
move 1 from 2 to 7
move 1 from 6 to 2
move 3 from 4 to 3
move 1 from 8 to 1
move 4 from 1 to 6
move 7 from 2 to 1
move 1 from 5 to 7
move 1 from 4 to 1
move 2 from 6 to 3
move 3 from 5 to 9
move 9 from 9 to 8
move 10 from 9 to 3
move 9 from 3 to 5

57
day6/day6.jl Normal file
View File

@@ -0,0 +1,57 @@
#!/usr/bin/env julia
using Test
function string_start_index(s, width=4)
delta = width - 1
for i in 1:length(s)-delta
if length(Set(s[i:i+delta])) == width
println(i, " ", s[i:i+delta])
return i + delta
end
end
end
function file_start_index(infile, width=4)
io = open(infile, "r")
data = readchomp(io)
close(io)
return string_start_index(data, width)
end
function test()
@testset "elf signal start ex" verbose=true begin
@test string_start_index("mjqjpqmgbljsphdztnvjfqwrcgsmlb") == 7
@test string_start_index("bvwbjplbgvbhsrlpgdmjqwftvncz") == 5
@test string_start_index("nppdvjthqldpwncqszvftbrmjlhg") == 6
@test string_start_index("nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg") == 10
@test string_start_index("zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw") == 11
@test string_start_index("wewewewewewewewewewewewewebo") == 28
end
@testset "elf signal start in" verbose=true begin
@test file_start_index("input.txt") == 1142
end
@testset "elf signal msg ex" verbose=true begin
@test string_start_index("mjqjpqmgbljsphdztnvjfqwrcgsmlb", 14) == 19
@test string_start_index("bvwbjplbgvbhsrlpgdmjqwftvncz", 14) == 23
@test string_start_index("nppdvjthqldpwncqszvftbrmjlhg", 14) == 23
@test string_start_index("nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg", 14) == 29
@test string_start_index("zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw", 14) == 26
end
@testset "elf signal msg in" verbose=true begin
@test file_start_index("input.txt", 14) == 2803
end
end
function main()
if size(ARGS, 1) == 0
test()
else
infile = ARGS[1]
println("infile = ", infile)
println("start index: ", file_start_index(infile))
end
end
main()

1
day6/input.txt Normal file
View File

@@ -0,0 +1 @@
wzsspbssbhshchmmrmprmrfrsfrrjhjphjjtppbfflqfqppdhdbhdhbbjgghgzgsgfsfhfhvvwcwhwwnppsbsggqnnvvtffpssjfjnnltntdtdddptprppjmmqssrlrplllfrrzggbmmlmnmtnnzddfdgfdfsstbstbbzcbbcjcvvfwwwzlzssglsgllnbnmbnmbbgmmppmwwsrrzqqvgqgnqnmmswwrnnbsnnbdbwwqnwqnwwzzqwzqzjqqwbqbccjcwwjlwjwppqfqjffwddrzrjzrjzzzhchjjlqqrggzvvnlvnvjvhvnvjvbbvdvldldbbwddtsscbbhccmbmbppbmmgjggcjjlrrwjwtjwwmffgddwvdvbdbvvhchmhmdmwwbjbjcbbcmbmmslmlslsjjrnrjrjpjcjgcjcjbbwsbsbfssjzsjsggcmcsswgssbbqpbqqdsdqqztzmzpmpbmbvbjjtrjtthwhbhnbhnbnssvpvsppgrrcwrrmqqhpphrpphchvhphqhbqbtttllsrlsrshrrmhmvvrmrnngbgnbnpbprrrftfjtjwwmrmvmcmvmrmwmssrccfbbhppjbpbwbqwbqbzzfmzmtttjbbvcvppmwwrbbzsbzbfzfdzzhrhzhvvsqvsqsnslljwllqlwllvccnttzhtzzpspqspqsqgsssvnsvshvsvqvnvlldbbfdfmmpbpgphhpqhpppchhbfbrfrllntnznrrhdrdhhdhjjgwwqhhfssjbjwjqqbffvvcrchccwmcwcllljtjrrqgrrdcrddvfvwvzzjqqcffgjgzzdhdwdssffjjhccggmtmltlhtthzhvhlvlddsfsbbtjbjcbjcjzcjjpfjfzzpnnbtbqtbqtqptpnplllbzbllhbllnqnttpddqvdqvqmmjnjggnnnhqqfcqcffqppdgpddvqddmhmrhrtrmrzmzhzpzlzqlqpqhphrpppjqqppzbzmmjgggqtggtjthhlclnclcnccmcppdcpddqrrfgrgbbhwhdhrrqtqpqjpqjpqjqqmcqmccnngqqqmtqtssnvnzvvpcpwcwwqcqqqfcqffsvsmvmttttmrrzssghgssjmsmbmvvwggggzhhfvdpgjmmvzbfjghqhrfbpmbvjzwvfmcthrqwdhghpwsspmhpqnmwhjzpnlzfnvhdnnrqwnvctbmjqzhqrpjlwrssdlwqzmsfrfzmgjhnwwnwczswnhsdbvqbmdlvntsdrhrjjcjjhpbblgwhjwdcdjtpvtmslwvncwdjbwzvbpzbvddvssnrhtshrcvnhqnpmjzfswqbbrztnwjcpflfbhnphfwmjvnvtswgfttgjcqcngmmwjlfsprwfcfwcmgrgbnqmzbtzbtbztngvrzpsnrzvhbsdjnzpwwzllgnfdrlwpmnrznqsqcmvnfbnhqjddvcjmtgbpbmsgqdqzflmlmqncmhwltrmdmgnwpfwddrdpfhsgsnggchzjhgpwrsmdzgjtrgmnprhbwbcbpzbdvvstfqcnqzbdjqpmrdbtgcthtclftghhmnrzrjqqsbndhpvmdpfpwdlhvmczvdfgvpqclssvlhqnhlcfnfbvtspdzmgzdctvpdcwchtqhpsgmmblspjdlvgblbpgrfrgnqqsphcsrgfsdmpqscbjmnqrfbcwfthdtswbzthpnvsfbntnbmmgpfzlqwhppvvdrmwbqzbgppbgsqmjfqtmntgwpnccthftwdmvwmnchlbjhsnmbhndczbrhhjpbvnjdzrcndbbmfwfwsjwfgbqhwhrsvlngsbhhlrdjzzbmjpsqhlpzwcsntjhlmngblspmsjrjwsjsrqwnrcwsmcsbmpjwrthbqhrschrmrppnnbmjbvjzlmzsrfdwqlfnfjljftjvzsqdwlhbblqcdlqjbprpcllhlhmwrbrlgfrcqshrtjpnmhljttdvpfnhdjqvjhhfczwvbzqgnzgljcfrbpgwnfhfchwzqmqqzpbcdpqmnbrppzblnnzqrfnmgtljwnfgzwvnjppdbdhbznvpgwhbdjjvlspgwgjsmfsvllpgwlfnnptmwnfsshjjvqzjwrqpvmsphpmftqdllqqdzcjwfvpftgvspprdwvvcnglmbpntghntdwpjvvsppgjvnbjgvtzchtqtwbddncsbrfcvrnvlggvwgmmnfzrswnzjrwthzmdsmzqmzsnrqsnslnhmfqljnnnzshqfqshrhhjmnhdgphctswdbhnrcgnzmmzqpjqbtdfhhltsmvvtntbgsznshhsghblhlhqpmdcfhmnfzvhgnfsfflcfwbfqzmccrjdpfvphtqbrdnzjfmfhbzqcpdnjdcgwprvchlzrcvrghgjqncjvnndbcshntrfsbsnmjlhclnzpfdgztflcpwqpnvlscfndwqzfvcmpgfncszpmwcsrdbrrhdjvmthslfvmlgpqhlgwhqnjljcvhswbsbqfrfhvzwjvdmhzsgbmbmfnbpclqdwhvrlpppszptjvwtvdmfltfqqgjttdggcvllblnnhjqnjzhvpgpzzpzwbpjqbthnjjlmsjgjzqwnjlqrcdmmvsldtcrzqdrcmwqhnhfghdlmzwcspgmlpzhbdsmlwlqnhhvcvdfzmvfwpbfmjtdllprfqzzjpbrshdzgspsrlrwrhdpmznzzqngwrzqpmtwgbsswrnnnfctjhbcftnslsqwjvmfwfdvfqcnsvfsvgstgbzpmljjtlvtnfsdzpvcgbjqwgbgzqbjfgltqvnhffflsbjzfqfrfbssrvvwqvqptmhrbgllqjwptrzgvqgccsrvbgtvmzfzlmtqrgfwhzddsptclbhjlwqfntvjqdvcddnffmbtqrnsvtmlvljcqdsrpggcmqvmmlzwwbgznhblwzjdppvtqzjvcmtfzhdzjplrdbrfrgzpldvnsgqlbwbmfvrbgwzmjmmqdfgwtbgtzmdqnvqbwvcfjhddqvnjtjlhhjnltbtqqvblwlmglrqcrcfjvdntrnqzzbmrjqglmrdcjgnshcghtprjqqsdrmgdnzmzcfqqdtjtrqgtqtgrpmmgzjtcrznmqccjbdpbvrnnbmbzvgdcnrczbctbrsrrqrjnfcdpzlnngwvcdtbbgssvhpptntqdzhcqtlpvzjbfgzggrgrcgtdfjbwdcrpztnfcdbscnlmqmwcbmtnddgbmhwsgvcfdcmhlsvtnqtmrnsjzhppgwvzlmhwwmpfjzrfbhsgntzrdhwswrnfmmmczqrvdrqnhgrvqbdddhglwsftsljvgbnjqfwfzsspdqvgsnlgfsfpvdrjhzcldtrmjjrmdhvvfrjldhhtqnvsvlldjpjbpwstfsmrpmbqbnnpvqtbgjvblthbmwqtfcfgnjscvtbvlqcmlhffpzgjzfscsqwnhrjhvbrrzwqvbjwtwhtqsdbssfgncppnsfgfltdcbjqjzqqtprsbvjzhmchnltvmbsvpvhgzhfhbrnttsqbcmwpdnwqqgdrjrdwdhtzwsmcdffqgsddvbzfjhtfhtnfdbfrwmdtcqshfjrcpswzcptgwgmctpmzjdbqlmqwthmnfplmctpsslcsdtqpqhjtmjdnmnqnjgchwstsmtpvsmgpsbfgwqnzhrdgdvcdlcldfcmjvsdldgbmhltjhczffwmzqssnhfnwftfgpshntjbpjdffjpcmcpwhclrrwqcqzmntjglzgcfrplfpvprtpvpjdlcrfwrtrzdzmhsrsmdcpqqrqgvfpdbmzbzqdfhpplmgfrdghclbclgswvwhhdvcpmpzflpffmptcrwglftztccrpbrvmpnqmqdgjgrrlbtqtvgcjpljttwtdslqjqlsdpblgrqbrtbmtblfbqtbvsqhpqzpqfhjqpmjrmcvqmsbbpjpdncgnjftclbltwszrrfzqbjcdtphcvpmbhppvwjwlprgmghrjzzgnvzlvghnjbzqjpdgzfsnjchpbzqdzpsjmsrvvqwjcpwznlpbjldlrdfqtrzhqzcnpjqbbbf

105
day7/day7.jl Normal file
View File

@@ -0,0 +1,105 @@
#!/usr/bin/env julia
using Test
mutable struct Dir
path :: String
dnames :: Vector{String}
fsize :: Int32
end
function get_dir_map(infile)
cwd = Vector{String}()
path = "/"
dirmap = Dict{String, Dir}()
open(infile, "r") do io
for line in eachline(io)
parts = split(line)
if parts[1] == "\$"
if parts[2] == "cd"
if parts[3] == "/"
empty!(cwd)
elseif parts[3] == ".."
pop!(cwd)
else
push!(cwd, parts[3])
end
path = "/" * join(cwd, '/')
if ! haskey(dirmap, path)
dirmap[path] = Dir(path, [], 0)
end
elseif parts[2] != "ls"
println("Unknown command: ", line)
end
else
parts = split(line, limit=2)
if parts[1] == "dir"
push!(dirmap[path].dnames, joinpath(path, parts[2]))
else
dirmap[path].fsize += parse(Int, parts[1])
end
end
end
end
for k in sort(collect(keys(dirmap)), by=p->length(p), rev=true)
v = dirmap[k]
for p in v.dnames
dirmap[k].fsize += dirmap[p].fsize
end
end
return dirmap
end
function small_dir_sum(infile)
dirmap = get_dir_map(infile)
small_sum = 0
for v in values(dirmap)
if v.fsize <= 100000
small_sum += v.fsize
end
end
return small_sum
end
function delete_candidate_size(infile)
dirmap = get_dir_map(infile)
total = 70000000
want = 30000000
used = dirmap["/"].fsize
free = total - used
need = want - free
candidates = Vector{Int64}()
# println("used ", used)
# println("free ", free)
# println("need ", need)
for v in values(dirmap)
if v.fsize >= need
push!(candidates, v.fsize)
end
end
return minimum(candidates)
end
function test()
@testset "disk usage small dir sum" verbose=true begin
@test small_dir_sum("example.txt") == 95437
@test small_dir_sum("input.txt") == 1306611
end
@testset "disk usage delete candidate size" verbose=true begin
@test delete_candidate_size("example.txt") == 24933642
@test delete_candidate_size("input.txt") == 13210366
end
end
function main()
if size(ARGS, 1) == 0
test()
else
infile = ARGS[1]
println("infile = ", infile)
println("error priority sum: ", rucksack_errors(infile))
end
end
main()

23
day7/example.txt Normal file
View File

@@ -0,0 +1,23 @@
$ cd /
$ ls
dir a
14848514 b.txt
8504156 c.dat
dir d
$ cd a
$ ls
dir e
29116 f
2557 g
62596 h.lst
$ cd e
$ ls
584 i
$ cd ..
$ cd ..
$ cd d
$ ls
4060174 j
8033020 d.log
5626152 d.ext
7214296 k

1083
day7/input.txt Normal file

File diff suppressed because it is too large Load Diff

105
day8/day8.jl Normal file
View File

@@ -0,0 +1,105 @@
#!/usr/bin/env julia
using Test
function is_visible(tree_map, i, j)
v = tree_map[i, j]
less_v(x) = x < v
if all(less_v, tree_map[i, 1:j-1])
return true
end
if all(less_v, tree_map[i, j+1:end])
return true
end
if all(less_v, tree_map[1:i-1, j])
return true
end
if all(less_v, tree_map[i+1:end, j])
return true
end
return false
end
function visible_trees_at(tree_map, i, j)
nrows, ncols = size(tree_map)
v = tree_map[i, j]
ge_v(x) = x >= v
up_idx = findfirst(ge_v, tree_map[i-1:-1:1, j])
up_score = up_idx === nothing ? i - 1 : up_idx
down_idx = findfirst(ge_v, tree_map[i+1:end, j])
down_score = down_idx === nothing ? nrows - i : down_idx
left_idx = findfirst(ge_v, tree_map[i, j-1:-1:1])
left_score = left_idx === nothing ? j - 1 : left_idx
right_idx = findfirst(ge_v, tree_map[i, j+1:end])
right_score = right_idx === nothing ? ncols - j : right_idx
return (up_score, down_score,left_score, right_score)
end
function scenic_score(tree_map, i, j)
return prod(visible_trees_at(tree_map, i, j))
end
function read_uint_matrix(io)
lines = readlines(io)
matrix = Matrix{UInt8}(undef, length(lines), length(lines[1]))
for (i, line) in enumerate(lines)
matrix[i, :] = parse.(UInt8, collect(line))
end
return matrix
end
function count_visible(tree_map)
nrows, ncols = size(tree_map)
nvisible = 2 * (nrows + ncols) - 4
nvisible += sum([is_visible(tree_map, i, j) ? 1 : 0
for j in 2:nrows-1
for i in 2:ncols-1])
return nvisible
end
function max_scenic_score(tree_map)
nrows, ncols = size(tree_map)
return maximum([scenic_score(tree_map, i, j)
for j in 2:nrows-1
for i in 2:ncols-1])
end
function visiblility_map(tree_map)
nrows, ncols = size(tree_map)
vmap = Matrix{NTuple{4, Int}}(undef, nrows-2, ncols-2)
for j in 2:nrows-1
for i in 2:ncols-1
vmap[i-1, j-1] = visible_trees_at(tree_map, i, j)
end
end
return vmap
end
function test()
@testset "visible trees" verbose=true begin
@test count_visible(read_uint_matrix("example.txt")) == 21
@test count_visible(read_uint_matrix("input.txt")) == 1845
end
@testset "max score" verbose=true begin
@test max_scenic_score(read_uint_matrix("example.txt")) == 8
@test max_scenic_score(read_uint_matrix("input.txt")) == 230112
end
end
function main()
if size(ARGS, 1) == 0
test()
else
infile = ARGS[1]
println("infile = ", infile)
tree_map = read_uint_matrix(infile)
println("matrix: ", tree_map)
println("visible: ", count_visible(tree_map))
println("max score: ", max_scenic_score(tree_map))
println("visible at: ")
display(visiblility_map(tree_map))
println()
end
end
main()

5
day8/example.txt Normal file
View File

@@ -0,0 +1,5 @@
30373
25512
65332
33549
35390

99
day8/input.txt Normal file
View File

@@ -0,0 +1,99 @@
011201001000123232122300403211332202122424332111151523152310403222120311202224013311113203311122001
102201211220103202323002411123324024134251423232343141424431144431022143443131141222323122010012220
002022232232102013311311301321044421352134513235443522243113311323213013301030440423203311103101020
002212021110130112400112141310424411421435324412235335534245212325313312413434430114302030310200000
202000312203303110042324124431114212153432535412115323131323541522511253002131401212012131031321110
120203002030304244102444143021314124552253521343321513511124144454343454102412220143321013220111212
012133330030200444414333325255125142322121412245551424242135123513411533153323130432231002121211210
012300220003100211444401144353345522135453435223464636451554321531323513234331131114224102232333310
000201310302031301344341134512444312432566266533252332656654251123535525135213300040211242011230031
121002133124022203240512452433331223524622643252532325346635555552514352434233454024134201432001111
112213110140442401434531255323512525265655352543623565556265545555235551143135124203142220020302000
033001202421424143555311243322416262636322654432542644633525453666655354514351121150231101002002310
133303044321221102531154151541224245536464535622566355532543644552554644312231415325142303020031312
112333344411024045335422225146442243536464622553556234523445362524655623435243115242532313102020021
123023422310204444121415255225254435644446326664473564435422565325224635623542352154120001224144312
102303024142131515433355242322223363453633455657436436574636544336652564626641215232314243234004001
021344140434455245134415553542352643537665534644574553367446664254532523624521243554252411433032112
100140101131444142414254644644434663647646555637737475474473636562243265243536422253531252202124322
111043301134142345422324342454235374733474673456744577746755765343355535622342432251442244140231224
232120141224122324244532255543256467566454337465647735433663734756446566663442525425254525142212311
102310340244433433553362546534535757453376643763344566566557634664535744445254533545223521213213014
330111232252114431226334564636467643777466445537346735563633337744734474466254662225321443542401243
344311321253412213666443354643647347656735478884748547564466577774737677363226422622515344334010341
222340105234132533423442424376674757757675647476557547564445666676437755355626455436313331225343402
334241221121414455435265324646757456774784864846746867457546648735456677555624445353555434433340341
333430021343121666326363537633737767788775478777445558858444854755434544735362564626265444342330020
332224425333452333556456745375454657668644877658744844547774765844454475434765533256545152435214410
411322431421116436336347456774356844455867864644844878664785864444475567664473365652253123453220003
130345455115155526426437663665665668576686587847778476557678655576775553535745643522532344433523042
241333521455132466523664543556384776587787745658797755565556576546847447434775733626365325451531301
202135433134452323646546565545646885747548679876767658578565476458486465755545465664435422532454541
344025243154435524235475655536845545775797795959686975588855546544875685664377465455353661444452422
120511445324333353265334766654858656857755669695597899959957757545465687447345336332322634434414522
041425252513666643357433333888555778459755889566967799659865567757457567576463765323236366123221323
142343534134652443554434768544658774587669979986775985989879787975445856456554364645323653454511323
443155144123223566654765746758688875856899955996667659755976778586644774777456744653322566354532232
013242522162435447764573774877757879868788876799896979576555597985885468586473474464455426633333452
101431333345553353553337548577478656967866886877887889699999856979976485874455544477534422463331314
422325541533664573334736464857446675995799977868697688998787757585668584775766563477536636621514142
313315332565562573637376866486547776557979868979996867779966955885566785455767644565336236452541411
231122455364326235655644685888786685587796897688777698977986787596655865857448333576665523356143332
314415154446535337443754887576795586569678967879977696896667866768856785586774365336636426455324541
251324556334435537567468544665859588888869687767876697967887867856679658788866355353346553442543353
134353225423362456734666455757877769577678987866887877799886886885859796767664444665534363236114533
251241346545626367667578575687955957988796678987999979977897978877579787844755554533763646262143315
353543555544353753474346565789555799696999667888997899777669899867697878476845756644734243432245123
221521465632632737777766744748678869769669668898887888987898666789869785645678734643552655525624335
351552456455622567337644647486678857766866879798779999878779869885869788874885873744772665326352324
153242153665224557353455465857685566797887699998988788877767696668668675666664465757646436665554315
321113152666424547657348876876678597898779877779998999978978777885976658558676664444674243656333212
421511245364456777655754476646885699898678788797778788778778999795687589454774563737333365434325525
213532265252653474345766566877669898969767779777879797899977669868595997784466766655547455234435452
125232235356525353764645486577668857868788699799787978898988669878688867586564457353673236664223343
441242562562223643773466848558599657669669968987979987787969676777796877655876456745562442232541525
135122156635652746574578664849659556998698797778797889988788869797687977855447474475546334662522444
144315413442434666777478887855885568968799966889978797797867786966685589646488554737453225335213325
511213234443636433646678657654587788667696879878989799867699988765895758788675765445656425425334544
052145146243336363474565857687976889776768867898889967686967668565998666768575534675445244546424155
235513424332444756467574556745997958679678999799789777998968876679956958746554677637762355253554335
331155256654246447545776676487485655676699678967897779688898989999768655488874564764434223445132152
152152253254255234473347878744485766678897879689897888667968795675655864748584644653323363464154251
245154344235223346354765457746867586969968687876867899766986679689585778787473555663424264553541344
235253541263666477544377746867785766579566868896689699876766695956667455774677646576554255521144355
033522343456423455634354575764856898657669957896677776766596688857787474488436433455326554242331222
321532413246333226435563556578864759978657759897896799958558598588975755858856537673332523244522141
101422552442534324467345475684574877989759655788785857697957976679848768474665346435664653421242444
103425135453353666736674677847548667967885667765576995797857589796866646565443377775564436443333543
041131245522253556554636537878457787468577768876778599999689667978487755747676763666266652435545351
424232344536333364556466767555646468677996965895798968676966868665587584664535544755645232211324114
334034423343366322247357747635787857555667756956768657779596877655676555367754633345545442422145333
424344345121532564223643563774744574746844686888885779565686455664565643634566756543362551431252401
232123114442152332546734767375678475664877645798695799654765488755876545334345452455463633534433233
414423121145222454332477456654436757485685646546884446667744645744675377357654436554353221451345404
234130223314353235262655676637577858558554556467788664555466588778677546456334642623666524333250443
414001252524152463224524734765775677644765886656877578666575855788653533364773455446565352432424320
024323134311552535243564667476365737764685474446876486685546667685363735646643655435355533243440034
331141044111451522226436327536773637654887585478885586588745847444466365767232265352211455413531431
241321311312323233252665352455436545735388846445565487667644555744667753556266645332452431541341044
234030032312154414563442653244476576544654676884777445766434443476675746365245632242515342521301442
202112004552434344564624422526757574735736566643654737673776743354737744242533546523434111443034202
323422334452422412134566522262537334374446646774476534347655656336555632626663364214333341322443300
031243421344143515452456444553266345437737337675574563437533573575456463665443432215213541123241240
002114441013421154331235436253442576764555535635775735635377573353666526333623554524421352131443020
111342301013125124521245222663363363467436357434736773473777464564655622533254352444544553311114233
222323000331131531351433363334345533653474663466435557365553376535246564324662454422135233103003200
002103300342403311123432563445263435443255635353333564444573456633466424623313351545133022013122320
300304042333200223123432352234525626625234236453763536563235242224645265643515312312520000242200000
210121244033001141551213125554433445222532265463624234562324443435344362451243522525243002401410013
303323342040431313415255233251226626334264553655346266323665655652522363324341123235410333230402230
300112203021311400115231251543524354554262365526643622264625434236554412121342322522123434120120203
011001023222004142422445443143212526654365444643442536365453622222634154551441553400220414300301332
230032020342121242113341435444543253355352433246243543645634456552525315313143243431133302112320020
232132202131312144424224413332214322543242664652323324456222615212244414145113442320023403200012111
112222030320432400004224215552515412325221525356363643351335211141344255554442403013303120331312202
110321230332323212301432002424211134155124241552254334221154111545254253122214132321141212032221001
021020121321302320401011302153145251455114411155452245422422135453412153112033343412340101230302010
122203012232330222213342133012334131225335225325343355122151154444535354414423434423220001330003020
221120213213221333210131242440001425551432522221141211124544343151315104244333311124033221102312011
202201033331203122413021242022211002455531321354252412214332215513311231404032244320020330332301120

148
day9/day9.jl Normal file
View File

@@ -0,0 +1,148 @@
#!/usr/bin/env julia
using Test
using Images
struct Move
direction :: Char
count :: Int
end
mutable struct Point{T}
x::T
y::T
end
function parse_move(line)
parts = split(line, limit=2)
return Move(parts[1][1], parse(Int, parts[2]))
end
function read_moves(io)
return [parse_move(line) for line in readlines(io)]
end
function apply_move(head, tail, direction)
if direction == 'U'
head.y += 1
elseif direction == 'D'
head.y -= 1
elseif direction == 'L'
head.x -= 1
elseif direction == 'R'
head.x += 1
elseif direction != 'O'
throw(DomainError("Unknown direction"))
end
x_diff = head.x - tail.x
y_diff = head.y - tail.y
if abs(x_diff) <= 1 && abs(y_diff) <= 1
return head, tail
end
if abs(x_diff) <= 1
tail.x += x_diff
tail.y += sign(y_diff) * (abs(y_diff) - 1)
elseif abs(y_diff) <= 1
tail.y += y_diff
tail.x += sign(x_diff) * (abs(x_diff) - 1)
elseif abs(x_diff) == 2 && abs(y_diff) == 2
# possible with more than 2 knots
tail.x += sign(x_diff) * (abs(x_diff) - 1)
tail.y += sign(y_diff) * (abs(y_diff) - 1)
else
throw(DomainError("invalid knots " * string(head) * " " * string(tail)))
end
return head, tail
end
function get_visited(moves; nknots::Int=2)
visited = Set{NTuple{2, Int}}()
knots = [Point(0, 0) for _ in 1:nknots]
push!(visited, (knots[nknots].x, knots[nknots].y))
for move in moves
for _ in 1:move.count
knots[1], knots[2] = apply_move(knots[1], knots[2], move.direction)
for i in 2:nknots
_, knots[i] = apply_move(knots[i-1], knots[i], 'O')
end
push!(visited, (knots[nknots].x, knots[nknots].y))
end
end
return visited
end
function int_map(visited)
(min_x, max_x) = extrema([t[1] for t in visited])
(min_y, max_y) = extrema([t[2] for t in visited])
nrows = max_y - min_y + 1
ncols = max_x - min_x + 1
imap = zeros(Int, nrows, ncols)
for (x, y) in visited
imap[nrows - (y - min_y), (x - min_x + 1)] = 1
end
imap[nrows + min_y, 1 - min_x] = -1
return imap
end
function ascii_map(visited)
map_char(n) = (n == -1 ? 's'
: (n == 1 ? "#"[1] : '.'))
srows = mapreduce(map_char, *, int_map(visited), dims=2; init="")
return join(srows, "\n")
end
function scale_pixels(img, scale::Int)
(nrows, ncols) = size(img)
new_img = Matrix{RGB}(undef, nrows * scale, ncols * scale)
for i in 1:nrows
for j in 1:ncols
i2 = (i - 1) * scale + 1
j2 = (j - 1) * scale + 1
new_img[i2:i2+scale-1, j2:j2+scale-1] .= img[i, j]
end
end
return new_img
end
function image_map(visited; scale::Int=10)
imap = int_map(visited)
map_color(n) = (n == -1 ? RGB(0, 0.8, 0)
: (n == 1 ? RGB(0.2, 0.2, 0.0) : RGB(0, 0, 0)))
cmap = map(map_color, int_map(visited))
return scale_pixels(cmap, scale)
end
function test()
@testset "visited count 2 knot" verbose=true begin
@test length(get_visited(read_moves("example.txt"))) == 13
@test length(get_visited(read_moves("input.txt"))) == 6037
end
@testset "visited count 10 knot" verbose=true begin
@test length(get_visited(read_moves("example.txt"), nknots=10)) == 1
@test length(get_visited(read_moves("input.txt"), nknots=10)) == 2485
end
end
function main()
if size(ARGS, 1) == 0
test()
else
infile = ARGS[1]
println("infile = ", infile)
moves = read_moves(infile)
println("moves: ", moves)
visited = get_visited(moves)
println("visited: ", visited)
println("count : ", length(visited))
println(ascii_map(visited))
save("visited.png", image_map(visited))
visited10 = get_visited(moves, nknots=10)
println("visited10: ", visited10)
println("count10 : ", length(visited10))
println(ascii_map(visited10))
save("visited10.png", image_map(visited10))
end
end
main()

8
day9/example.txt Normal file
View File

@@ -0,0 +1,8 @@
R 4
U 4
L 3
D 1
R 4
D 1
L 5
R 2

8
day9/example2.txt Normal file
View File

@@ -0,0 +1,8 @@
R 5
U 8
L 8
D 3
R 17
D 10
L 25
U 20

2000
day9/input.txt Normal file

File diff suppressed because it is too large Load Diff