Add day3 problem + solution
This commit is contained in:
parent
c257ed1410
commit
51caf3c8ff
4 changed files with 1197 additions and 0 deletions
91
day3/p2.nim
Normal file
91
day3/p2.nim
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
import os
|
||||
import std/[strutils, enumerate, sets, sequtils]
|
||||
|
||||
proc getMostCommon(indices: var HashSet[int], values: var seq[string]): string =
|
||||
var counts = newSeq[int](len(values[0]))
|
||||
|
||||
for index in indices:
|
||||
let binary = values[index]
|
||||
for (i, binVal) in enumerate(binary):
|
||||
counts[i] += (if binVal == '1': 1 else: -1)
|
||||
|
||||
result = newString(counts.len)
|
||||
|
||||
for (i, val) in enumerate(counts):
|
||||
if val > 0: # one is most common, so gamma is one, epsilon is zero
|
||||
result[i] = '1'
|
||||
elif val < 0: # zero is most common, so gamma is zero, epsilon is one
|
||||
result[i] = '0'
|
||||
else: # zero and one are the same commonality
|
||||
result[i] = '1'
|
||||
|
||||
proc getLeastCommon(indices: var HashSet[int], values: var seq[string]): string =
|
||||
var counts = newSeq[int](len(values[0]))
|
||||
|
||||
for index in indices:
|
||||
let binary = values[index]
|
||||
for (i, binVal) in enumerate(binary):
|
||||
counts[i] += (if binVal == '1': 1 else: -1)
|
||||
|
||||
result = newString(counts.len)
|
||||
|
||||
for (i, val) in enumerate(counts):
|
||||
if val > 0: # one is most common, so gamma is one, epsilon is zero
|
||||
result[i] = '0'
|
||||
elif val < 0: # zero is most common, so gamma is zero, epsilon is one
|
||||
result[i] = '1'
|
||||
else: # zero and one are the same commonality
|
||||
result[i] = '0'
|
||||
|
||||
proc main() =
|
||||
let fileName = paramStr(1)
|
||||
|
||||
# if we have a one, increase the counter
|
||||
# otherwise for zero, decrease the counter for each bit
|
||||
# this will give a positive number for 1 being the most
|
||||
# common, and negative if 0 is the most common
|
||||
|
||||
var binarySeq = newSeq[string]()
|
||||
|
||||
for binary in fileName.lines:
|
||||
binarySeq.add(binary)
|
||||
|
||||
var o2Indices = toHashSet(toSeq(0..<binarySeq.len))
|
||||
var co2Indices = toHashSet(toSeq(0..<binarySeq.len))
|
||||
|
||||
var pos = 0
|
||||
while o2Indices.len > 1:
|
||||
var mostCommon = o2Indices.getMostCommon(binarySeq)
|
||||
if pos >= mostCommon.len:
|
||||
break
|
||||
let mc = mostCommon[pos]
|
||||
var o2Copy = o2Indices
|
||||
for index in o2Copy:
|
||||
let binVal = binarySeq[index][pos]
|
||||
if binVal != mc and o2Indices.len > 1:
|
||||
o2Indices.excl(index)
|
||||
|
||||
pos += 1
|
||||
|
||||
pos = 0
|
||||
while co2Indices.len > 1:
|
||||
var leastCommon = co2Indices.getLeastCommon(binarySeq)
|
||||
if pos >= leastCommon.len:
|
||||
break
|
||||
let lc = leastCommon[pos]
|
||||
var co2Copy = co2Indices
|
||||
for index in co2Copy:
|
||||
let binVal = binarySeq[index][pos]
|
||||
if binVal != lc and co2Indices.len > 1:
|
||||
co2Indices.excl(index)
|
||||
|
||||
pos += 1
|
||||
|
||||
let oxygen = binarySeq[o2Indices.toSeq[0]]
|
||||
let co2 = binarySeq[co2Indices.toSeq[0]]
|
||||
|
||||
let lifeSupport = oxygen.parseBinInt * co2.parseBinInt
|
||||
echo "Life support rating: ", lifeSupport
|
||||
|
||||
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue