Add 2021-03 in Nim
This commit is contained in:
parent
053dde805d
commit
86893d983c
3 changed files with 84 additions and 5 deletions
|
@ -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.
|
78
challenges/2021/03-binaryDiagnostic/nim/challenge.nim
Normal file
78
challenges/2021/03-binaryDiagnostic/nim/challenge.nim
Normal file
|
@ -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
|
|
@ -8,10 +8,10 @@ Solutions to the [2021 Advent of Code](https://adventofcode.com/2021).
|
|||
|
||||
<!-- PARSE START -->
|
||||
|
||||
| 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! |
|
||||
|
||||
<!-- PARSE END -->
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue