Day1
parent
6ca4b02c67
commit
bbadeee601
|
@ -1,6 +1,9 @@
|
|||
{
|
||||
"cSpell.words": [
|
||||
"Bifunctor",
|
||||
"bimap",
|
||||
"Collatz",
|
||||
"Combinators",
|
||||
"concat",
|
||||
"coprime",
|
||||
"elems",
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
-- https://adventofcode.com/2023/day/1
|
||||
|
||||
import Data.Bifunctor (bimap)
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Text.ParserCombinators.ReadP (ReadP, choice, many, readP_to_S,
|
||||
string, (<++))
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
entries <- lines <$> readFile "src/advent_of_code/2023/input1"
|
||||
print "Advent of Code 2022 - Day 4"
|
||||
-- print entries
|
||||
|
||||
print ("Part 1: " <> show (solveP1 entries))
|
||||
print ("Part 2: " <> show (solveP2 entries))
|
||||
|
||||
|
||||
--
|
||||
-- Part 1
|
||||
--
|
||||
|
||||
solveP1 :: [String] -> Int
|
||||
solveP1 = sum . map solveP1Line
|
||||
|
||||
solveP1Line :: String -> Int
|
||||
solveP1Line = sumPairS . bimap head last . doubleString . filter isNumP1 . tokenized tokensP1
|
||||
|
||||
tokensP1 :: ReadP String
|
||||
tokensP1 = parseNumberChars <++ parseChars
|
||||
|
||||
--
|
||||
-- Part 2
|
||||
--
|
||||
|
||||
solveP2 :: [String] -> Int
|
||||
solveP2 = sum . map solveP2Line
|
||||
|
||||
--
|
||||
-- Need to parse from both sides
|
||||
-- "oneight" should return 18, not 11
|
||||
solveP2Line :: String -> Int
|
||||
solveP2Line = sumPairS . bimap a b . doubleString
|
||||
where
|
||||
a = head . condense . fromLeft
|
||||
b = last . condense . fromRight
|
||||
|
||||
condense = map stringToNum . filter isNumP2
|
||||
fromLeft = tokenized tokensP2
|
||||
fromRight = map reverse . reverse . tokenized tokensP2' . reverse
|
||||
|
||||
tokensP2 :: ReadP String
|
||||
tokensP2 = parseNumberWords <++ parseNumberChars <++ parseChars
|
||||
|
||||
tokensP2' :: ReadP String
|
||||
tokensP2' = parseNumberWords' <++ parseNumberChars <++ parseChars
|
||||
|
||||
solveP2LineBad :: String -> Int
|
||||
solveP2LineBad = sumPairS . bimap head last . doubleString . map stringToNum . filter isNumP2 . tokenized tokensP2
|
||||
|
||||
--
|
||||
-- Utility functions
|
||||
--
|
||||
|
||||
-- Doing this because I want to use a bifunctor
|
||||
doubleString :: str -> (str, str)
|
||||
doubleString str = (str, str)
|
||||
|
||||
sumPairS :: (String, String) -> Int
|
||||
sumPairS (x,y) = read (x ++ y)
|
||||
|
||||
stringToNum :: String -> String
|
||||
stringToNum str = fromMaybe str (lookup str $ zip numberWords numberChars)
|
||||
|
||||
--
|
||||
-- Boilerplate equality checks
|
||||
-- Now condensed
|
||||
--
|
||||
|
||||
isNumP1 :: String -> Bool
|
||||
isNumP1 = flip elem numberChars
|
||||
|
||||
isNumP2 :: String -> Bool
|
||||
isNumP2 = flip elem (numberChars ++ numberWords)
|
||||
|
||||
--
|
||||
-- Parsing for question
|
||||
--
|
||||
|
||||
numberWords :: [String]
|
||||
numberWords = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
|
||||
|
||||
numberChars :: [String]
|
||||
numberChars = map show [0..9]
|
||||
|
||||
letterChars :: String
|
||||
letterChars = ['a'..'z']
|
||||
|
||||
parseNumberWords :: ReadP String
|
||||
parseNumberWords = choice $ map string numberWords
|
||||
|
||||
parseNumberWords' :: ReadP String
|
||||
parseNumberWords' = choice $ map (string . reverse) numberWords
|
||||
|
||||
parseNumberChars :: ReadP String
|
||||
parseNumberChars = choice $ map string numberChars
|
||||
|
||||
parseChars :: ReadP String
|
||||
parseChars = choice $ map (\c -> string [c]) letterChars
|
||||
|
||||
tokenized :: ReadP a -> String -> [a]
|
||||
tokenized tokenSet = fst . last . readP_to_S (many tokenSet)
|
||||
|
||||
--
|
||||
-- Examples
|
||||
--
|
||||
|
||||
example1 :: [String]
|
||||
example1 =
|
||||
[ "1abc2"
|
||||
, "pqr3stu8vwx"
|
||||
, "a1b2c3d4e5f"
|
||||
, "treb7uchet"
|
||||
]
|
||||
|
||||
example2 :: [String]
|
||||
example2 =
|
||||
[ "two1nine"
|
||||
, "eightwothree"
|
||||
, "abcone2threexyz"
|
||||
, "xtwone3four"
|
||||
, "4nineeightseven2"
|
||||
, "zoneight234"
|
||||
, "7pqrstsixteen"
|
||||
]
|
Loading…
Reference in New Issue