주문서는 손님이 담은 순서다. 창고는 랙이 놓인 순서다.
그 둘은 아무 상관이 없다. 그런데 대부분의 피킹 리스트는 주문서 순서 그대로 인쇄된다. 그러면 사람이 1번 통로 갔다가 4번 통로 갔다가 다시 1번 통로로 온다.
주장 대신 잰다
"정렬하면 빨라진다"는 말은 누구나 한다. 이 샘플은 두 경로를 다 계산해서 화면에 같이 띄운다.

as typed 106 steps · walking order 82 steps · saved 24 steps
주문서대로 걸으면 106보, 랙 순서대로 걸으면 82보. 24보 차이가 다섯 줄짜리 주문 하나에서 나온다.
걸음 계산은 일부러 조잡하다.
/// Crude on purpose: moving along an aisle costs one per bay, and changing
/// aisle costs the walk to the end and back. It does not need to be a real
/// floor plan to show that the two sequences are not the same length.
실제 창고 도면이 아니어도 두 순서의 길이가 다르다는 것은 보인다. 그게 이 편이 주장하는 전부고, 그 이상을 주장하면 도면이 필요하다.
정렬은 데이터가 아니다
주문에 "순서" 칸이 있으면 안 된다. 순서는 위치에서 나오는 것이지 들어오는 것이 아니다.
/// The same lines, in the sequence a person actually walks.
List<Line> get _walkOrder => List.of(_lines)
..sort((a, b) {
final byAisle = a.slot.aisle.compareTo(b.slot.aisle);
if (byAisle != 0) return byAisle;
return a.slot.bay.compareTo(b.slot.bay);
});
물건이 다른 랙으로 옮겨지면 다음 피킹부터 순서가 저절로 바뀐다. 저장된 순서였다면 누가 전부 다시 계산해야 하고, 아무도 안 하니까 리스트가 슬슬 틀려진다.
검증이 그 순서를 확인한다.
grep -q "walking order: A1-03-L1 -> A1-14-L2 -> A2-09-L1 -> A4-02-L3 -> A4-12-L2" captures/run.log \
|| { echo " the route changed — check whether it is still a walk"; exit 1; }
그리고 하니스가 직접 정렬을 검사한다.
final sorted = List.of(slots)..sort();
expect(slots, sorted, reason: 'the route must be in walking order');
절약한 걸음이 소스에 없어야 한다
24라는 숫자가 어디서 왔는지가 이 글의 신뢰 전부다. 그래서 소스에 그 숫자가 있으면 검증이 실패한다.
SAVED=$(grep -o "saved [0-9]* steps" captures/run.log | head -1 | awk '{print $2}')
[ "$SAVED" -gt 0 ] || { echo " walking order saved nothing — the claim fails"; exit 1; }
if grep -RIn --exclude-dir=captures -F "$SAVED steps" pick_server/bin pick.mbd >/dev/null 2>&1; then
echo " the saving $SAVED is written literally in the source — it must be measured"
exit 1
fi
walking order saved 24 steps, and that number is nowhere in the source
이 검사는 물어볼 수 있는 기록에서 처음 쓴 형태다. 화면에 나온 수치가 소스에 문자열로 박혀 있으면 그건 계산이 아니라 그림이다.