Day1
parent
6ca4b02c67
commit
bbadeee601
|
@ -1,6 +1,9 @@
|
||||||
{
|
{
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
|
"Bifunctor",
|
||||||
|
"bimap",
|
||||||
"Collatz",
|
"Collatz",
|
||||||
|
"Combinators",
|
||||||
"concat",
|
"concat",
|
||||||
"coprime",
|
"coprime",
|
||||||
"elems",
|
"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