From 4d1313ebb0dfde750586d15fceb0585d8ddeaa32 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 8 Dec 2021 12:31:17 -0700 Subject: [PATCH] Add improved day8 code --- day8/p2improved.nim | 79 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 day8/p2improved.nim diff --git a/day8/p2improved.nim b/day8/p2improved.nim new file mode 100644 index 0000000..c43f933 --- /dev/null +++ b/day8/p2improved.nim @@ -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()