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