@@ -164,3 +164,9 @@ executable day21
 | 
			
		||||
  hs-source-dirs: src
 | 
			
		||||
  main-is:        Day21.hs
 | 
			
		||||
  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
 | 
			
		||||
            name = n: "day${(if n < 10 then "0" else "" ) + toString n}";
 | 
			
		||||
          in
 | 
			
		||||
          with pkgs.lib; genAttrs (map name (range 1 21))
 | 
			
		||||
          with pkgs.lib; genAttrs (map name (range 1 22))
 | 
			
		||||
            (n: {
 | 
			
		||||
              type = "app";
 | 
			
		||||
              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