Part 1 in nim

This commit is contained in:
Daniel Flanagan 2021-12-03 11:47:18 -06:00
parent 1ef1c05668
commit 3f8f891bd3
Signed by: lytedev
GPG key ID: 5B2020A0F9921EF4
2 changed files with 130 additions and 13 deletions

View file

@ -3,8 +3,42 @@ const input = await collectArray(await inputLines("3"));
type SubmarineCommand = ["forward", number] | ["up", number] | ["down", number]; type SubmarineCommand = ["forward", number] | ["up", number] | ["down", number];
type Counters = [zeroCount: number, oneCount: number][];
const ASCII_ZERO = "0".charCodeAt(0); const ASCII_ZERO = "0".charCodeAt(0);
function countBits(
input: string[],
width?: number,
windowWidth?: number,
): Counters {
if (!width) width = input[0].length;
if (!windowWidth) windowWidth = width;
const counter: Counters = Array.from(Array(width), (_) => [0, 0]);
for (const l of input) {
for (let i = width - windowWidth; i < width; i++) {
const val = l.charCodeAt(i) - ASCII_ZERO;
counter[i][val]++;
}
}
return counter;
}
export function part1(input: string[]): number { export function part1(input: string[]): number {
const width = input[0].length;
const counter = countBits(input);
const ones = [...Array(width).keys()].reduce((acc, i) =>
acc += (counter[i][1] >= counter[i][0]) ? (1 << i) : 0
);
// xor with a mask the same size as the width to get the zeroes value
console.log("oz:", ones);
return ones * (ones ^ (Math.pow(2, width) - 1));
}
await measureDuration(() => console.log("Part 1", part1(input)));
export function part2(input: string[]): number {
// I hate this.
const width = input[0].length; const width = input[0].length;
const counter = Array.from(Array(width), (_) => [0, 0]); const counter = Array.from(Array(width), (_) => [0, 0]);
for (const l of input) { for (const l of input) {
@ -13,20 +47,52 @@ export function part1(input: string[]): number {
counter[i][val]++; counter[i][val]++;
} }
} }
let ones = 0; let oxyGenRating = null;
let coScrubRating = null;
let oxyGenCandidates = input.slice(0);
let coScrubCandidates = input.slice(0);
for (let i = 0; i < width; i++) { for (let i = 0; i < width; i++) {
if (counter[i][1] >= counter[i][0]) ones++; const newOxyGenCandidates: string[] = [];
ones = ones << 1; const newCoScrubCandidates: string[] = [];
// console.log(counter[i]);
const moreCommon = (counter[i][1] > counter[i][0] ? 1 : 0).toString();
// console.log(i, width, moreCommon);
if (!oxyGenRating) {
for (const binnum of oxyGenCandidates) {
if (binnum[i] == moreCommon) newOxyGenCandidates.push(binnum);
} }
ones = ones >> 1; if (newOxyGenCandidates.length == 1) {
const zeroes = ones ^ (Math.pow(2, width) - 1); // xor with a mask the same size as the width oxyGenRating = parseInt(newOxyGenCandidates[0], 2);
return ones * zeroes; /*
console.log(
"Oxygen Generator Rating:",
oxyGenRating,
oxyGenCandidates,
newOxyGenCandidates,
);
*/
} else oxyGenCandidates = newOxyGenCandidates;
// console.log(oxyGenCandidates);
}
if (!coScrubRating) {
for (const binnum of coScrubCandidates) {
if (binnum[i] != moreCommon) newCoScrubCandidates.push(binnum);
}
if (newCoScrubCandidates.length == 1) {
coScrubRating = parseInt(newCoScrubCandidates[0], 2);
/*
console.log(
"CO2 Scrubber Rating:",
coScrubRating,
coScrubCandidates,
newCoScrubCandidates,
);
*/
} else coScrubCandidates = newCoScrubCandidates;
// console.log(coScrubCandidates);
}
}
return (oxyGenRating || 0) * (coScrubRating || 0);
} }
await measureDuration(() => console.log("Part 1", part1(input))); // await measureDuration(() => console.log("Part 2", part2(input)));
export function part2(input: string[]): number {
return 0;
}
await measureDuration(() => console.log("Part 2", part2(input)));

51
2021/three.nim Normal file
View file

@ -0,0 +1,51 @@
import std/[strutils, sequtils, options, math]
import ./common
const ASCII_ZERO = int('0')
type BitCounter = object
zeroes: int
ones: int
proc countBits(inputs: seq[string], maybeWidth: Option[int], maybeWindow: Option[int]): seq[BitCounter] =
let width = maybeWidth.get(inputs[0].len())
let window = maybeWindow.get(width)
let start = (width - window)
for i in 0..<window: result.add(BitCounter(zeroes: 0, ones: 0))
for binstring in inputs:
for i in start..<width:
if (binstring[i].int() - ASCII_ZERO) > 0: inc result[i - start].ones
else: inc result[i - start].zeroes
proc powerConsumption(inputs: seq[string]): int =
let counters = inputs.countBits(none(int), none(int))
let width: Natural = inputs[0].len()
for i in 0..<width:
if counters[i].ones > counters[i].zeroes: inc result
result = result shl 1
result = result shr 1
result = result * (result xor ((2 ^ width) - 1))
proc lifeSupportRating(inputs: seq[string]): int =
return 0
let input = 3.loadInput()
time("countBits part 1"): echo input.powerConsumption()
when not defined(release):
static:
let testInput = @[
"00100",
"11110",
"10110",
"10111",
"10101",
"01111",
"00111",
"11100",
"10000",
"11001",
"00010",
"01010",
]
doAssert testInput.powerConsumption() == 198
doAssert testInput.lifeSupportRating() == 230