1 more bugfix in this commit: running a BFS over BFSs was not traversing the paths from shortest to longest, because it was implicitly counting the number of crate pushes and not including moves in between crate pushes. Now things seem a lot more natural.
YR62G4PUZEC2PMXMLTPUKFYTSQ3YTCAXXFGLZOIQTUOM2FABPNFQC table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x-1, y=c.y}, dir='left', moves=moves, prev=cand})
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x-1, y=c.y}, dir='left', moves=moves, prev=cand, path_length=cand.path_length+moves.path_length})
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x+1, y=c.y}, dir='right', moves=moves, prev=cand})
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x+1, y=c.y}, dir='right', moves=moves, prev=cand, path_length=cand.path_length+moves.path_length})
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x, y=c.y-1}, dir='up', moves=moves, prev=cand})
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x, y=c.y-1}, dir='up', moves=moves, prev=cand, path_length=cand.path_length+moves.path_length})
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x, y=c.y+1}, dir='down', moves=moves, prev=cand})
table.insert(cands, {player={x=c.x, y=c.y}, crate={x=c.x, y=c.y+1}, dir='down', moves=moves, prev=cand, path_length=cand.path_length+moves.path_length})
table.insert(cands, {x=x-1, y=y, dir='left', prev=cand})table.insert(cands, {x=x+1, y=y, dir='right', prev=cand})table.insert(cands, {x=x, y=y-1, dir='up', prev=cand})table.insert(cands, {x=x, y=y+1, dir='down', prev=cand})
table.insert(cands, {x=x-1, y=y, dir='left', prev=cand, path_length=p+1})table.insert(cands, {x=x+1, y=y, dir='right', prev=cand, path_length=p+1})table.insert(cands, {x=x, y=y-1, dir='up', prev=cand, path_length=p+1})table.insert(cands, {x=x, y=y+1, dir='down', prev=cand, path_length=p+1})
function shortest_path(cands)Real_print('', #cands)local min, minscore = 1, cands[1].path_lengthfor i=2,#cands dolocal iscore = cands[i].path_lengthReal_print('', i, iscore, '<=>', min,minscore)if iscore < minscore thenmin, minscore = i, iscoreendendreturn minend