Day 09
This commit is contained in:
parent
5191b7bd39
commit
3234596629
|
@ -0,0 +1,103 @@
|
|||
{ pkgs, lib }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
mapDirectionStepsToHorizontalVertical = { direction, steps }: {
|
||||
horizontal = if direction == "L" then steps else
|
||||
if direction == "R" then -steps else 0;
|
||||
vertical = if direction == "D" then steps else
|
||||
if direction == "U" then -steps else 0;
|
||||
};
|
||||
|
||||
scanl = f: x1: list: let
|
||||
x2 = head list;
|
||||
x1' = f x1 x2;
|
||||
in if list == [] then [] else [x1'] ++ (scanl f x1' (tail list));
|
||||
|
||||
foldHeadPosition =
|
||||
{ x ? 0, y ? 0 }:
|
||||
{ horizontal, vertical }: {
|
||||
x = x + horizontal;
|
||||
y = y + vertical;
|
||||
};
|
||||
|
||||
movements = pipe ./input.txt [
|
||||
fileContents
|
||||
(splitString "\n")
|
||||
(map (splitString " "))
|
||||
(map (x: { direction = head x; steps = toInt (elemAt x 1); }))
|
||||
(map mapDirectionStepsToHorizontalVertical)
|
||||
(scanl foldHeadPosition {})
|
||||
];
|
||||
|
||||
abs = x: if x < 0 then -x else x;
|
||||
|
||||
ropePieceLength = headPiece: tailPiece: let
|
||||
deltaX = abs (headPiece.x - tailPiece.x);
|
||||
deltaY = abs (headPiece.y - tailPiece.y);
|
||||
in max deltaX deltaY;
|
||||
|
||||
moveRopePiece = headPiece: tailPiece: {
|
||||
x = if headPiece.x > tailPiece.x then tailPiece.x + 1 else
|
||||
if headPiece.x < tailPiece.x then tailPiece.x - 1 else
|
||||
tailPiece.x;
|
||||
y = if headPiece.y > tailPiece.y then tailPiece.y + 1 else
|
||||
if headPiece.y < tailPiece.y then tailPiece.y - 1 else
|
||||
tailPiece.y;
|
||||
};
|
||||
|
||||
moveRope = headToOverlap: rope: let
|
||||
newHead = moveRopePiece headToOverlap (head rope);
|
||||
moveIfNextPieceMoved = x: y:
|
||||
if ropePieceLength x y > 1
|
||||
then moveRopePiece x y
|
||||
else y;
|
||||
newTail = scanl moveIfNextPieceMoved newHead (tail rope);
|
||||
in [newHead] ++ newTail;
|
||||
|
||||
moveRopeUntilHeadOverlapsAndReportLastPositions = headToOverlap: rope: let
|
||||
newRope = moveRope headToOverlap rope;
|
||||
nextIteration = moveRopeUntilHeadOverlapsAndReportLastPositions headToOverlap newRope;
|
||||
in if head rope == headToOverlap
|
||||
then {
|
||||
inherit rope;
|
||||
tailPositions = [];
|
||||
}
|
||||
else {
|
||||
inherit (nextIteration) rope;
|
||||
tailPositions = [(last newRope)] ++ nextIteration.tailPositions;
|
||||
};
|
||||
|
||||
repeat = item: times: map (const item) (range 1 times);
|
||||
|
||||
f = n: { rope ? (repeat { x = 0; y = 0; } n), tailPositions ? [{ x = 0; y = 0; }] }: newHeadPosition: let
|
||||
newRope = moveRopeUntilHeadOverlapsAndReportLastPositions newHeadPosition rope;
|
||||
in {
|
||||
rope = newRope.rope;
|
||||
tailPositions = tailPositions ++ newRope.tailPositions;
|
||||
};
|
||||
|
||||
answer1 = pipe movements [
|
||||
(foldl (f 2) {})
|
||||
(x: x.tailPositions)
|
||||
unique
|
||||
length
|
||||
toString
|
||||
];
|
||||
|
||||
answer2 = pipe movements [
|
||||
(foldl (f 10) {})
|
||||
(x: x.tailPositions)
|
||||
unique
|
||||
length
|
||||
toString
|
||||
];
|
||||
|
||||
in pkgs.writeText "answers" ''
|
||||
Task1:
|
||||
${answer1}
|
||||
|
||||
Task2:
|
||||
${answer2}
|
||||
''
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue