104 lines
3 KiB
Nim
104 lines
3 KiB
Nim
import os, sets, math
|
|
import std/[strutils, sequtils]
|
|
|
|
type
|
|
Digit = enum
|
|
One = 2
|
|
Seven = 3
|
|
Four = 4
|
|
TwoThreeFive = 5
|
|
ZeroSixNine = 6
|
|
Eight = 7
|
|
|
|
proc main() =
|
|
let fileName = paramStr(1)
|
|
|
|
# The main idea here is to use process of elimination to find each number
|
|
# uniquely. To do this, we can use hashsets to eliminate or isolate numbers
|
|
# that we don't know.
|
|
|
|
var sum = 0
|
|
|
|
for line in fileName.lines:
|
|
let
|
|
lineSplit = line.split(" | ")
|
|
allDigits = lineSplit[0].strip().splitWhitespace()
|
|
displayDigits = lineSplit[1].strip().splitWhitespace()
|
|
|
|
var
|
|
oneDigit: HashSet[char]
|
|
fourDigit: HashSet[char]
|
|
sevenDigit: HashSet[char]
|
|
eightDigit: HashSet[char]
|
|
twoThreeFiveDigits = newSeqOfCap[HashSet[char]](3)
|
|
zeroSixNineDigits = newSeqOfCap[HashSet[char]](3)
|
|
|
|
for digit in allDigits:
|
|
case len(digit).Digit:
|
|
of One:
|
|
oneDigit.incl toHashSet(digit)
|
|
of Four:
|
|
fourDigit.incl toHashSet(digit)
|
|
of Seven:
|
|
sevenDigit.incl toHashSet(digit)
|
|
of Eight:
|
|
eightDigit.incl toHashSet(digit)
|
|
of TwoThreeFive:
|
|
twoThreeFiveDigits.add toHashSet(digit)
|
|
of ZeroSixNine:
|
|
zeroSixNineDigits.add toHashSet(digit)
|
|
|
|
# this section is pretty inefficient, but reduces code complexity. Since
|
|
# the seqs are only length 3, iterating over them multiple times is fine.
|
|
#
|
|
# we isolate the numbers based on process of elimination to uniquely identify
|
|
# each number
|
|
let
|
|
twoDigit = twoThreeFiveDigits.filterIt((it - fourDigit).len == 3)[0]
|
|
threeDigit = twoThreeFiveDigits.filterIt((it - oneDigit).len == 3)[0]
|
|
fiveDigit = twoThreeFiveDigits.filterIt((it - twoDigit).len == 2)[0]
|
|
|
|
lowerLeftSegment = twoDigit - threeDigit
|
|
upperLeftSegment = fourDigit - threeDigit
|
|
middleSegment = (fourDigit - oneDigit) - upperLeftSegment
|
|
upperRightSegment = (twoDigit - fiveDigit) - lowerLeftSegment
|
|
|
|
zeroDigit = zeroSixNineDigits.filterIt((it - middleSegment).len == 6)[0]
|
|
sixDigit = zeroSixNineDigits.filterIt((it - upperRightSegment).len == 6)[0]
|
|
nineDigit = zeroSixNineDigits.filterIt((it - lowerLeftSegment).len == 6)[0]
|
|
|
|
var localSum = 0
|
|
|
|
for i in 0 ..< displayDigits.len:
|
|
let displayDigit = toHashSet(displayDigits[i])
|
|
var digit: uint8
|
|
|
|
# there's probably a better way to do this
|
|
if displayDigit == zeroDigit:
|
|
digit = 0
|
|
if displayDigit == oneDigit:
|
|
digit = 1
|
|
elif displayDigit == twoDigit:
|
|
digit = 2
|
|
elif displayDigit == threeDigit:
|
|
digit = 3
|
|
elif displayDigit == fourDigit:
|
|
digit = 4
|
|
elif displayDigit == fiveDigit:
|
|
digit = 5
|
|
elif displayDigit == sixDigit:
|
|
digit = 6
|
|
elif displayDigit == sevenDigit:
|
|
digit = 7
|
|
elif displayDigit == eightDigit:
|
|
digit = 8
|
|
elif displayDigit == nineDigit:
|
|
digit = 9
|
|
|
|
localSum += (digit.float * math.pow(10.0, (3 - i).float)).int
|
|
|
|
sum += localSum
|
|
|
|
echo "Sum of digits: ", sum
|
|
|
|
main()
|