Advent of Code — Day 6
Don’t we all love lanternfish?
I will be straightforward, my solution is anything but refined.
I want to explain how I did it. First I have a function to define a base set of fish:
function getFishZeroState() {
return {
"0" : {"nb": 0, "hatch": false},
"1" : {"nb": 0, "hatch": false},
"2" : {"nb": 0, "hatch": false},
"3" : {"nb": 0, "hatch": false},
"4" : {"nb": 0, "hatch": false},
"5" : {"nb": 0, "hatch": false},
"6" : {"nb": 0, "hatch": false},
"7" : {"nb": 0, "hatch": false},
"8" : {"nb": 0, "hatch": false},
};
}
Could be better? Yes, of course. But I am lazy and I wanted to get it over with without being fancy. I knew the state is not going to change. Ever.
I read the file with the problem input, iterate through it and fill the zero state object as follows:
Input:
3, 4, 3, 1, 2
State:
"0" : {"nb": 0, "hatch": false},
"1" : {"nb": 1, "hatch": true},
"2" : {"nb": 1, "hatch": true},
"3" : {"nb": 2, "hatch": true},
"4" : {"nb": 1, "hatch": true},
"5" : {"nb": 0, "hatch": false},
"6" : {"nb": 0, "hatch": false},
"7" : {"nb": 0, "hatch": false},
"8" : {"nb": 0, "hatch": false},
Code:
Array.from(data.split(','), x => parseInt(x)).forEach( (fish) => {
fishes[fish]["nb"] += 1;
fishes[fish]["hatch"] = true;
});
Hatch is just a flag. I will go through that line ONLY if I have to, saving a bit of time.
And when a day passes… I just shift it like this:
Day 1 passes:
"0" : {"nb": 1, "hatch": true},
"1" : {"nb": 1, "hatch": true},
"2" : {"nb": 2, "hatch": true},
"3" : {"nb": 1, "hatch": true},
"4" : {"nb": 0, "hatch": false},
"5" : {"nb": 0, "hatch": false},
"6" : {"nb": 0, "hatch": false},
"7" : {"nb": 0, "hatch": false},
"8" : {"nb": 0, "hatch": false},
Day 2 passes:
"0" : {"nb": 1, "hatch": true},
"1" : {"nb": 2, "hatch": true},
"2" : {"nb": 1, "hatch": true},
"3" : {"nb": 0, "hatch": false},
"4" : {"nb": 0, "hatch": false},
"5" : {"nb": 0, "hatch": false},
"6" : {"nb": 1, "hatch": true},
"7" : {"nb": 0, "hatch": false},
"8" : {"nb": 1, "hatch": true},
Code:
const days = 80;
for(let i = 1; i <= days; i++){
let newFishes = getFishZeroState();
for(const fish in fishes){
if(fishes[fish]["hatch"]){
if(fish == 0){
newFishes[8]["nb"] += fishes[fish]["nb"];
newFishes[8]["hatch"] = true;
newFishes[6]["nb"] += fishes[fish]["nb"];
newFishes[6]["hatch"] = true;
}
else {
newFishes[fish-1]["nb"] += fishes[fish]["nb"];
newFishes[fish-1]["hatch"] = true;
}
}
}
fishes = newFishes;
}
I just build a new object and replace the old one containing the fish with the new state. Yes, it could’ve been better, I know :D But I didn’t want to complicate it, I wanted to get it done.
And at the end… I just iterate through the fish object and… I sum up the numbers:
let sum = 0;
for(let key in fishes){
sum += fishes[key]["nb"];
}
Talking time
As of the time and days are as follows:
- I did 10 runs for each and average the times to get the final result
80 days — 0.856ms
256 days — 1.191ms
512 days — 2.741ms
1024 days — 4.293ms
65535 days — 70.004ms
1 gogolplex days — still did not compile :( not efficient enough to get there, even 1 trillion is too much as of now