Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions haskell/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Make dayN to run the day
# Make dayN input=./path/to/input.txt to use custom input
day1:
$(eval input ?= ./src/DayOne/input.txt)
cabal run haskell-exe -- 1 $(input)

.PHONY: day1

day2:
$(eval input ?= ./src/DayTwo/input.txt)
cabal run haskell-exe -- 2 $(input)

.PHONY: day


18 changes: 17 additions & 1 deletion haskell/app/Main.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE LambdaCase #-}
module Main (main) where

import System.Environment (getArgs)
import Text.Read (readMaybe)

import DayOne.Solution qualified
import DayTwo.Solution qualified

main :: IO ()
main = print "someFunc"
main = getArgs >>= \case
dayStr : args | Just day <- readMaybe dayStr -> runDay day args
_ -> error "USAGE: haskell-exe DAY ARGS..."

runDay :: Int -> [String] -> IO ()
runDay day args = case day of
1 -> DayOne.Solution.main args
2 -> DayTwo.Solution.main args
x -> error $ unwords ["Bad day", show x]
13 changes: 8 additions & 5 deletions haskell/src/DayOne/Solution.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module DayOne.Solution (calculateMaxCalories) where
{-# LANGUAGE LambdaCase #-}
module DayOne.Solution (calculateMaxCalories, main) where

-- Problem: https://adventofcode.com/2022/day/1

Expand Down Expand Up @@ -32,7 +33,9 @@ safeIntegerRead = readMaybe
calculateMaxCalories :: CaloriesInput -> Integer
calculateMaxCalories = getMaxCalories . parseInput

-- main :: IO ()
-- main = do
-- inputFileContents <- readFile "input.txt"
-- print $ calculateMaxCalories inputFileContents
main :: [String] -> IO ()
main = \case
[path] -> do
inputFileContents <- readFile path
print $ calculateMaxCalories inputFileContents
_ -> error "Invalid args"
113 changes: 58 additions & 55 deletions haskell/src/DayTwo/Solution.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{-# LANGUAGE LambdaCase #-}
module DayTwo.Solution where

import Data.Maybe (fromMaybe)
import Text.Read
import Data.Bifunctor (first)
import Text.Read (readEither)

-- Problem: https://adventofcode.com/2022/day/2

Expand All @@ -21,56 +22,58 @@ import Text.Read
Draw -> 3pt
-}

data OpponentPlayOptions = A | B | C | NopPlay deriving (Show, Eq, Read)

data PlayOptions = X | Y | Z | Nplay deriving (Show, Eq, Read)

type RoundPlay = (OpponentPlayOptions, PlayOptions)

type RoundPlays = [RoundPlay]

type RawRoundPlays = String

type RoundOutcome = (PlayOptions, Integer)

calculateTotalPoints :: RawRoundPlays -> Integer
calculateTotalPoints rawRoundPlays = sum [sumTuple $ getTotalRoundOutcomePts roundPlay playOption | roundPlay@(_, playOption) <- roundPlays]
where
sumTuple (x, y) = x + y
roundPlays = fromRawToParsedRoundPlays rawRoundPlays
getTotalRoundOutcomePts roundPlay playOption = (parsePlayOptionIntoPoints playOption, parseRoundPlayIntoOutcomePoints roundPlay)

-- CHange name
parseRoundPlayIntoOutcomePoints :: RoundPlay -> Integer
parseRoundPlayIntoOutcomePoints roundPlay = case roundPlay of
(A, Y) -> win
(B, Z) -> win
(C, X) -> win
(NopPlay, _) -> win
(A, X) -> draw
(B, Y) -> draw
(C, Z) -> draw
(_, _) -> lose
where
win = 6
draw = 3
lose = 0

parsePlayOptionIntoPoints :: PlayOptions -> Integer
parsePlayOptionIntoPoints X = 1
parsePlayOptionIntoPoints Y = 2
parsePlayOptionIntoPoints Z = 3
parsePlayOptionIntoPoints _ = 0

fromRawToParsedRoundPlays :: RawRoundPlays -> RoundPlays
fromRawToParsedRoundPlays rawSG = [(safeOpponentPlayOptionsParse [x], safePlayOptionsParse [y]) | [x, _, y] <- lines rawSG]

safeOpponentPlayOptionsParse :: String -> OpponentPlayOptions
safeOpponentPlayOptionsParse = fromMaybe NopPlay . readMaybe

safePlayOptionsParse :: String -> PlayOptions
safePlayOptionsParse = fromMaybe Nplay . readMaybe

-- main :: IO ()
main :: IO ()
main = readFile "./input.txt" >>= print . calculateTotalPoints
data OpponentPlayOption = A | B | C deriving (Show, Eq, Read)

data PlayOption = X | Y | Z deriving (Show, Eq, Read)

data Round = OpponentPlayOption `Vs` PlayOption

data RoundResult = Loss | Draw | Win deriving (Show)

runRound :: Round -> RoundResult
runRound = \case
A `Vs` Y -> Win
B `Vs` Z -> Win
C `Vs` X -> Win
A `Vs` X -> Draw
B `Vs` Y -> Draw
C `Vs` Z -> Draw
_ -> Loss

resultScore :: RoundResult -> Integer
resultScore = \case
Loss -> 0
Draw -> 3
Win -> 6

playScore :: Round -> Integer
playScore (_ `Vs` p) = case p of
X -> 1
Y -> 2
Z -> 3

roundScore :: Round -> Integer
roundScore r = resultScore (runRound r) + playScore r

parseRounds :: String -> Either String [Round]
parseRounds = traverse (uncurry parseRoundNumber) . zip [1..] . lines

parseRoundNumber :: Int -> String -> Either String Round
parseRoundNumber n =
first ((unwords ["Error in round", show n, ": "]) ++) . parseRound

parseRound :: String -> Either String Round
parseRound = \case
[x, ' ', y] ->
Vs
<$> first ("Error parsing OpponentPlayOption: " ++) (readEither [x])
<*> first ("Error parsing PlayOption: " ++) (readEither [y])
invalid -> Left $ unwords ["Invalid round: \"", invalid, " \""]

runRPS :: String -> Either String Integer
runRPS = fmap (sum . fmap roundScore) . parseRounds

main :: [String] -> IO ()
main = \case
[path] -> readFile path >>= pure . runRPS >>= either error print
_ -> error "Invalid args"
Loading