From bd66e14d3d10d863e19fc767f9d1c612d6b5f8ed Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Wed, 6 Dec 2023 00:54:51 +0000 Subject: [PATCH] Add day 1 --- 1.hs | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100755 1.hs diff --git a/1.hs b/1.hs new file mode 100755 index 0000000..1676ab4 --- /dev/null +++ b/1.hs @@ -0,0 +1,68 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i runghc -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [ ])" +import Data.List (find, isInfixOf) +import Data.Maybe (catMaybes) + +{- https://adventofcode.com/2023/day/1 -} + +main = print =<< run 0 + +-- recursively read each line from stdin, concatenating first and last digits and folding the result into a sum +run :: Int -> IO Int +run acc = do + line <- getLine + if null line + then return acc + else do + let x = concatFirstLastDigitsInString line + run $ acc + x + +-- read first and last digit in a string and concatenate the two together +concatFirstLastDigitsInString :: String -> Int +concatFirstLastDigitsInString s = + case catMaybes [findDigitFromLeft "" s, findDigitFromRight "" s] of + [x, y] -> x * 10 + y + [x] -> x * 11 + _ -> 0 + +-- find the first digit in the string, searching from the left hand side +findDigitFromLeft :: String -> String -> Maybe Int +findDigitFromLeft acc "" = findDigit acc +findDigitFromLeft acc (x : xs) = case findDigit acc of + Just v -> Just v + Nothing -> findDigitFromLeft (acc ++ [x]) xs + +-- find the last digit in the string, searching from the right hand side +findDigitFromRight :: String -> String -> Maybe Int +findDigitFromRight acc "" = findDigit acc +findDigitFromRight acc xs = case findDigit acc of + Just v -> Just v + Nothing -> findDigitFromRight (last xs : acc) (init xs) + +-- finds a digit in either textual or numeric form and returns it as an int +findDigit :: String -> Maybe Int +findDigit s = case find (`isInfixOf` s) digitAsText of + Just textual -> lookup textual digitMap + Nothing -> Nothing + where + digitMap = + [ ("eight", 8), + ("seven", 7), + ("three", 3), + ("nine", 9), + ("four", 4), + ("five", 5), + ("two", 2), + ("one", 1), + ("six", 6), + ("1", 1), + ("2", 2), + ("3", 3), + ("4", 4), + ("5", 5), + ("6", 6), + ("7", 7), + ("8", 8), + ("9", 9) + ] + digitAsText = map fst digitMap -- libgit2 1.7.2