Part 1 in nim
This commit is contained in:
parent
1ef1c05668
commit
3f8f891bd3
92
2021/3.ts
92
2021/3.ts
|
@ -3,8 +3,42 @@ const input = await collectArray(await inputLines("3"));
|
|||
|
||||
type SubmarineCommand = ["forward", number] | ["up", number] | ["down", number];
|
||||
|
||||
type Counters = [zeroCount: number, oneCount: number][];
|
||||
|
||||
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 {
|
||||
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 counter = Array.from(Array(width), (_) => [0, 0]);
|
||||
for (const l of input) {
|
||||
|
@ -13,20 +47,52 @@ export function part1(input: string[]): number {
|
|||
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++) {
|
||||
if (counter[i][1] >= counter[i][0]) ones++;
|
||||
ones = ones << 1;
|
||||
const newOxyGenCandidates: string[] = [];
|
||||
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);
|
||||
}
|
||||
if (newOxyGenCandidates.length == 1) {
|
||||
oxyGenRating = parseInt(newOxyGenCandidates[0], 2);
|
||||
/*
|
||||
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);
|
||||
}
|
||||
}
|
||||
ones = ones >> 1;
|
||||
const zeroes = ones ^ (Math.pow(2, width) - 1); // xor with a mask the same size as the width
|
||||
return ones * zeroes;
|
||||
return (oxyGenRating || 0) * (coScrubRating || 0);
|
||||
}
|
||||
|
||||
await measureDuration(() => console.log("Part 1", part1(input)));
|
||||
|
||||
export function part2(input: string[]): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
await measureDuration(() => console.log("Part 2", part2(input)));
|
||||
// await measureDuration(() => console.log("Part 2", part2(input)));
|
||||
|
|
51
2021/three.nim
Normal file
51
2021/three.nim
Normal 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
|
Loading…
Reference in a new issue