#!/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)