alright its fast now
This commit is contained in:
parent
6665b7030b
commit
2758ef369d
1 changed files with 65 additions and 14 deletions
|
@ -3,8 +3,10 @@ import { resolve } from 'node:path'
|
||||||
|
|
||||||
const pipe = (...fns) => x => fns.reduce((val, fn) => fn(val), x)
|
const pipe = (...fns) => x => fns.reduce((val, fn) => fn(val), x)
|
||||||
const add = (a, b) => a + b
|
const add = (a, b) => a + b
|
||||||
const sum = list => list.reduce(add, 0n)
|
const mul = (a, b) => a * b
|
||||||
const toInt = n => parseInt(n, 10)
|
const toInt = n => parseInt(n, 10)
|
||||||
|
const sum = (list, init = 0) => list.reduce(add, init)
|
||||||
|
|
||||||
|
|
||||||
function* scanLeft(xs) {
|
function* scanLeft(xs) {
|
||||||
for (let i = 0, j = 0; i < xs.length; i++) {
|
for (let i = 0, j = 0; i < xs.length; i++) {
|
||||||
|
@ -19,7 +21,7 @@ function* scanLeft(xs) {
|
||||||
|
|
||||||
function* scanRight(xs) {
|
function* scanRight(xs) {
|
||||||
const len = xs.length - 1
|
const len = xs.length - 1
|
||||||
for (let i = len; i > 0; i--) {
|
for (let i = len; i >= 0; i--) {
|
||||||
const token = xs[i]
|
const token = xs[i]
|
||||||
const value = i % 2 ? -1 : i / 2
|
const value = i % 2 ? -1 : i / 2
|
||||||
|
|
||||||
|
@ -32,10 +34,10 @@ function* scanRight(xs) {
|
||||||
const expand = input => {
|
const expand = input => {
|
||||||
const tokens = Array.isArray(input) ? input : input.split('')
|
const tokens = Array.isArray(input) ? input : input.split('')
|
||||||
const ints = tokens.map(toInt)
|
const ints = tokens.map(toInt)
|
||||||
return [scanLeft(ints), scanRight(ints), sum(tokens.map(BigInt))]
|
return [scanLeft(ints), scanRight(ints), sum(tokens.map(BigInt), 0n)]
|
||||||
}
|
}
|
||||||
|
|
||||||
function* defrag([fwd, bwd, len]) {
|
function* enfrag([fwd, bwd, len]) {
|
||||||
const swaps = new Set()
|
const swaps = new Set()
|
||||||
let i = 0n
|
let i = 0n
|
||||||
let j = len - 1n
|
let j = len - 1n
|
||||||
|
@ -45,7 +47,7 @@ function* defrag([fwd, bwd, len]) {
|
||||||
for (i, a; !a.done; a = fwd.next(), i += 1n) {
|
for (i, a; !a.done; a = fwd.next(), i += 1n) {
|
||||||
const x = a.value
|
const x = a.value
|
||||||
if (swaps.has(i)) {
|
if (swaps.has(i)) {
|
||||||
yield -1
|
yield - 1
|
||||||
swaps.delete(i)
|
swaps.delete(i)
|
||||||
continue
|
continue
|
||||||
} else if (x !== -1) {
|
} else if (x !== -1) {
|
||||||
|
@ -75,23 +77,72 @@ function* defrag([fwd, bwd, len]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const checksum = iter => {
|
const checksum = iter => {
|
||||||
let acc = 0
|
return iter.map(mul)
|
||||||
|
.filter(x => x > 0)
|
||||||
|
.reduce(add)
|
||||||
|
}
|
||||||
|
|
||||||
let j = 0
|
const expand3 = x => x.split('').map(toInt).map((x, i) => ([x, i % 2, i % 2 ? -1 : i / 2]))
|
||||||
for (const value of iter) {
|
|
||||||
const skip = value === -1
|
|
||||||
acc += skip ? 0 : j * value
|
|
||||||
|
|
||||||
if (!skip) {
|
const defrag2 = blocks => {
|
||||||
j++
|
const len = blocks.length - 1
|
||||||
|
for (let i = len; i > 0; i--) {
|
||||||
|
const right = blocks[i]
|
||||||
|
if (right[1]) { continue }
|
||||||
|
|
||||||
|
for (let j = 0; j < len; j++) {
|
||||||
|
if (i < j) { break }
|
||||||
|
const left = blocks[j]
|
||||||
|
if (!left[1]) { continue }
|
||||||
|
if (left[0] >= right[0]) {
|
||||||
|
blocks.splice(i, 1)
|
||||||
|
blocks.splice(j, 0, right)
|
||||||
|
left[0] -= right[0]
|
||||||
|
blocks.splice(i, 0, [right[0], 1, -1])
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return blocks
|
||||||
|
}
|
||||||
|
|
||||||
|
const naturalSum = n => (n * (n + 1)) / 2
|
||||||
|
const sumRange = (x, y) => naturalSum(y) - naturalSum(x - 1)
|
||||||
|
|
||||||
|
const checksum2 = blocks => {
|
||||||
|
let index = 0
|
||||||
|
let acc = 0
|
||||||
|
for (let i = 0; i < blocks.length; i++) {
|
||||||
|
const block = blocks[i]
|
||||||
|
const start = index
|
||||||
|
index += block[0]
|
||||||
|
if (block[1] > 0) { continue }
|
||||||
|
acc += block[2] * sumRange(start, start + block[0] - 1)
|
||||||
|
}
|
||||||
return acc
|
return acc
|
||||||
}
|
}
|
||||||
|
|
||||||
const main = pipe(expand, defrag, checksum)
|
const part1 = pipe(expand, enfrag, checksum)
|
||||||
|
const part3 = pipe(expand3, defrag2, checksum2)
|
||||||
|
|
||||||
|
//const tests = [
|
||||||
|
// ['1313165', 169],
|
||||||
|
// ['12345', 132],
|
||||||
|
// ['54321', 31],
|
||||||
|
// ['2333133121414131402', 2858],
|
||||||
|
// ['1010101010101010101010', 385],
|
||||||
|
// ['111111111111111111111', 290],
|
||||||
|
// ['10101010101010101010101', 506],
|
||||||
|
// ['90909', 513]
|
||||||
|
//]
|
||||||
|
//
|
||||||
|
//tests.forEach(([input, expected], i) => {
|
||||||
|
// //console.log(`input length is ${input.length}`)
|
||||||
|
// const result = part3(input)
|
||||||
|
// console.log(i, result === expected, result)
|
||||||
|
//})
|
||||||
|
|
||||||
readFile(resolve('./input'), { encoding: 'utf8' })
|
readFile(resolve('./input'), { encoding: 'utf8' })
|
||||||
.then(main)
|
.then(part3)
|
||||||
.then(console.log)
|
.then(console.log)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue