Annwan
3 weeks ago
commit
e497c34b9b
8 changed files with 193 additions and 0 deletions
-
2.gitignore
-
5CHANGELOG.md
-
29LICENSE
-
41aoc2024.cabal
-
23run/Main.hs
-
36src/Day1.hs
-
40src/Day2.hs
-
17test/Main.hs
@ -0,0 +1,2 @@ |
|||
/dist-newstyle |
|||
/inputs |
@ -0,0 +1,5 @@ |
|||
# Revision history for aoc2024 |
|||
|
|||
## 0.1.0.0 -- YYYY-mm-dd |
|||
|
|||
* First version. Released on an unsuspecting world. |
@ -0,0 +1,29 @@ |
|||
Copyright (c) 2024, Annwan |
|||
|
|||
|
|||
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 the copyright holder nor the names of its |
|||
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 |
|||
HOLDER 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. |
@ -0,0 +1,41 @@ |
|||
cabal-version: 3.4 |
|||
name: aoc2024 |
|||
version: 0.1.0.0 |
|||
synopsis: AOC 2024 solutions |
|||
homepage: https://git.annwan.me/Annwan/aoc2024 |
|||
license: BSD-3-Clause |
|||
license-file: LICENSE |
|||
author: Annwan |
|||
maintainer: annwan@annwan.me |
|||
build-type: Simple |
|||
extra-doc-files: CHANGELOG.md |
|||
common warnings |
|||
ghc-options: -Wall |
|||
|
|||
library |
|||
import: warnings |
|||
exposed-modules: Day1, Day2 |
|||
build-depends: base ^>=4.18.0.0 |
|||
hs-source-dirs: src |
|||
default-language: GHC2021 |
|||
|
|||
test-suite aoc2024-test |
|||
import: warnings |
|||
default-language: GHC2021 |
|||
type: exitcode-stdio-1.0 |
|||
hs-source-dirs: test |
|||
main-is: Main.hs |
|||
build-depends: |
|||
base ^>=4.18.0.0, |
|||
aoc2024, |
|||
hspec, |
|||
hspec-contrib |
|||
|
|||
executable aoc2024-runner |
|||
import: warnings |
|||
default-language: GHC2021 |
|||
hs-source-dirs: run |
|||
main-is: Main.hs |
|||
build-depends: |
|||
base ^>=4.18.0.0, |
|||
aoc2024, |
@ -0,0 +1,23 @@ |
|||
module Main where |
|||
import qualified Day1 as D1 |
|||
import qualified Day2 as D2 |
|||
|
|||
solutions :: [(String -> String, String -> String)] |
|||
solutions = [(D1.part1, D1.part2), |
|||
(D2.part1, D2.part2)] |
|||
|
|||
|
|||
run :: Int -> Int -> IO () |
|||
run day part = do |
|||
input <- readFile ("inputs/" ++ show day) |
|||
let select = if part == 1 then fst else snd |
|||
putStrLn $ select (solutions !! (day - 1)) input |
|||
pure () |
|||
|
|||
|
|||
main :: IO () |
|||
main = do |
|||
day <- getLine |
|||
problem <- getLine |
|||
run (read day :: Int) (read problem :: Int) |
|||
|
@ -0,0 +1,36 @@ |
|||
module Day1 (part1, part2) where |
|||
|
|||
import Data.List (transpose, sort) |
|||
|
|||
part1' :: [[Integer]] -> Integer |
|||
part1' [a, b] = sum |
|||
. map (\(x, y) -> abs (x - y)) |
|||
$ zip (sort a) (sort b) |
|||
part1' _ = error "Unreachable" |
|||
|
|||
part1 :: String -> String |
|||
part1 = show . part1' . prepare |
|||
where |
|||
prepare :: String -> [[Integer]] |
|||
prepare = transpose |
|||
. map (map read . words) |
|||
. lines |
|||
|
|||
part2' :: [[Integer]] -> Integer |
|||
part2' [a, b] = sum |
|||
. zipWith (*) a |
|||
. map (\x -> count x b) |
|||
$ a |
|||
where |
|||
count :: Eq a => a -> [a] -> Integer |
|||
count what (x:xs) = count what xs + if what == x then 1 else 0 |
|||
count _ [] = 0 |
|||
part2' _ = error "Unreachable" |
|||
|
|||
part2 :: String -> String |
|||
part2 = show . part2'. prepare |
|||
where |
|||
prepare :: String -> [[Integer]] |
|||
prepare = transpose |
|||
. map (map read . words) |
|||
. lines |
@ -0,0 +1,40 @@ |
|||
module Day2 (part1, part2) where |
|||
import Data.List (subsequences) |
|||
|
|||
isSafe :: [Integer] -> Bool |
|||
isSafe x = isSafeIntevals x && (isAscending x || isDescending x) |
|||
where |
|||
isSafeIntevals :: [Integer] -> Bool |
|||
isSafeIntevals = all (\(a, b) -> 3 >= abs (a - b)) . pairs |
|||
isAscending :: [Integer] -> Bool |
|||
isAscending = all (\(a, b) -> a < b) . pairs |
|||
isDescending :: [Integer] -> Bool |
|||
isDescending = all (\(a, b) -> a > b) . pairs |
|||
pairs :: [a] -> [(a, a)] |
|||
pairs [_] = [] |
|||
pairs [] = [] |
|||
pairs (x1:x2:xs) = (x1, x2) : pairs (x2:xs) |
|||
|
|||
|
|||
|
|||
part1 :: String -> String |
|||
part1 = show |
|||
. length |
|||
. filter isSafe |
|||
. prepare |
|||
where |
|||
prepare :: String -> [[Integer]] |
|||
prepare = map (map read . words) |
|||
. lines |
|||
|
|||
|
|||
part2 :: String -> String |
|||
part2 = show |
|||
. length |
|||
. filter (\x -> |
|||
isSafe x |
|||
|| any isSafe [y | y <- subsequences x, length y == length x - 1]) |
|||
. prepare |
|||
where |
|||
prepare :: String -> [[Integer]] |
|||
prepare = map (map read . words) . lines |
@ -0,0 +1,17 @@ |
|||
module Main (main) where |
|||
import Test.Hspec |
|||
import Day1 |
|||
import Day2 |
|||
|
|||
main :: IO () |
|||
main = hspec $ do |
|||
describe "Day1" $ do |
|||
it "solves part 1" $ do |
|||
Day1.part1 "3 4\n4 3\n2 5\n1 3\n3 9\n3 3\n" `shouldBe` "11" |
|||
it "solves part 2" $ do |
|||
Day1.part2 "3 4\n4 3\n2 5\n1 3\n3 9\n3 3\n" `shouldBe` "31" |
|||
describe "Day 2" $ do |
|||
it "solves part 1" $ do |
|||
Day2.part1 "7 6 4 2 1\n1 2 7 8 9\n9 7 6 2 1\n1 3 2 4 5\n8 6 4 4 1\n1 3 6 7 9" `shouldBe` "2" |
|||
it "solves part 2" $ do |
|||
Day2.part2 "7 6 4 2 1\n1 2 7 8 9\n9 7 6 2 1\n1 3 2 4 5\n8 6 4 4 1\n1 3 6 7 9" `shouldBe` "4" |
Write
Preview
Loading…
Cancel
Save
Reference in new issue