135 lines
4.8 KiB
JavaScript
135 lines
4.8 KiB
JavaScript
/*
|
|
If the stone is engraved with the number 0, it is replaced by a stone engraved with the number 1.
|
|
If the stone is engraved with a number that has an even number of digits, it is replaced by two stones. The left half of the digits are engraved on the new left stone, and the right half of the digits are engraved on the new right stone. (The new numbers don't keep extra leading zeroes: 1000 would become stones 10 and 0.)
|
|
If none of the other rules apply, the stone is replaced by a new stone; the old stone's number multiplied by 2024 is engraved on the new stone.
|
|
*/
|
|
|
|
let initial_stones = "17639 47 3858 0 470624 9467423 5 188" //"1 2 4 6921 7 823 2219 31 0 4500 22 111 0 9213 44 1 23 1";
|
|
//let initial_stones = "125 17"
|
|
|
|
const cache = []//new Map()
|
|
|
|
const Bisect = (input => {
|
|
let text = String(input)
|
|
let len = text.length
|
|
let left = text.slice(0, len / 2)
|
|
let right = text.slice(len / 2, len)
|
|
return [parseInt(left), parseInt(right)]
|
|
})
|
|
const Blink = ((stone, numberOfTimes) => {
|
|
//console.log(`----------${numberOfTimes}----------`)
|
|
if (numberOfTimes === 0) return 1
|
|
if (cache[`${stone}.${numberOfTimes}`]) {
|
|
console.log(`Found cached value for ${stone}: ${cache[`${stone}.${numberOfTimes}`]}`)
|
|
return cache[`${stone}.${numberOfTimes}`]
|
|
}
|
|
if (stone === 0) {
|
|
//console.log(`Stone with value 0 turned to 1`)
|
|
cache[`${stone}.${numberOfTimes}`] = Blink(1, numberOfTimes - 1)
|
|
return cache[`${stone}.${numberOfTimes}`]
|
|
}
|
|
if (String(stone).length % 2 === 0) {
|
|
let stones = Bisect(stone)
|
|
let left = stones[0]
|
|
let right = stones[1]
|
|
cache[`${left}.${numberOfTimes}`] = Blink(left, numberOfTimes - 1)
|
|
cache[`${right}.${numberOfTimes}`] = Blink(right, numberOfTimes - 1)
|
|
//console.log(`Found left value: ${left}, right value: ${right}`)
|
|
return cache[`${left}.${numberOfTimes}`], cache[`${right}.${numberOfTimes}`]
|
|
}
|
|
cache[`${stone}.${numberOfTimes}`] = Blink(stone * 2024, numberOfTimes - 1)
|
|
return cache[`${stone}.${numberOfTimes}`]
|
|
})
|
|
function startBlinking(stone, numberOfTimes) {
|
|
if (numberOfTimes === 0) return 1
|
|
|
|
const key = `${stone}:${numberOfTimes}`
|
|
if (key in cache) return cache[key]
|
|
if (typeof stone == 'object') { }
|
|
if (stone === 0) { cache[key] = 1; startBlinking(stone, numberOfTimes - 1) }
|
|
if (String(stone).length % 2 === 0) {
|
|
[left, right] = [...Bisect(stones)]
|
|
cache[key] = [left, right]
|
|
return Blink([left, right], numberOfTimes - 1)
|
|
}
|
|
cache[key] = startBlinking(stone * 2024, numberOfTimes - 1)
|
|
return startBlinking(stone, numberOfTimes)
|
|
}
|
|
|
|
function transform(stone) {
|
|
if (stone === 0) {
|
|
return [1]
|
|
}
|
|
|
|
if (stone.toString().length % 2 === 0) {
|
|
const str = stone.toString()
|
|
const midIndex = Math.ceil(str.length / 2)
|
|
const [left, right] = Bisect(stone.toString())
|
|
//const left = str.slice(0, midIndex)
|
|
//const right = str.slice(midIndex)
|
|
|
|
return [Number(left), Number(right)]
|
|
}
|
|
|
|
return [stone * 2024]
|
|
}
|
|
|
|
function simulation(stone, ticks) {
|
|
const key = `${ticks}-${stone}`
|
|
|
|
if (cache[key]) return cache[key]
|
|
if (ticks === 0) return 1
|
|
|
|
const nextStones = transform(stone)
|
|
console.log(`stone ${stone}, received ${nextStones}`)
|
|
const result = nextStones.reduce(
|
|
(acc, nextStone) => acc + simulation(nextStone, ticks - 1),
|
|
0
|
|
)
|
|
|
|
cache[key] = result
|
|
|
|
return result
|
|
}
|
|
//let num = "125 7 0 91".split(' ').forEach(stone => { num += simulation(stone, 25) })
|
|
let num = 0
|
|
for (stone of "17639 47 3858 0 470624 9467423 5 188".split(' ')) {
|
|
num += simulation(stone, 75)
|
|
}
|
|
console.log(num)
|
|
//console.log(cache)
|
|
//let num = Blink("125 17", 5)
|
|
//console.log(num)
|
|
// function blink(stones) {
|
|
// let new_stones = []
|
|
// stones.split(' ').forEach(element => {
|
|
// let changed = false
|
|
// let new_element = 0
|
|
// if (element == 0) {
|
|
// // switch place with a 1
|
|
// //console.log(`${element} is a 0, turn into 1`)
|
|
// new_element = 1
|
|
// changed = true
|
|
// }
|
|
// if (element.length % 2 === 0) {
|
|
// let right = parseInt(element.slice(element.length / 2, element.length))
|
|
// let left = parseInt(element.slice(0, element.length / 2))
|
|
// new_stones.push(left)
|
|
// new_element = right
|
|
// changed = true
|
|
// }
|
|
// if (!changed) new_element = element * 2024
|
|
// new_stones.push(parseInt(new_element))
|
|
// });
|
|
// return new_stones.join(" ");
|
|
// console.log(`${i + 1}: ${new_stones.join(" ")}`)
|
|
// }
|
|
|
|
//for (let i = 0; i < 75; i++) {
|
|
// console.log(`------------------------`)
|
|
// initial_stones = blink(initial_stones)
|
|
// console.log(`${i + 1}: ${initial_stones.split(' ').length}`)
|
|
//console.log(`${initial_stones}`)
|
|
//}
|
|
|