Add improved day8 code
This commit is contained in:
parent
33c5b2c829
commit
4d1313ebb0
1 changed files with 79 additions and 0 deletions
79
day8/p2improved.nim
Normal file
79
day8/p2improved.nim
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import os, math
|
||||
import std/[strutils, sequtils]
|
||||
|
||||
type
|
||||
Segment = enum sA, sB, sC, sD, sE, sF, sG
|
||||
Digit = set[Segment]
|
||||
|
||||
func toDigit(chars: string): Digit =
|
||||
chars.mapIt(Segment(ord(it) - ord('a'))).foldl(a + Digit({b}), Digit({}))
|
||||
|
||||
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 sets to eliminate or isolate numbers
|
||||
# that we don't know. Inspired by:
|
||||
# https://github.com/ZoomRmc/aoc2021_nim/blob/main/src/aoc08.nim
|
||||
|
||||
var sum = 0
|
||||
|
||||
const maxSetSize = 2^(Segment.high.int + 1)
|
||||
|
||||
for line in fileName.lines:
|
||||
let
|
||||
lineSplit = line.split(" | ")
|
||||
var
|
||||
digitMap: array[maxSetSize, int]
|
||||
allDigits = lineSplit[0].strip().splitWhitespace().map(toDigit)
|
||||
displayDigits = lineSplit[1].strip().splitWhitespace().map(toDigit)
|
||||
|
||||
# 0, 1, 2, 3, 4, 5, 6, 7
|
||||
let lenToNum = [-1, -1, 1, 7, 4, -1, -1, 8]
|
||||
|
||||
var
|
||||
decoded: array[10, Digit]
|
||||
group235: seq[Digit]
|
||||
group069: seq[Digit]
|
||||
|
||||
for digit in allDigits:
|
||||
case len(digit):
|
||||
of 2..4, 7:
|
||||
decoded[lenToNum[len(digit)]] = digit
|
||||
of 5:
|
||||
group235.add(digit)
|
||||
of 6:
|
||||
group069.add(digit)
|
||||
else: discard
|
||||
|
||||
for digit in group235:
|
||||
if (digit - decoded[4]).len == 3:
|
||||
decoded[2] = digit
|
||||
elif (digit - decoded[1]).len == 3:
|
||||
decoded[3] = digit
|
||||
else:
|
||||
decoded[5] = digit
|
||||
|
||||
for digit in group069:
|
||||
if (digit - decoded[4]).len == 2:
|
||||
decoded[9] = digit
|
||||
elif (digit - decoded[7]).len == 4:
|
||||
decoded[6] = digit
|
||||
else:
|
||||
decoded[0] = digit
|
||||
|
||||
for i, digit in decoded:
|
||||
digitMap[cast[int](digit)] = i
|
||||
|
||||
var i = 0
|
||||
# wish I could access the index in mapIt :/
|
||||
let mapped = displayDigits.mapIt:
|
||||
let power = 10^(3-i)
|
||||
i += 1
|
||||
digitMap[cast[int](it)] * power
|
||||
|
||||
sum += mapped.foldl(a+b)
|
||||
|
||||
echo "Sum of digits: ", sum
|
||||
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue