The final Advent of Code problem for 2021 only required a one part solution. We are given the positions of sea cucumbers that can move in one of two directions. All single direction moves happen simultaneously. The target position needs to have been previously un-occupied i.e. sea cucumbers cannot move into a spot that is anticipated to become vacant in the current step
In the function below newPos is a lambda that accepts the x,y position of a sea cucumber and returns the potential new position. It also accepts the direction in which the sea cucumber can move. The code first determines all the sea cucumbers that can be moved and then proceeds to reposition them.
def moveSeaCucumbers(dir,newPos): # figure out what can be moved canMove = [ (x,y) for (x,y) in scPositions[dir] \ if newPos(x,y) not in scPositions['>'] \ and newPos(x,y) not in scPositions['v'] ] # move for (x,y) in canMove: scPositions[dir].remove((x,y)) scPositions[dir].add(newPos(x,y)) return len(canMove)
Learnings
While I have used anonymous functions in Java and Node.js, I hadn't encountered the need to use a lambda in Python yet. Quite interestingly, Python supports the declaration of an anonymous function via the lambda keyword, while also supporting the passing of named functions via a function call.
I first invoke the move of sea cucumbers that face east, followed by those that face south. Both calls use different lambdas that reposition either the x or y co-ordinates. These steps are repeated until no more moves are possible.
counter = 0 moves = -1 while moves != 0: moves = moveSeaCucumbers('>', lambda x,y: ((x+1)%w,y) ) moves += moveSeaCucumbers('v', lambda x,y: (x,(y+1)%h) ) counter +=1 print(scPositions) print("count",counter)