@@ -164,3 +164,9 @@ executable day21
|
|||||||
hs-source-dirs: src
|
hs-source-dirs: src
|
||||||
main-is: Day21.hs
|
main-is: Day21.hs
|
||||||
build-depends: containers
|
build-depends: containers
|
||||||
|
|
||||||
|
executable day22
|
||||||
|
import: common
|
||||||
|
hs-source-dirs: src
|
||||||
|
main-is: Day22.hs
|
||||||
|
build-depends: containers
|
||||||
|
38
fetch.sh
Executable file
38
fetch.sh
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SOURCE_DIR=$(realpath "$(dirname "$0")")
|
||||||
|
INPUT_DIR=${INPUT_DIR:="$SOURCE_DIR/inputs"}
|
||||||
|
|
||||||
|
help () {
|
||||||
|
echo "usage: $0 <day1-day25>"
|
||||||
|
echo "example: $0 day15"
|
||||||
|
echo " $0 15"
|
||||||
|
echo " $0 all"
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch () {
|
||||||
|
TMPFILE=$(mktemp)
|
||||||
|
curl "https://adventofcode.com/2024/day/${1}/input" \
|
||||||
|
-s --fail-with-body --cookie "session=$AOC_SESSION" \
|
||||||
|
-o "${TMPFILE}"
|
||||||
|
|
||||||
|
mkdir -p "$INPUT_DIR"
|
||||||
|
mv "$TMPFILE" "$INPUT_DIR/day${1}.in"
|
||||||
|
echo "Fetched Day $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $# != 1 || ! "${1#day}" =~ ^([1-9]|1[0-9]|2[0-5]|all)$ ]]; then
|
||||||
|
help
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${AOC_SESSION}" ]]; then
|
||||||
|
echo "\$AOC_SESSION is not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $1 == "all" ]]; then
|
||||||
|
for x in {1..25}; do fetch "$x"; done
|
||||||
|
else
|
||||||
|
fetch "${1#day}"
|
||||||
|
fi
|
@@ -31,7 +31,7 @@
|
|||||||
let
|
let
|
||||||
name = n: "day${(if n < 10 then "0" else "" ) + toString n}";
|
name = n: "day${(if n < 10 then "0" else "" ) + toString n}";
|
||||||
in
|
in
|
||||||
with pkgs.lib; genAttrs (map name (range 1 21))
|
with pkgs.lib; genAttrs (map name (range 1 22))
|
||||||
(n: {
|
(n: {
|
||||||
type = "app";
|
type = "app";
|
||||||
program = "${self'.packages.aoc2024}/bin/${n}";
|
program = "${self'.packages.aoc2024}/bin/${n}";
|
||||||
|
46
src/Day22.hs
Normal file
46
src/Day22.hs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
module Main where
|
||||||
|
|
||||||
|
import Data.Bits (Bits (xor))
|
||||||
|
import qualified Data.Map as M
|
||||||
|
|
||||||
|
type Bananas = M.Map Int Int
|
||||||
|
|
||||||
|
evolve :: Int -> Int
|
||||||
|
evolve =
|
||||||
|
(`mod` 16777216)
|
||||||
|
. (xor <*> (* 2048))
|
||||||
|
. (`mod` 16777216)
|
||||||
|
. (xor <*> (`div` 32))
|
||||||
|
. (`mod` 16777216)
|
||||||
|
. (xor <*> (* 64))
|
||||||
|
|
||||||
|
part1 :: [Int] -> Int
|
||||||
|
part1 = sum . map ((!! 2000) . iterate evolve)
|
||||||
|
|
||||||
|
hash :: (Int, Int, Int, Int) -> Int
|
||||||
|
hash (a, b, c, d) = a + 19 * (b + 19 * (c + 19 * d))
|
||||||
|
|
||||||
|
bananas :: Bananas -> [Int] -> Bananas
|
||||||
|
bananas f (a : b : c : d : e : xs) =
|
||||||
|
let key = hash (b - a, c - b, d - c, e - d)
|
||||||
|
next = bananas f (b : c : d : e : xs)
|
||||||
|
in case M.lookup key f of
|
||||||
|
Nothing -> M.insert key e next
|
||||||
|
Just _ -> next
|
||||||
|
bananas f _ = f
|
||||||
|
|
||||||
|
part2 :: [Int] -> Int
|
||||||
|
part2 =
|
||||||
|
maximum
|
||||||
|
. M.elems
|
||||||
|
. M.unionsWith (+)
|
||||||
|
. map
|
||||||
|
(bananas M.empty . map (`mod` 10) . take 2001 . iterate evolve)
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main =
|
||||||
|
do
|
||||||
|
buyers <- map read . words <$> readFile "./inputs/day22.in"
|
||||||
|
|
||||||
|
putStr "Part 1: " >> print (part1 buyers)
|
||||||
|
putStr "Part 2: " >> print (part2 buyers)
|
Reference in New Issue
Block a user