From 86893d983cf2f4371af32138dc816d338d9df059 Mon Sep 17 00:00:00 2001 From: AKP Date: Fri, 3 Dec 2021 15:34:24 +0000 Subject: [PATCH] Add 2021-03 in Nim --- challenges/2021/03-binaryDiagnostic/README.md | 1 + .../03-binaryDiagnostic/nim/challenge.nim | 78 +++++++++++++++++++ challenges/2021/README.md | 10 +-- 3 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 challenges/2021/03-binaryDiagnostic/nim/challenge.nim diff --git a/challenges/2021/03-binaryDiagnostic/README.md b/challenges/2021/03-binaryDiagnostic/README.md index 6f77e7f..600b7dc 100644 --- a/challenges/2021/03-binaryDiagnostic/README.md +++ b/challenges/2021/03-binaryDiagnostic/README.md @@ -1,2 +1,3 @@ # [Day 3: Binary Diagnostic](https://adventofcode.com/2021/day/3) +The Nim code is a direct translation of the Python code - see the Python code for descriptive comments. \ No newline at end of file diff --git a/challenges/2021/03-binaryDiagnostic/nim/challenge.nim b/challenges/2021/03-binaryDiagnostic/nim/challenge.nim new file mode 100644 index 0000000..7104e93 --- /dev/null +++ b/challenges/2021/03-binaryDiagnostic/nim/challenge.nim @@ -0,0 +1,78 @@ +import std/sequtils +import std/strformat +import std/strutils + +proc parse(instr: string): tuple[numbers: seq[int], length: int] = + let y = instr.splitLines.filter(proc(x: string): bool = x != "") + return (y.map(parseBinInt), y[0].len) + +proc getBit(number: int, n: int): int = + return (number shr n) and 0b1 + +proc analyseBits(numbers: seq[int], n: int): tuple[mostCommon, leastCommon: int] = + var + zeros = 0 + ones = 0 + + for _, number in numbers: + let sel = getBit(number, n) + case sel + of 0: + zeros += 1 + of 1: + ones += 1 + else: + raise newException(ValueError, fmt"impossible value {sel} reached") + + if zeros > ones: + return (0, 1) + elif ones > zeros: + return (1, 0) + return (-1, -1) + +proc partOne*(instr: string): int = + let (numbers, bitLength) = parse(instr) + + var gamma, epsilon: string + + for bitNumber in countdown(bitLength-1, 0): + let (mostCommon, leastCommon) = analyseBits(numbers, bitNumber) + gamma.add($mostCommon) + epsilon.add($leastCommon) + + return parseBinInt(gamma) * parseBinInt(epsilon) + +proc partTwo*(instr: string): int = + let (numbers, bitLength) = parse(instr) + + proc find(inp: seq[int], useMostCommon: bool, n: int = bitLength-1): int = + if inp.len == 1: + return inp[0] + + let (mostCommon, leastCommon) = analyseBits(inp, n) + + var target: int + if mostCommon == -1 or leastCommon == -1: + if useMostCommon: + target = 1 + else: + target = 0 + else: + if useMostCommon: + target = mostCommon + else: + target = leastCommon + + return find( + inp.filter( + proc(x: int): bool = getBit(x, n) == target, + ), + useMostCommon, + n-1 + ) + + let + o2Rating = find(numbers, true) + co2Rating = find(numbers, false) + + return o2Rating * co2Rating \ No newline at end of file diff --git a/challenges/2021/README.md b/challenges/2021/README.md index 35e97ab..5a580d5 100644 --- a/challenges/2021/README.md +++ b/challenges/2021/README.md @@ -8,10 +8,10 @@ Solutions to the [2021 Advent of Code](https://adventofcode.com/2021). -| Day | Status | Solutions | Notes | -| ----------------------------------- | ------------------ | ---------------------------------------------------------------------------- | ---------------------------- | -| 01 - Sonar Sweep | Complete | [Python](01-sonarSweep/py), [Go](01-sonarSweep/go), [Nim](01-sonarSweep/nim) | | -| 02 - Dive! | Complete | [Python](02-dive/py), [Go](02-dive/go) | | -| 02 - Binary Diagnostic | Complete | [Python](03-binaryDiagnostic/py) | Bit twiddling, my favourite! | +| Day | Status | Solutions | Notes | +| ----------------------------------- | ------------------ | ---------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| 01 - Sonar Sweep | Complete | [Python](01-sonarSweep/py), [Go](01-sonarSweep/go), [Nim](01-sonarSweep/nim) | Numbers and sliding windows. | +| 02 - Dive! | Complete | [Python](02-dive/py), [Go](02-dive/go) | Have this set of instructions and do something sensible with it. | +| 02 - Binary Diagnostic | Complete | [Python](03-binaryDiagnostic/py), [Nim](03-binaryDiagnostic/nim) | Bit twiddling aplenty! |