mirror of
https://github.com/mx42/adventofcode.git
synced 2026-01-14 13:59:51 +01:00
WIP AOC 2022 & 2023
This commit is contained in:
5
AOC2023/.gitignore
vendored
Normal file
5
AOC2023/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.stack-work/
|
||||
.idea
|
||||
out/
|
||||
*.iml
|
||||
*~
|
||||
11
AOC2023/CHANGELOG.md
Normal file
11
AOC2023/CHANGELOG.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Changelog for `AOC2023`
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to the
|
||||
[Haskell Package Versioning Policy](https://pvp.haskell.org/).
|
||||
|
||||
## Unreleased
|
||||
|
||||
## 0.1.0.0 - YYYY-MM-DD
|
||||
30
AOC2023/LICENSE
Normal file
30
AOC2023/LICENSE
Normal file
@@ -0,0 +1,30 @@
|
||||
Copyright Author name here (c) 2023
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* Neither the name of Author name here nor the names of other
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
1
AOC2023/README.md
Normal file
1
AOC2023/README.md
Normal file
@@ -0,0 +1 @@
|
||||
# AOC2023
|
||||
2
AOC2023/Setup.hs
Normal file
2
AOC2023/Setup.hs
Normal file
@@ -0,0 +1,2 @@
|
||||
import Distribution.Simple
|
||||
main = defaultMain
|
||||
54
AOC2023/app/Main.hs
Normal file
54
AOC2023/app/Main.hs
Normal file
@@ -0,0 +1,54 @@
|
||||
module Main (main) where
|
||||
|
||||
import System.Environment
|
||||
|
||||
import Day01
|
||||
import Day02
|
||||
import Day03
|
||||
import Day04
|
||||
import Day05
|
||||
import Day06
|
||||
import Day07
|
||||
import Day08
|
||||
import Day09
|
||||
import Day10
|
||||
import Day11
|
||||
import Day12
|
||||
import Day13
|
||||
import Day14
|
||||
import Day15
|
||||
import Day16
|
||||
import Day17
|
||||
import Day18
|
||||
import Day19
|
||||
import Day20
|
||||
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
args <- getArgs
|
||||
dayPicker args
|
||||
|
||||
dayPicker :: [String] -> IO ()
|
||||
dayPicker [] = putStrLn "Usage: script [day]"
|
||||
dayPicker ("01":_) = day01
|
||||
dayPicker ("02":_) = day02
|
||||
dayPicker ("03":_) = day03
|
||||
dayPicker ("04":_) = day04
|
||||
dayPicker ("05":_) = day05
|
||||
dayPicker ("06":_) = day06
|
||||
dayPicker ("07":_) = day07
|
||||
dayPicker ("08":_) = day08
|
||||
dayPicker ("09":_) = day09
|
||||
dayPicker ("10":_) = day10
|
||||
dayPicker ("11":_) = day11
|
||||
dayPicker ("12":_) = day12
|
||||
dayPicker ("13":_) = day13
|
||||
dayPicker ("14":_) = day14
|
||||
dayPicker ("15":_) = day15
|
||||
dayPicker ("16":_) = day16
|
||||
dayPicker ("17":_) = day17
|
||||
dayPicker ("18":_) = day18
|
||||
dayPicker ("19":_) = day19
|
||||
dayPicker ("20":_) = day20
|
||||
dayPicker _ = putStrLn "Unavailable date"
|
||||
62
AOC2023/package.yaml
Normal file
62
AOC2023/package.yaml
Normal file
@@ -0,0 +1,62 @@
|
||||
name: AOC2023
|
||||
version: 0.1.0.0
|
||||
github: "githubuser/AOC2023"
|
||||
license: BSD-3-Clause
|
||||
author: "Author name here"
|
||||
maintainer: "example@example.com"
|
||||
copyright: "2023 Author name here"
|
||||
|
||||
extra-source-files:
|
||||
- README.md
|
||||
- CHANGELOG.md
|
||||
|
||||
# Metadata used when publishing your package
|
||||
# synopsis: Short description of your package
|
||||
# category: Web
|
||||
|
||||
# To avoid duplicated efforts in documentation and dealing with the
|
||||
# complications of embedding Haddock markup inside cabal files, it is
|
||||
# common to point users to the README.md file.
|
||||
description: Please see the README on GitHub at <https://github.com/githubuser/AOC2023#readme>
|
||||
|
||||
dependencies:
|
||||
- base >= 4.7 && < 5
|
||||
- containers
|
||||
- split
|
||||
- parsec
|
||||
|
||||
ghc-options:
|
||||
- -Wall
|
||||
- -Wcompat
|
||||
- -Widentities
|
||||
- -Wincomplete-record-updates
|
||||
- -Wincomplete-uni-patterns
|
||||
- -Wmissing-export-lists
|
||||
- -Wmissing-home-modules
|
||||
- -Wpartial-fields
|
||||
- -Wredundant-constraints
|
||||
|
||||
library:
|
||||
source-dirs: src
|
||||
|
||||
executables:
|
||||
AOC2023-exe:
|
||||
main: Main.hs
|
||||
source-dirs: app
|
||||
ghc-options:
|
||||
- -threaded
|
||||
- -rtsopts
|
||||
- -with-rtsopts=-N
|
||||
dependencies:
|
||||
- AOC2023
|
||||
|
||||
tests:
|
||||
AOC2023-test:
|
||||
main: Spec.hs
|
||||
source-dirs: test
|
||||
ghc-options:
|
||||
- -threaded
|
||||
- -rtsopts
|
||||
- -with-rtsopts=-N
|
||||
dependencies:
|
||||
- AOC2023
|
||||
50
AOC2023/src/Day01.hs
Normal file
50
AOC2023/src/Day01.hs
Normal file
@@ -0,0 +1,50 @@
|
||||
module Day01 (day01) where
|
||||
|
||||
import Data.Char (digitToInt, isDigit)
|
||||
|
||||
getNumberFromDigits :: [Int] -> Int
|
||||
getNumberFromDigits nums = head nums * 10 + last nums
|
||||
|
||||
extractDataP1 :: String -> Int
|
||||
extractDataP1 input = getNumberFromDigits $ map digitToInt (filter isDigit input)
|
||||
|
||||
extractDataP2 :: String -> Int
|
||||
extractDataP2 input = getFirst input * 10 + getSecond (reverse input)
|
||||
where
|
||||
getFirst ('o':'n':'e':_) = 1
|
||||
getFirst ('t':'w':'o':_) = 2
|
||||
getFirst ('t':'h':'r':'e':'e':_) = 3
|
||||
getFirst ('f':'o':'u':'r':_) = 4
|
||||
getFirst ('f':'i':'v':'e':_) = 5
|
||||
getFirst ('s':'i':'x':_) = 6
|
||||
getFirst ('s':'e':'v':'e':'n':_) = 7
|
||||
getFirst ('e':'i':'g':'h':'t':_) = 8
|
||||
getFirst ('n':'i':'n':'e':_) = 9
|
||||
getFirst (c:t)
|
||||
| isDigit c = digitToInt c
|
||||
| otherwise = getFirst t
|
||||
getFirst [] = 0
|
||||
getSecond ('e':'n':'o':_) = 1
|
||||
getSecond ('o':'w':'t':_) = 2
|
||||
getSecond ('e':'e':'r':'h':'t':_) = 3
|
||||
getSecond ('r':'u':'o':'f':_) = 4
|
||||
getSecond ('e':'v':'i':'f':_) = 5
|
||||
getSecond ('x':'i':'s':_) = 6
|
||||
getSecond ('n':'e':'v':'e':'s':_) = 7
|
||||
getSecond ('t':'h':'g':'i':'e':_) = 8
|
||||
getSecond ('e':'n':'i':'n':_) = 9
|
||||
getSecond (c:t)
|
||||
| isDigit c = digitToInt c
|
||||
| otherwise = getSecond t
|
||||
getSecond [] = 0
|
||||
|
||||
day01 :: IO ()
|
||||
day01 = do
|
||||
putStrLn "AOC 2023 day 01"
|
||||
input <- getContents
|
||||
putStrLn "Part1"
|
||||
let resP1 = map extractDataP1 $ lines input
|
||||
print $ sum resP1
|
||||
putStrLn "Part2"
|
||||
let resP2 = map extractDataP2 $ lines input
|
||||
print resP2
|
||||
60
AOC2023/src/Day02.hs
Normal file
60
AOC2023/src/Day02.hs
Normal file
@@ -0,0 +1,60 @@
|
||||
module Day02 (day02) where
|
||||
|
||||
import Data.List as List
|
||||
import Data.List.Split (splitOn)
|
||||
|
||||
import Data.Char (digitToInt, isDigit)
|
||||
|
||||
data Play = Play Int Int Int deriving (Show, Eq)
|
||||
instance Ord Play where
|
||||
compare (Play r1 g1 b1) (Play r2 g2 b2) =
|
||||
let cr = compare r1 r2
|
||||
cg = compare g1 g2
|
||||
cb = compare b1 b2
|
||||
in case (cr, cg, cb) of
|
||||
(GT, _, _) -> GT
|
||||
(_, GT, _) -> GT
|
||||
(_, _, GT) -> GT
|
||||
_ -> LT
|
||||
|
||||
|
||||
data Game = Game { gameNb :: Int, plays :: [Play] } deriving Show
|
||||
|
||||
parsePlay :: String -> Play
|
||||
parsePlay input = foldl parseItem (Play 0 0 0) parts
|
||||
where parts = map ((\e -> (head e, e !! 1)) . splitOn " ") (", " `splitOn` input)
|
||||
parseItem (Play r g b) (n, "red") = Play (r + read n) g b
|
||||
parseItem (Play r g b) (n, "green") = Play r (g + read n) b
|
||||
parseItem (Play r g b) (n, "blue") = Play r g (b + read n)
|
||||
parseItem p _ = p
|
||||
|
||||
getGameNb :: String -> Int
|
||||
getGameNb input = read $ ps !! 1
|
||||
where ps = " " `splitOn` input
|
||||
|
||||
parseLine :: String -> Game
|
||||
parseLine input = Game gameNb plays
|
||||
where parts = ": " `splitOn` input
|
||||
gameNb = getGameNb $ head parts
|
||||
plays = map parsePlay $ "; " `splitOn` (parts !! 1)
|
||||
|
||||
runP1 :: Play -> Game -> Bool
|
||||
runP1 limit (Game _ ps) = all (<= limit) ps
|
||||
|
||||
runP2 :: Game -> Int
|
||||
runP2 (Game _ ps) = rs * gs * bs
|
||||
where acc = foldl accumulate (Play 0 0 0) ps
|
||||
accumulate (Play r1 g1 b1) (Play r2 g2 b2) = Play (max r1 r2) (max g1 g2) (max b1 b2)
|
||||
(Play rs gs bs) = acc
|
||||
|
||||
day02 :: IO ()
|
||||
day02 = do
|
||||
putStrLn "AOC 2023 day 02"
|
||||
input <- getContents
|
||||
let parsed = map parseLine (lines input)
|
||||
putStrLn "Part1"
|
||||
let resP1 = filter (runP1 (Play 12 13 14)) parsed
|
||||
print $ sum $ map gameNb resP1
|
||||
putStrLn "Part2"
|
||||
let resP2 = sum $ map runP2 parsed
|
||||
print resP2
|
||||
51
AOC2023/src/Day03.hs
Normal file
51
AOC2023/src/Day03.hs
Normal file
@@ -0,0 +1,51 @@
|
||||
module Day03 (day03) where
|
||||
|
||||
import Data.Char (isDigit, digitToInt)
|
||||
|
||||
import qualified Data.Map as Map
|
||||
|
||||
data Pos = Pos Int Int deriving (Show, Ord, Eq)
|
||||
|
||||
data Symbol = Symbol { symbolChar :: Char, symbolPos :: Pos } deriving (Show, Eq)
|
||||
|
||||
data Part = Part { pos :: Pos, partNb :: Int, partSymbols :: [Symbol] } deriving (Show)
|
||||
|
||||
isNeighbor :: Pos -> Pos -> Bool
|
||||
isNeighbor (Pos x1 y1) (Pos x2 y2) = (abs (x2 - x1) <= 1) && (abs (y2 - y1) <= 1)
|
||||
|
||||
getNeighborSymbols :: [Symbol] -> Pos -> [Symbol]
|
||||
getNeighborSymbols symbols p = filter (\(Symbol _ ps) -> isNeighbor p ps) symbols
|
||||
|
||||
getAccNumbers :: [Symbol] -> [Part] -> (Pos, Int) -> [Part]
|
||||
getAccNumbers allSymbols [] (curPos, curNb) = [Part curPos curNb neighborSymbols]
|
||||
where neighborSymbols = getNeighborSymbols allSymbols curPos
|
||||
getAccNumbers allSymbols (curPart@(Part (Pos accX accY) accInt symbols):t) (curPos@(Pos curX curY), curInt)
|
||||
| accX == curX && accY == curY - 1 = Part curPos (accInt * 10 + curInt) (neighborSymbols ++ symbols) : t
|
||||
| otherwise = Part curPos curInt neighborSymbols : curPart : t
|
||||
where neighborSymbols = getNeighborSymbols allSymbols curPos
|
||||
|
||||
getParts :: Map.Map Pos Int -> [Symbol] -> [Part]
|
||||
getParts numbers symbols = foldl accNumber [] (Map.toList numbers)
|
||||
where accNumber = getAccNumbers symbols
|
||||
|
||||
|
||||
parseInput :: String -> ([Part], [Symbol])
|
||||
parseInput input = (parts, symbols)
|
||||
where chars = [ (Pos x y, c) | (x, row) <- zip [0..] (lines input), (y, c) <- zip [0..] row, c /= '.' ]
|
||||
numbers = Map.fromList $ map (\(k, v) -> (k, digitToInt v)) $ filter (\(_, v) -> isDigit v) chars :: Map.Map Pos Int
|
||||
symbols = map (\(k, v) -> Symbol v k) $ filter (\(_, v) -> not $ isDigit v) chars :: [Symbol]
|
||||
parts = getParts numbers symbols
|
||||
|
||||
|
||||
day03 :: IO ()
|
||||
day03 = do
|
||||
putStrLn "AOC 2023 day 03"
|
||||
input <- getContents
|
||||
let (parts, symbols) = parseInput input
|
||||
putStrLn "Part1"
|
||||
let part1 = sum $ map partNb $ filter (not . null . partSymbols) parts
|
||||
print part1
|
||||
putStrLn "Part2"
|
||||
let allStars = filter ((== '*') . symbolChar) symbols
|
||||
let part2 = sum $ map (\ps -> head ps * ps !! 1) $ filter ((== 2) . length) $ map (\s -> map partNb $ filter (elem s . partSymbols) parts) allStars
|
||||
print part2
|
||||
38
AOC2023/src/Day04.hs
Normal file
38
AOC2023/src/Day04.hs
Normal file
@@ -0,0 +1,38 @@
|
||||
{-# LANGUAGE TupleSections #-}
|
||||
|
||||
module Day04 (day04) where
|
||||
|
||||
import Data.List (intersect)
|
||||
import Data.List.Split (splitOn)
|
||||
import qualified Data.Map as Map
|
||||
|
||||
parseLine :: String -> Int
|
||||
parseLine input = length matchingNumbers
|
||||
where (leftSide: part3: _) = splitOn " | " input
|
||||
(_: part2: _) = splitOn ": " leftSide
|
||||
winningNumbers = filter (not . null) $ splitOn " " part2
|
||||
cardNumbers = filter (not . null) $ splitOn " " part3
|
||||
matchingNumbers = winningNumbers `intersect` cardNumbers
|
||||
|
||||
computeCardScore :: Int -> Int
|
||||
computeCardScore 0 = 0
|
||||
computeCardScore nbMatching = 2 ^ nbMatching - 1
|
||||
|
||||
winCards :: ([Int], [(Int, Int)]) -> Int -> ([Int], [(Int, Int)])
|
||||
winCards (cardsQty, []) _ = (cardsQty, [])
|
||||
winCards (cardsQty, (nb, matching):t) _ = (nb:cardsQty, updatedNext)
|
||||
where updatedNext = if matching == 0 then t else (map (\(qty, m) -> (qty + nb, m)) $ take matching t) ++ drop matching t
|
||||
|
||||
|
||||
day04 :: IO ()
|
||||
day04 = do
|
||||
putStrLn "AOC 2023 day 04"
|
||||
input <- getContents
|
||||
let cards = map parseLine $ lines input
|
||||
let resP1 = sum $ map computeCardScore cards
|
||||
putStrLn "Part1"
|
||||
print resP1
|
||||
let cardsWithQty = map (1,) cards
|
||||
putStrLn "Part2"
|
||||
let resP2 = sum $ fst $ foldl winCards ([], cardsWithQty) cards
|
||||
print resP2
|
||||
68
AOC2023/src/Day05.hs
Normal file
68
AOC2023/src/Day05.hs
Normal file
@@ -0,0 +1,68 @@
|
||||
module Day05 (day05) where
|
||||
import Debug.Trace (trace)
|
||||
|
||||
import Data.List.Split (splitOn, chunksOf)
|
||||
|
||||
type Mapping = [(Int, Int, Int)]
|
||||
type Mappings = [Mapping]
|
||||
|
||||
browseMappings :: Mappings -> Int -> Int
|
||||
browseMappings [] i = i
|
||||
browseMappings ([]:t) i = browseMappings t i
|
||||
browseMappings (((to, from, len):t):tt) i
|
||||
| i >= from, i <= from + len = browseMappings tt $ i - from + to
|
||||
| otherwise = browseMappings (t:tt) i
|
||||
|
||||
revBrowseMappings :: Mappings -> Int -> Int
|
||||
revBrowseMappings [] i = i
|
||||
revBrowseMappings ([]:t) i = browseMappings t i
|
||||
revBrowseMappings (((from, to, len):t):tt) i
|
||||
| i >= from, i <= from + len = browseMappings tt $ i - from + to
|
||||
| otherwise = browseMappings (t:tt) i
|
||||
|
||||
parseMapping :: String -> Mapping
|
||||
parseMapping input = numbers
|
||||
where
|
||||
input_ = tail $ lines input
|
||||
numbers = map ((\nbs -> (read $ head nbs, read $ nbs !! 1, read $ nbs !! 2)) . splitOn " ") input_
|
||||
|
||||
parseSeedId :: String -> [Int]
|
||||
parseSeedId input = map read $ splitOn " " $ splitOn ": " input !! 1
|
||||
|
||||
parseInput :: String -> ([Int], Mappings)
|
||||
parseInput input = (seedsId_, mappings)
|
||||
where
|
||||
seedsId_ = parseSeedId $ head split
|
||||
mappings = map parseMapping $ tail split
|
||||
split = splitOn "\n\n" input
|
||||
|
||||
switchSeedIdToRanges :: [Int] -> [(Int, Int)]
|
||||
switchSeedIdToRanges input = map (\c -> (head c, head c + last c)) chunks
|
||||
where chunks = chunksOf 2 input
|
||||
|
||||
isInRanges :: [(Int, Int)] -> Int -> Bool
|
||||
isInRanges [] _ = False
|
||||
isInRanges ((a, b):t) v
|
||||
| v >= a && v <= b = True
|
||||
| otherwise = isInRanges t v
|
||||
|
||||
reverseSearchMapping :: Mappings -> [(Int, Int)] -> Int -> Int
|
||||
reverseSearchMapping mappings seedRanges start
|
||||
| isInRanges seedRanges endValue = start
|
||||
| otherwise = reverseSearchMapping mappings seedRanges (start + 1)
|
||||
where endValue = revBrowseMappings mappings start
|
||||
|
||||
day05 :: IO ()
|
||||
day05 = do
|
||||
putStrLn "AOC 2023 day 05"
|
||||
input <- getContents
|
||||
let (seeds, mappings) = parseInput input
|
||||
putStrLn "Part1"
|
||||
let resP1 = minimum $ map (browseMappings mappings) seeds
|
||||
print resP1
|
||||
putStrLn "Part2"
|
||||
putStrLn "Not working..."
|
||||
print $ mappings
|
||||
print $ reverse mappings
|
||||
let resP2 = reverseSearchMapping (reverse mappings) (switchSeedIdToRanges seeds) 0
|
||||
print resP2
|
||||
34
AOC2023/src/Day06.hs
Normal file
34
AOC2023/src/Day06.hs
Normal file
@@ -0,0 +1,34 @@
|
||||
module Day06 (day06) where
|
||||
|
||||
import Data.List.Split (splitOn)
|
||||
|
||||
parseInput :: [String] -> [(Int, Int)]
|
||||
parseInput input = zip (head cleaned) (cleaned !! 1)
|
||||
where input_ = map (last . splitOn ":") input :: [String]
|
||||
cleanPart i = map read $ filter (/= "") $ splitOn " " i :: [Int]
|
||||
cleaned = map cleanPart input_ :: [[Int]]
|
||||
|
||||
parseInputP2 :: [String] -> (Int, Int)
|
||||
parseInputP2 input = (head cleaned, cleaned !! 1)
|
||||
where input_ = map (last . splitOn ":") input :: [String]
|
||||
cleanPart i = read $ filter (/= ' ') i :: Int
|
||||
cleaned = map cleanPart input_ :: [Int]
|
||||
|
||||
runDistances :: Int -> [(Int, Int)]
|
||||
runDistances totalTime = forChargeTime totalTime
|
||||
where forChargeTime 0 = [(0, 0)]
|
||||
forChargeTime n = (n, (totalTime - n) * n) : forChargeTime (n - 1)
|
||||
|
||||
day06 :: IO ()
|
||||
day06 = do
|
||||
putStrLn "AOC 2023 day 06"
|
||||
input <- getContents
|
||||
let inputP1 = parseInput $ lines input
|
||||
let winningRuns = map (\i -> filter (\(_, d) -> d > snd i) $ runDistances $ fst i) inputP1
|
||||
putStrLn "Part1"
|
||||
let resP1 = product $ map length winningRuns
|
||||
print resP1
|
||||
putStrLn "Part2"
|
||||
let inputP2 = parseInputP2 $ lines input
|
||||
let resP2 = length $ filter (\(_, d) -> d > snd inputP2) $ runDistances $ fst inputP2
|
||||
print resP2
|
||||
102
AOC2023/src/Day07.hs
Normal file
102
AOC2023/src/Day07.hs
Normal file
@@ -0,0 +1,102 @@
|
||||
module Day07 (day07) where
|
||||
|
||||
import Data.List (sort, sortBy, group)
|
||||
import Data.List.Split (splitOn)
|
||||
|
||||
|
||||
data HandScore = HandScore { typeValue :: Int, highCard1 :: Int, highCard2 :: Int, highCard3 :: Int, highCard4 :: Int, highCard5 :: Int } deriving (Show, Eq, Ord)
|
||||
|
||||
type Hand = [Int]
|
||||
type Bid = Int
|
||||
|
||||
-- HandScore typeValue highCard1 highCard2
|
||||
-- 5 of a kind 10 card value 0
|
||||
-- 4 of a kind 9 card value remaining
|
||||
-- full house 8 3 card value 2 card value
|
||||
-- 3 of a kind 7 3 card value remaining best
|
||||
-- 2 pairs 6 2 card value1 2 card value2
|
||||
-- 1 pair 5 2 card value remaining best
|
||||
-- high card 1 best value 2nd best
|
||||
--getHandScore :: Hand -> HandScore
|
||||
--getHandScore cards = score
|
||||
-- where grouped = group cards
|
||||
|
||||
compareGroupOfCards :: [Int] -> [Int] -> Ordering
|
||||
compareGroupOfCards x y
|
||||
| lengths == EQ = vals
|
||||
| otherwise = lengths
|
||||
where lengths = compare (length y) (length x)
|
||||
vals = compare (head y) (head x)
|
||||
|
||||
|
||||
getHandScore :: Hand -> HandScore
|
||||
getHandScore cards
|
||||
| length grouped == 1 = HandScore 10 (head cards) (cards !! 1) (cards !! 2) (cards !! 3) (cards !! 4)
|
||||
| length grouped == 2 && length (head grouped) == 4 = HandScore 9 (head cards) (cards !! 1) (cards !! 2) (cards !! 3) (cards !! 4)
|
||||
| length grouped == 2 && length (head grouped) == 3 = HandScore 8 (head cards) (cards !! 1) (cards !! 2) (cards !! 3) (cards !! 4)
|
||||
| length grouped == 3 && length (head grouped) == 3 = HandScore 7 (head cards) (cards !! 1) (cards !! 2) (cards !! 3) (cards !! 4)
|
||||
| length grouped == 3 && length (head grouped) == 2 = HandScore 6 (head cards) (cards !! 1) (cards !! 2) (cards !! 3) (cards !! 4)
|
||||
| length grouped == 4 = HandScore 5 (head cards) (cards !! 1) (cards !! 2) (cards !! 3) (cards !! 4)
|
||||
| otherwise = HandScore 1 (head cards) (cards !! 1) (cards !! 2) (cards !! 3) (cards !! 4)
|
||||
where grouped = sortBy compareGroupOfCards $ group $ sort cards
|
||||
|
||||
getHandScoreP2 :: Hand -> HandScore
|
||||
getHandScoreP2 cards
|
||||
| length newGrouped == 1 = HandScore 10 (head cards) (cards !! 1) (cards !! 2) (cards !! 3) (cards !! 4)
|
||||
| length newGrouped == 2 && length (head newGrouped) == 4 = HandScore 9 (head cards) (cards !! 1) (cards !! 2) (cards !! 3) (cards !! 4)
|
||||
| length newGrouped == 2 && length (head newGrouped) == 3 = HandScore 8 (head cards) (cards !! 1) (cards !! 2) (cards !! 3) (cards !! 4)
|
||||
| length newGrouped == 3 && length (head newGrouped) == 3 = HandScore 7 (head cards) (cards !! 1) (cards !! 2) (cards !! 3) (cards !! 4)
|
||||
| length newGrouped == 3 && length (head newGrouped) == 2 = HandScore 6 (head cards) (cards !! 1) (cards !! 2) (cards !! 3) (cards !! 4)
|
||||
| length newGrouped == 4 = HandScore 5 (head cards) (cards !! 1) (cards !! 2) (cards !! 3) (cards !! 4)
|
||||
| otherwise = HandScore 1 (head cards) (cards !! 1) (cards !! 2) (cards !! 3) (cards !! 4)
|
||||
where grouped = sortBy compareGroupOfCards $ group $ sort cards
|
||||
groupOf1 = filter (\gc -> head gc == 1) grouped
|
||||
jokers = if (length groupOf1) > 0 then head groupOf1 else []
|
||||
groupDiff1 = filter (\gc -> head gc /= 1) grouped
|
||||
newGrouped = (head groupDiff1 ++ jokers) : (if length groupDiff1 > 0 then tail groupDiff1 else [])
|
||||
|
||||
charToCard :: Char -> Int
|
||||
charToCard '2' = 2
|
||||
charToCard '3' = 3
|
||||
charToCard '4' = 4
|
||||
charToCard '5' = 5
|
||||
charToCard '6' = 6
|
||||
charToCard '7' = 7
|
||||
charToCard '8' = 8
|
||||
charToCard '9' = 9
|
||||
charToCard 'T' = 10
|
||||
charToCard 'J' = 11
|
||||
charToCard 'Q' = 12
|
||||
charToCard 'K' = 13
|
||||
charToCard 'A' = 14
|
||||
charToCard _ = 0
|
||||
|
||||
parseLine :: String -> (String, Hand, Bid, HandScore)
|
||||
parseLine input = (head input', hand, bid, getHandScore hand)
|
||||
where input' = splitOn " " input :: [String]
|
||||
hand = map charToCard (head input') :: [Int]
|
||||
bid = read $ last input' :: Bid
|
||||
|
||||
mapForP2 :: (Int, String, Hand, Bid, HandScore) -> (String, Hand, Bid, HandScore)
|
||||
mapForP2 (_, str, h1, bid, _) = (str, h2, bid, s2)
|
||||
where h2 = map (\c -> if c == 11 then 1 else c) h1
|
||||
s2 = getHandScoreP2 h2
|
||||
|
||||
addRank :: [(String, Hand, Bid, HandScore)] -> [(Int, String, Hand, Bid, HandScore)]
|
||||
addRank entries = map (\(rank, (str, hand, bid, score)) -> (rank, str, hand, bid, score)) entriesWithRank
|
||||
where entriesWithRank = zip [1..] sortedEntries
|
||||
sortedEntries = sortBy (\(_, _, _, s1) (_, _, _, s2) -> compare s1 s2) entries
|
||||
|
||||
day07 :: IO ()
|
||||
day07 = do
|
||||
putStrLn "AOC 2023 day 07"
|
||||
input <- getContents
|
||||
let hands = addRank $ map parseLine $ lines input
|
||||
let resP1 = sum $ map (\(rank, _, _, bid, _) -> rank * bid) hands
|
||||
putStrLn "Part1"
|
||||
print resP1
|
||||
let handP2 = addRank $ map mapForP2 hands
|
||||
putStrLn "Part2"
|
||||
mapM_ print handP2
|
||||
let resP2 = sum $ map (\(rank, _, _, bid, _) -> rank * bid) handP2
|
||||
print resP2
|
||||
47
AOC2023/src/Day08.hs
Normal file
47
AOC2023/src/Day08.hs
Normal file
@@ -0,0 +1,47 @@
|
||||
module Day08 (day08) where
|
||||
|
||||
import Debug.Trace (trace)
|
||||
|
||||
import qualified Data.Map.Strict as M
|
||||
|
||||
import Data.List.Split (splitOn)
|
||||
import Data.Maybe (fromJust)
|
||||
|
||||
parseLine :: String -> (String, (String, String))
|
||||
parseLine input = (from, (toleft, toright))
|
||||
where from = take 3 input
|
||||
toleft = take 3 . drop 7 $ input
|
||||
toright = take 3 . drop 12 $ input
|
||||
|
||||
walkP1 :: M.Map String (String, String) -> String -> Int -> String -> Int
|
||||
walkP1 theMap (curDir:nextDir) c curZone
|
||||
| curZone == "ZZZ" = c
|
||||
| curDir == 'L' = walkP1 theMap nextDir (c + 1) toLeft
|
||||
| curDir == 'R' = walkP1 theMap nextDir (c + 1) toRight
|
||||
where Just(toLeft, toRight) = M.lookup curZone theMap
|
||||
|
||||
walkP2 :: M.Map String (String, String) -> String -> Int -> [String] -> Int
|
||||
walkP2 theMap (curDir:nextDir) c curZones
|
||||
| all endWithZ curZones = c
|
||||
| curDir == 'L' = walkP2 theMap nextDir (c + 1) $ map goToLeft curZones
|
||||
| curDir == 'R' = walkP2 theMap nextDir (c + 1) $ map goToRight curZones
|
||||
where endWithZ s = last s == 'Z'
|
||||
goToLeft z = fst $ fromJust $ M.lookup z theMap
|
||||
goToRight z = snd $ fromJust $ M.lookup z theMap
|
||||
|
||||
day08 :: IO ()
|
||||
day08 = do
|
||||
putStrLn "AOC 2023 day 08"
|
||||
input <- getContents
|
||||
let inputParts = splitOn "\n\n" input
|
||||
let moveSequence = cycle $ head inputParts
|
||||
let theMap = M.fromList $ map parseLine $ lines $ last inputParts
|
||||
print $ take 10 moveSequence
|
||||
print theMap
|
||||
putStrLn "Part1"
|
||||
let resP1 = walkP1 theMap moveSequence 0 "AAA"
|
||||
print resP1
|
||||
putStrLn "Part2"
|
||||
let entranceP2 = filter (\s -> last s == 'A') $ M.keys theMap
|
||||
let resP2 = walkP2 theMap moveSequence 0 entranceP2
|
||||
print resP2
|
||||
39
AOC2023/src/Day09.hs
Normal file
39
AOC2023/src/Day09.hs
Normal file
@@ -0,0 +1,39 @@
|
||||
module Day09 (day09) where
|
||||
|
||||
import Data.List.Split (splitOn)
|
||||
|
||||
parseLine :: String -> [Int]
|
||||
parseLine i = map read $ splitOn " " i
|
||||
|
||||
getDifferences :: [Int] -> [Int]
|
||||
getDifferences [] = []
|
||||
getDifferences [_] = []
|
||||
getDifferences (h:t@(th:_)) = (th - h) : getDifferences t
|
||||
|
||||
listIsZeros :: [Int] -> Bool
|
||||
listIsZeros = all (== 0)
|
||||
|
||||
getIterations :: [Int] -> [[Int]]
|
||||
getIterations a = takeWhile (not . listIsZeros) $ iterate getDifferences a
|
||||
|
||||
getNextItem :: [Int] -> Int -> Int
|
||||
getNextItem l incr = last l + incr
|
||||
|
||||
getNextItems :: [[Int]] -> Int
|
||||
getNextItems = foldr getNextItem 0
|
||||
|
||||
getPrevItem :: [Int] -> Int -> Int
|
||||
getPrevItem l incr = head l - incr
|
||||
|
||||
getPrevItems :: [[Int]] -> Int
|
||||
getPrevItems = foldr getPrevItem 0
|
||||
|
||||
day09 :: IO ()
|
||||
day09 = do
|
||||
putStrLn "AOC 2023 day 09"
|
||||
input <- getContents
|
||||
let input' = map parseLine $ lines input
|
||||
putStrLn "Part1"
|
||||
print $ sum $ map (getNextItems . getIterations) input'
|
||||
putStrLn "Part2"
|
||||
print $ sum $ map (getPrevItems . getIterations) input'
|
||||
87
AOC2023/src/Day10.hs
Normal file
87
AOC2023/src/Day10.hs
Normal file
@@ -0,0 +1,87 @@
|
||||
module Day10 (day10) where
|
||||
|
||||
import Debug.Trace (trace)
|
||||
|
||||
|
||||
pos2xy :: Int -> Int -> (Int, Int)
|
||||
pos2xy width pos = (curX, curY)
|
||||
where curX = mod pos width
|
||||
curY = pos `div` width
|
||||
|
||||
xy2pos :: Int -> (Int, Int) -> Int
|
||||
xy2pos width (x, y) = x + width * y
|
||||
|
||||
getNeighbors :: (Int, Int) -> Int -> [Int]
|
||||
getNeighbors (w, h) p = map (xy2pos w) $ filter (\(x', y') -> x' >= 0 && x' < (w - 1) && y' >= 0 && y' < h) candidates
|
||||
where candidates = [(x, y - 1), (x - 1, y), (x + 1, y), (x, y + 1)]
|
||||
p' = pos2xy w p
|
||||
x = fst p'
|
||||
y = snd p'
|
||||
|
||||
getStartPos :: String -> Int
|
||||
getStartPos input = head sPos
|
||||
where charPos = zip input [0..]
|
||||
sPos = map snd $ filter (\(c, _) -> c == 'S') charPos
|
||||
|
||||
computeDiff :: (Int, Int) -> (Int, Int) -> (Int, Int)
|
||||
computeDiff (x1, y1) (x2, y2) = (x2 - x1, y2 - y1)
|
||||
|
||||
opening :: Char -> (Int, Int) -> Bool
|
||||
opening 'S' _ = True
|
||||
opening 'F' (1, 0) = True
|
||||
opening 'F' (0, 1) = True
|
||||
opening 'L' (1, 0) = True
|
||||
opening 'L' (0, -1) = True
|
||||
opening 'J' (-1, 0) = True
|
||||
opening 'J' (0, -1) = True
|
||||
opening '7' (-1, 0) = True
|
||||
opening '7' (0, 1) = True
|
||||
opening '-' (_, 0) = True
|
||||
opening '|' (0, _) = True
|
||||
opening _ _ = False
|
||||
|
||||
walkable :: String -> Int -> Int -> Bool
|
||||
walkable mapData curPos destPos
|
||||
| destChar == '.' = False
|
||||
| otherwise = canLeaveCur && canArriveTo
|
||||
where lined = lines mapData
|
||||
width = 1 + length (head lined)
|
||||
curChar = mapData !! curPos
|
||||
destChar = mapData !! destPos
|
||||
dirFrom = computeDiff (pos2xy width curPos) (pos2xy width destPos)
|
||||
dirTo = computeDiff (pos2xy width destPos) (pos2xy width curPos)
|
||||
canLeaveCur = opening curChar dirFrom
|
||||
canArriveTo = opening destChar dirTo
|
||||
|
||||
getWalkableNeighbors :: String -> Int -> [Int]
|
||||
getWalkableNeighbors mapData pos = filter (walkable mapData pos) $ getNeighbors (mapWidth, mapHeight) pos
|
||||
where lined = lines mapData
|
||||
mapWidth = 1 + length (head lined)
|
||||
mapHeight = length lined
|
||||
|
||||
walkNode :: String -> ([(Int, Int)], [(Int, Int)]) -> ([(Int, Int)], [(Int, Int)])
|
||||
walkNode _ t@([], _) = t
|
||||
walkNode mapData (cur@(pos,distance):t, walked) = walkNode mapData (t ++ filteredWalkableNeighbors, cur:walked)
|
||||
where walkableNeighbors = getWalkableNeighbors mapData pos
|
||||
filteredWalkableNeighbors = map (\p -> (p, distance + 1)) $ filter (\p -> p `notElem` map fst (t ++ walked)) walkableNeighbors
|
||||
|
||||
cleanInput :: [Int] -> [(Int, Char)] -> String
|
||||
cleanInput _ [] = []
|
||||
cleanInput ps ((_, '\n'):t) = '\n':cleanInput ps t
|
||||
cleanInput ps ((p, c):t)
|
||||
| p `elem` ps = c:cleanInput ps t
|
||||
| otherwise = ' ':cleanInput ps t
|
||||
|
||||
day10 :: IO ()
|
||||
day10 = do
|
||||
putStrLn "AOC 2023 day 10"
|
||||
input <- getContents
|
||||
putStrLn "Part1"
|
||||
mapM_ print $ lines input
|
||||
let startPos = getStartPos input
|
||||
let (_, computedLoop) = walkNode input ([(startPos, 0)], [])
|
||||
print $ snd $ head computedLoop
|
||||
putStrLn "Part2"
|
||||
let loopPos = map fst computedLoop
|
||||
let cleaned = cleanInput loopPos (zip [0..] input)
|
||||
mapM_ print $ lines cleaned
|
||||
37
AOC2023/src/Day11.hs
Normal file
37
AOC2023/src/Day11.hs
Normal file
@@ -0,0 +1,37 @@
|
||||
{-# LANGUAGE TupleSections #-}
|
||||
module Day11 (day11) where
|
||||
import Data.List (elemIndices)
|
||||
|
||||
getRowsToExpand :: [String] -> [Int]
|
||||
getRowsToExpand input = filter (\i -> all (== '.') (input !! i)) [0..(length input - 1)]
|
||||
|
||||
getColsToExpand :: [String] -> [Int]
|
||||
getColsToExpand input = filter (all (== '.') . byCol) [0..(length (head input) - 1)]
|
||||
where byCol n = map (!! n) input
|
||||
|
||||
getGalaxiesPos :: [String] -> [(Int, Int)]
|
||||
getGalaxiesPos input = concatMap getGalaxiesAtLine [0..(length input - 1)]
|
||||
where getGalaxiesAtLine n = map (, n) (elemIndices '#' (input !! n))
|
||||
|
||||
getPairs :: [a] -> [(a, a)]
|
||||
getPairs [] = []
|
||||
getPairs (h:t) = map (h,) t ++ getPairs t
|
||||
|
||||
getDistance :: [Int] -> [Int] -> Int -> (Int, Int) -> (Int, Int) -> Int
|
||||
getDistance cols rows factor (x1, y1) (x2, y2) = abs (y2 - y1) + abs (x2 - x1) + ((rowsExpansion + colsExpansion) * factor)
|
||||
where rowsExpansion = length $ filter (\i -> i > minimum [y1, y2] && i < maximum [y1, y2]) rows
|
||||
colsExpansion = length $ filter (\i -> i > minimum [x1, x2] && i < maximum [x1, x2]) cols
|
||||
|
||||
day11 :: IO ()
|
||||
day11 = do
|
||||
putStrLn "AOC 2023 day 11"
|
||||
input <- getContents
|
||||
let input' = lines input
|
||||
let colsToExpand = getColsToExpand input'
|
||||
let rowsToExpand = getRowsToExpand input'
|
||||
let galaxiesPos = getGalaxiesPos input'
|
||||
let pairs = getPairs galaxiesPos
|
||||
putStrLn "Part1"
|
||||
print $ sum $ map (uncurry (getDistance colsToExpand rowsToExpand 1)) pairs
|
||||
putStrLn "Part2"
|
||||
print $ sum $ map (uncurry (getDistance colsToExpand rowsToExpand (1000000 - 1))) pairs
|
||||
43
AOC2023/src/Day12.hs
Normal file
43
AOC2023/src/Day12.hs
Normal file
@@ -0,0 +1,43 @@
|
||||
module Day12 (day12) where
|
||||
|
||||
import Data.List (intercalate)
|
||||
import Data.List.Split (splitOn)
|
||||
|
||||
parseLine :: String -> (String, [Int])
|
||||
parseLine input = (head parts, parsedPart2)
|
||||
where parts = splitOn " " input
|
||||
parsedPart2 = map read (splitOn "," $ parts !! 1)
|
||||
|
||||
computeLine :: String -> [Int]
|
||||
computeLine input = reverse $ snd $ foldl accumulate ('.', []) input
|
||||
where accumulate (_, counts) '.' = ('.', counts)
|
||||
accumulate ('#', h:t) '#' = ('#', h + 1:t)
|
||||
accumulate (_, counts) '#' = ('#', 1:counts)
|
||||
accumulate (_, counts) c = (c, counts)
|
||||
|
||||
bruteforceQmarks :: String -> [String]
|
||||
bruteforceQmarks "" = [""]
|
||||
bruteforceQmarks ('?':t) = [ c:xs | c <- ['.', '#'], xs <- bruteforceQmarks t]
|
||||
bruteforceQmarks (h:t) = [ h:xs | xs <- bruteforceQmarks t]
|
||||
|
||||
getPossibleEntries :: String -> [Int] -> [String]
|
||||
getPossibleEntries input check = filter ((== check) . computeLine) possibilities
|
||||
where possibilities = bruteforceQmarks input
|
||||
|
||||
adaptForP2 :: (String, [Int]) -> (String, [Int])
|
||||
adaptForP2 (str, check) = (repeatedStr, repeatedCheck)
|
||||
where repeatedStr = intercalate "?" $ replicate 5 str
|
||||
repeatedCheck = concat $ replicate 5 check
|
||||
|
||||
day12 :: IO ()
|
||||
day12 = do
|
||||
putStrLn "AOC 2023 day 12"
|
||||
input <- getContents
|
||||
let input' = map parseLine $ lines input
|
||||
putStrLn "Part1"
|
||||
let computedPossibilities = map (\(str, check) -> length (getPossibleEntries str check)) input'
|
||||
print $ sum computedPossibilities
|
||||
putStrLn "Part2"
|
||||
let inputP2 = map adaptForP2 input'
|
||||
let possP2 = map (\(str, check) -> length (getPossibleEntries str check)) inputP2
|
||||
print $ sum possP2
|
||||
9
AOC2023/src/Day13.hs
Normal file
9
AOC2023/src/Day13.hs
Normal file
@@ -0,0 +1,9 @@
|
||||
module Day13 (day13) where
|
||||
|
||||
day13 :: IO ()
|
||||
day13 = do
|
||||
putStrLn "AOC 2023 day 13"
|
||||
input <- getContents
|
||||
putStrLn "Part1"
|
||||
putStrLn "Part2"
|
||||
|
||||
9
AOC2023/src/Day14.hs
Normal file
9
AOC2023/src/Day14.hs
Normal file
@@ -0,0 +1,9 @@
|
||||
module Day14 (day14) where
|
||||
|
||||
day14 :: IO ()
|
||||
day14 = do
|
||||
putStrLn "AOC 2023 day 14"
|
||||
input <- getContents
|
||||
putStrLn "Part1"
|
||||
putStrLn "Part2"
|
||||
|
||||
9
AOC2023/src/Day15.hs
Normal file
9
AOC2023/src/Day15.hs
Normal file
@@ -0,0 +1,9 @@
|
||||
module Day15 (day15) where
|
||||
|
||||
day15 :: IO ()
|
||||
day15 = do
|
||||
putStrLn "AOC 2023 day 15"
|
||||
input <- getContents
|
||||
putStrLn "Part1"
|
||||
putStrLn "Part2"
|
||||
|
||||
9
AOC2023/src/Day16.hs
Normal file
9
AOC2023/src/Day16.hs
Normal file
@@ -0,0 +1,9 @@
|
||||
module Day16 (day16) where
|
||||
|
||||
day16 :: IO ()
|
||||
day16 = do
|
||||
putStrLn "AOC 2023 day 16"
|
||||
input <- getContents
|
||||
putStrLn "Part1"
|
||||
putStrLn "Part2"
|
||||
|
||||
8
AOC2023/src/Day17.hs
Normal file
8
AOC2023/src/Day17.hs
Normal file
@@ -0,0 +1,8 @@
|
||||
module Day17 (day17) where
|
||||
|
||||
day17 :: IO ()
|
||||
day17 = do
|
||||
putStrLn "AOC 2023 day 17"
|
||||
input <- getContents
|
||||
putStrLn "Part1"
|
||||
putStrLn "Part2"
|
||||
8
AOC2023/src/Day18.hs
Normal file
8
AOC2023/src/Day18.hs
Normal file
@@ -0,0 +1,8 @@
|
||||
module Day18 (day18) where
|
||||
|
||||
day18 :: IO ()
|
||||
day18 = do
|
||||
putStrLn "AOC 2023 day 18"
|
||||
input <- getContents
|
||||
putStrLn "Part1"
|
||||
putStrLn "Part2"
|
||||
9
AOC2023/src/Day19.hs
Normal file
9
AOC2023/src/Day19.hs
Normal file
@@ -0,0 +1,9 @@
|
||||
module Day19 (day19) where
|
||||
|
||||
day19 :: IO ()
|
||||
day19 = do
|
||||
putStrLn "AOC 2023 day 19"
|
||||
input <- getContents
|
||||
putStrLn "Part1"
|
||||
putStrLn "Part2"
|
||||
|
||||
9
AOC2023/src/Day20.hs
Normal file
9
AOC2023/src/Day20.hs
Normal file
@@ -0,0 +1,9 @@
|
||||
module Day20 (day20) where
|
||||
|
||||
day20 :: IO ()
|
||||
day20 = do
|
||||
putStrLn "AOC 2023 day 20"
|
||||
input <- getContents
|
||||
putStrLn "Part1"
|
||||
putStrLn "Part2"
|
||||
|
||||
67
AOC2023/stack.yaml
Normal file
67
AOC2023/stack.yaml
Normal file
@@ -0,0 +1,67 @@
|
||||
# This file was automatically generated by 'stack init'
|
||||
#
|
||||
# Some commonly used options have been documented as comments in this file.
|
||||
# For advanced use and comprehensive documentation of the format, please see:
|
||||
# https://docs.haskellstack.org/en/stable/yaml_configuration/
|
||||
|
||||
# Resolver to choose a 'specific' stackage snapshot or a compiler version.
|
||||
# A snapshot resolver dictates the compiler version and the set of packages
|
||||
# to be used for project dependencies. For example:
|
||||
#
|
||||
# resolver: lts-21.13
|
||||
# resolver: nightly-2023-09-24
|
||||
# resolver: ghc-9.6.2
|
||||
#
|
||||
# The location of a snapshot can be provided as a file or url. Stack assumes
|
||||
# a snapshot provided as a file might change, whereas a url resource does not.
|
||||
#
|
||||
# resolver: ./custom-snapshot.yaml
|
||||
# resolver: https://example.com/snapshots/2023-01-01.yaml
|
||||
resolver:
|
||||
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/22.yaml
|
||||
|
||||
# User packages to be built.
|
||||
# Various formats can be used as shown in the example below.
|
||||
#
|
||||
# packages:
|
||||
# - some-directory
|
||||
# - https://example.com/foo/bar/baz-0.0.2.tar.gz
|
||||
# subdirs:
|
||||
# - auto-update
|
||||
# - wai
|
||||
packages:
|
||||
- .
|
||||
# Dependency packages to be pulled from upstream that are not in the resolver.
|
||||
# These entries can reference officially published versions as well as
|
||||
# forks / in-progress versions pinned to a git hash. For example:
|
||||
#
|
||||
# extra-deps:
|
||||
# - acme-missiles-0.3
|
||||
# - git: https://github.com/commercialhaskell/stack.git
|
||||
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
|
||||
#
|
||||
# extra-deps: []
|
||||
|
||||
# Override default flag values for local packages and extra-deps
|
||||
# flags: {}
|
||||
|
||||
# Extra package databases containing global packages
|
||||
# extra-package-dbs: []
|
||||
|
||||
# Control whether we use the GHC we find on the path
|
||||
# system-ghc: true
|
||||
#
|
||||
# Require a specific version of Stack, using version ranges
|
||||
# require-stack-version: -any # Default
|
||||
# require-stack-version: ">=2.13"
|
||||
#
|
||||
# Override the architecture used by Stack, especially useful on Windows
|
||||
# arch: i386
|
||||
# arch: x86_64
|
||||
#
|
||||
# Extra directories used by Stack for building
|
||||
# extra-include-dirs: [/path/to/dir]
|
||||
# extra-lib-dirs: [/path/to/dir]
|
||||
#
|
||||
# Allow a newer minor version of GHC than the snapshot specifies
|
||||
# compiler-check: newer-minor
|
||||
13
AOC2023/stack.yaml.lock
Normal file
13
AOC2023/stack.yaml.lock
Normal file
@@ -0,0 +1,13 @@
|
||||
# This file was autogenerated by Stack.
|
||||
# You should not edit this file by hand.
|
||||
# For more information, please see the documentation at:
|
||||
# https://docs.haskellstack.org/en/stable/lock_files
|
||||
|
||||
packages: []
|
||||
snapshots:
|
||||
- completed:
|
||||
sha256: afd5ba64ab602cabc2d3942d3d7e7dd6311bc626dcb415b901eaf576cb62f0ea
|
||||
size: 640060
|
||||
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/22.yaml
|
||||
original:
|
||||
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/22.yaml
|
||||
2
AOC2023/test/Spec.hs
Normal file
2
AOC2023/test/Spec.hs
Normal file
@@ -0,0 +1,2 @@
|
||||
main :: IO ()
|
||||
main = putStrLn "Test suite not yet implemented"
|
||||
Reference in New Issue
Block a user