diff --git a/day 15/day_15_mark.js b/day 15/day_15_mark.js new file mode 100644 index 0000000000000000000000000000000000000000..835a674080bb6b48e8243589ec7415cbd80aaea9 --- /dev/null +++ b/day 15/day_15_mark.js @@ -0,0 +1,220 @@ +range = x => [...Array(x).keys()] + +room = input.split('\n\n')[0].split('\n').map(x => x.split('')) +instructions = input.split('\n\n')[1].split('\n').join('').split('').map(x => '^>v<'.indexOf(x)) + +n = room.length +m = room[0].length + +isValid = x => (x[0] >= 0 && x[0] < n && x[1] >= 0 && x[1] < m) + +getEntry = (x) => isValid(x) ? room[x[0]][x[1]] : undefined +setEntry = (x,y) => isValid(x) ? room[x[0]][x[1]] = y : undefined + +up = [-1,0] +right = [0,1] +down = [1,0] +left = [0,-1] + +directions = [up, right, down, left] + +add = (x,y) => [x[0] + y[0], x[1] + y[1]] + +robot = [-1, -1] +range(n).map(i => range(m).map(j => { + if(room[i][j] == '@'){ + robot = [i,j]; + } +})) + +canMoveInto = (position, direction) => { + entry = getEntry(position) + if(entry == '.'){ + return true; + } + if(entry == '#'){ + return false; + } + if(entry == 'O'){ + newPosition = add(position, direction) + if(canMoveInto(newPosition, direction)){ + setEntry(newPosition, 'O') + return true; + } else { + return false; + } + } + if(entry == '@'){ + console.error('pushing on robot') + return false; + } +} + +step = instruction => { + //console.log(directions, instruction, directions[instruction]) + direction = directions[instruction]; + newRobot = add(robot, direction) + moves = canMoveInto(newRobot, direction) + if(moves){ + setEntry(newRobot, '@') + setEntry(robot, '.') + robot = newRobot + } +} + +print = () => { + console.log(room.map(x => x.join('')).join('\n')) +} + +print() + +instructions.map(instruction => step(instruction)) + +print() + +score = 0 +range(n).map(i => range(m).map(j => { + if(room[i][j] == 'O'){ + score += i * 100 + j + } +})) + +output1 = score + +//// + +range = x => [...Array(x).keys()] + +room = input.split('\n\n')[0].split('\n').map(x => x.split('').map(x => ['##','[]','..','@.']['#O.@'.indexOf(x)]).join('').split('')) +instructions = input.split('\n\n')[1].split('\n').join('').split('').map(x => '^>v<'.indexOf(x)) + +n = room.length +m = room[0].length + +isValid = x => (x[0] >= 0 && x[0] < n && x[1] >= 0 && x[1] < m) + +getEntry = (x) => isValid(x) ? room[x[0]][x[1]] : undefined +setEntry = (x,y) => isValid(x) ? room[x[0]][x[1]] = y : undefined + +up = [-1,0] +right = [0,1] +down = [1,0] +left = [0,-1] + +directions = [up, right, down, left] + +add = (x,y) => [x[0] + y[0], x[1] + y[1]] + +robot = [-1, -1] +boxes = [] +range(n).map(i => range(m).map(j => { + if(room[i][j] == '@'){ + robot = [i,j]; + } + if(room[i][j] == '['){ + boxes.push([i,j]) + } +})) + +positionHasBox = position => { + result = boxes.reduce((boxPositions,box) => boxPositions.concat([box.toString(), add(box, right).toString()]),[]).indexOf(position.toString()) + if(result < 0) + return -1 + else + return Math.floor(result/2) +} + +robotTryMove = directionId => { + direction = directions[directionId] + newPosition = add(robot, direction) + + if(isWall(newPosition)){ + return; + } + + boxId = positionHasBox(newPosition) + if(boxId < 0){ + moveRobot(directionId) + return; + } + + if(boxCanMove(boxId, directionId)){ + moveBox(boxId, directionId) + moveRobot(directionId) + } + +} + +onlyUnique = (v, i, a) => a.indexOf(v) === i + +isWall = position => getEntry(position) == '#' || getEntry(position) === undefined + +boxCanMove = (boxId, directionId) => { + positionLeft = boxes[boxId] + positionRight = add(positionLeft, right) + direction = directions[directionId] + newPositionLeft = add(positionLeft, direction) + newPositionRight = add(positionRight, direction) + + if(isWall(newPositionLeft) || isWall(newPositionRight)){ + return false + } + + newPositionBoxesId = [positionHasBox(newPositionLeft), positionHasBox(newPositionRight)].filter(id => id >= 0 && id != boxId).filter(onlyUnique) + + if(newPositionBoxesId.every(id => boxCanMove(id, directionId))){ + return true + } + + return false; +} + +moveBox = (boxId, directionId) => { + positionLeft = boxes[boxId] + positionRight = add(boxes[boxId], right) + direction = directions[directionId] + newPositionLeft = add(positionLeft, direction) + newPositionRight = add(positionRight, direction) + + newPositionBoxesId = [positionHasBox(newPositionLeft), positionHasBox(newPositionRight)].filter(id => id >= 0 && id != boxId).filter(onlyUnique) + + newPositionBoxesId.map(id => moveBox(id, directionId)) + + boxes[boxId] = add(boxes[boxId], direction) +} + +moveRobot = directionId => { + position = robot + direction = directions[directionId] + robot = add(position, direction) +} + + +print = () => { + isLeftBox = position => boxes.reduce((boxPositions, box) => boxPositions.concat(box.toString()),[]).indexOf(position.toString()) >= 0 + isRightBox = position => boxes.reduce((boxPositions, box) => boxPositions.concat([add(box, right).toString()]),[]).indexOf(position.toString()) >= 0 + map = range(n).map(i => + range(m).map(j => + room[i][j] == '#' + ? '#' + : isLeftBox([i,j]) + ? '[' + : isRightBox([i,j]) + ? ']' + : robot.toString() == [i,j].toString() + ? '@' + : '.' + ).join('') + ).join('\n') +} + +print() + +instructions.map(robotTryMove) + +score = 0 +boxes.map(box => { + score += box[0] * 100 + box[1] +}) + +output2 = score \ No newline at end of file