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
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)
|