IntCodes on odd days as usual. Will we have to use them on Christmas too? 🤔
At first was considering getting the map out of the input itself, but it's hidden well enough so I thought it was easier to give it a try anyway.
So, the approach. Instead of the suggested way of backtracking with the drone, I decided to keep a "frontier" of tiles next to unexplored ones, and expand it at every iteration until the leak is reached (for part one) or the frontier is empty (for part two).
Therefor "frontier" consists in an object mapping coordinates with the "state" of the machine (which has to be copied). The only optimization I made here to my IntCode machine was using a Uint16Array instead of a normal array, but it wasn't really necessary.
To the code (in JavaScript):
// Initial part like usual, only using typed arrays. See my repofunctionmoveRobot(column,row,direction){switch(direction){case1:return[column,row-1];case2:return[column,row+1];case3:return[column-1,row];case4:return[column+1,row];}}functionevolveFrontier(initialMap,initialState,condition){constmap={...initialMap};letfrontier={[Object.keys(map)[0]]:initialState};letcounter=0;while(!(condition(map,frontier))){counter++;constnewFrontier={};for(const[coords,state]ofObject.entries(frontier)){const[column,row]=coords.split(',').map(Number);for(letdirection=1;direction<=4;direction++){const[newColumn,newRow]=moveRobot(column,row,direction);constpositionKey=`${newColumn},${newRow}`;if(positionKeyinmap){continue;}constnewState=state.slice();constdrone=createProgramInstance(newState,direction);const{value}=drone.next();map[positionKey]=value;if(value!==0){newFrontier[positionKey]=newState;}drone.return();// Closes the generator to avoid memory leaks}}frontier=newFrontier;}return[map,frontier,counter];}
The evolveFrontier function takes three arguments:
the initial map (an object mapping coordinates with their type of tile): it's needed to keep track of the explored tiles;
the initial state: a copy of the IntCode program;
a condition callback: so the look knows when to stop.
It return the map at the moment the condition becomes true; the frontier at the same istant; and the number of iterations.
The values tankMap and tankFrontier will be needed for the second part:
constleakCoords=Object.keys(tankMap).find(coords=>tankMap[coords]===2);constleakState=tankFrontier[leakCoords];const[,,fillUpAfter]=evolveFrontier({[leakCoords]:2},leakState,(_,frontier)=>Object.keys(frontier).length===0);// -1 because the last round has always hit a wallconsole.log('Part 2:',fillUpAfter-1);
Find today's text, my input the my complete solution at my repo.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
IntCodes on odd days as usual. Will we have to use them on Christmas too? 🤔
At first was considering getting the map out of the input itself, but it's hidden well enough so I thought it was easier to give it a try anyway.
So, the approach. Instead of the suggested way of backtracking with the drone, I decided to keep a "frontier" of tiles next to unexplored ones, and expand it at every iteration until the leak is reached (for part one) or the frontier is empty (for part two).
Therefor "frontier" consists in an object mapping coordinates with the "state" of the machine (which has to be copied). The only optimization I made here to my IntCode machine was using a
Uint16Array
instead of a normal array, but it wasn't really necessary.To the code (in JavaScript):
The
evolveFrontier
function takes three arguments:The first part is now rather easy:
The values
tankMap
andtankFrontier
will be needed for the second part:Find today's text, my input the my complete solution at my repo.