You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
4.3 KiB

#!/usr/bin/env julia
#=
--- Part Two ---
Through a little deduction, you should now be able to determine the remaining digits. Consider again the first example above:
acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab |
cdfeb fcadb cdfeb cdbaf
After some careful analysis, the mapping between signal wires and segments only make sense in the following configuration:
dddd
e a
e a
ffff
g b
g b
cccc
So, the unique signal patterns would correspond to the following digits:
acedgfb: 8
cdfbe: 5
gcdfa: 2
fbcad: 3
dab: 7
cefabd: 9
cdfgeb: 6
eafb: 4
cagedb: 0
ab: 1
Then, the four digits of the output value can be decoded:
cdfeb: 5
fcadb: 3
cdfeb: 5
cdbaf: 3
Therefore, the output value for this entry is 5353.
Following this same process for each entry in the second, larger example above, the output value of each entry can be determined:
fdgacbe cefdb cefbgd gcbe: 8394
fcgedb cgb dgebacf gc: 9781
cg cg fdcagb cbg: 1197
efabcd cedba gadfec cb: 9361
gecf egdcabf bgf bfgea: 4873
gebdcfa ecba ca fadegcb: 8418
cefg dcbef fcge gbcadfe: 4548
ed bcgafe cdgba cbgef: 1625
gbdfcae bgc cg cgb: 8717
fgae cfgab fg bagce: 4315
Adding all of the output values in this larger example produces 61229.
For each entry, determine all of the wire/segment connections and decode the four-digit output values. What do you get if you add up all of the output values?
=#
infile = length(ARGS) > 0 ? ARGS[1] : "input.txt"
println("infile = ", infile)
function charset(s)
return Set(c for c in s)
end
unique_sizes = Set([2, 4, 3, 7])
size_map = Dict(2 => [1],
3 => [7],
4 => [4],
5 => [2, 3, 5],
6 => [0, 6, 9],
7 => [8])
segment_map = Dict(0 => "abcefg",
1 => "cf",
2 => "acdeg",
3 => "acdfg",
4 => "bcdf",
5 => "abdfg",
6 => "abdefg",
7 => "acf",
8 => "abcdefg",
9 => "abcdfg")
set_num_map = Dict(charset(v) => k for (k, v) in segment_map)
function get_map(inputs)
segmap = Dict(c => charset("abcdefg") for c in charset("abcdefg"))
by_len = Dict{Int, Vector{Set{Char}}}()
for s in inputs
len = length(s)
if haskey(by_len, len)
push!(by_len[len], charset(s))
else
by_len[len] = [charset(s)]
end
end
# segment 'a' is the element in 7 and not 1
segmap['a'] = setdiff(by_len[3][1], by_len[2][1])
# segment 'f' is the element in 1 that is also in all
# of the len 6 numbers [0, 6, 9], and segment 'c' is the
# other element in 1
len6_intersect = intersect(by_len[6][1], by_len[6][2], by_len[6][3])
segmap['f'] = intersect(by_len[2][1], len6_intersect)
segmap['c'] = setdiff(by_len[2][1], segmap['f'])
# segment 'b' is the element in 4 other than c/f that is also in all of
# the len 6 numbers, and 'd' is the other one
segmap['b'] = intersect(setdiff(by_len[4][1], by_len[2][1]),
len6_intersect)
segmap['d'] = setdiff(setdiff(by_len[4][1], by_len[2][1]),
segmap['b'])
# segment 'g' is the element in all len 6 numbers that is not any that
# we have already found
segmap['g'] = setdiff(len6_intersect,
union(segmap['a'], segmap['f'], segmap['c'],
segmap['b'], segmap['d']))
segmap['e'] = setdiff(segmap['e'],
union(segmap['a'], segmap['f'], segmap['c'],
segmap['b'], segmap['d'], segmap['g']))
segs_to_num = Dict{Set{Char}, Int}()
for (num, segs) in segment_map
num_seg_set = Set{Char}()
for c in segs
union!(num_seg_set, segmap[c])
end
segs_to_num[num_seg_set] = num
end
return segs_to_num
end
total = 0
for line in eachline(infile)
global total
inputs, outputs = [split(v) for v in split(line, " | ")]
set_to_num = get_map(inputs)
v = 0
nout = length(outputs)
for (i, s) in enumerate(outputs)
v += set_to_num[charset(s)] * 10^(nout - i)
end
total += v
end
println("sum ", total)