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 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);
|
||||||
|
}
|
||||||
|
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;
|
return (oxyGenRating || 0) * (coScrubRating || 0);
|
||||||
const zeroes = ones ^ (Math.pow(2, width) - 1); // xor with a mask the same size as the width
|
|
||||||
return ones * zeroes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
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