feat: implement day 3, part 1
The solution I went with is to walk the entire bank of batteries with their joltages and pair them up. At every step I can either form an incomplete candidate (Left x), or a complete candidate (Right (a, b)) if I already have a previous candidate.
This commit is contained in:
parent
3f0d19a5d1
commit
249365968a
2 changed files with 250 additions and 0 deletions
50
app/Day3.hs
Normal file
50
app/Day3.hs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
module Main where
|
||||
|
||||
import Data.Char (digitToInt)
|
||||
import Data.Either (rights)
|
||||
import Debug.Trace
|
||||
import System.Environment (getArgs)
|
||||
|
||||
-- | A candidate is either a left-most number we've just selected, or
|
||||
-- a complete candidate represented as a pair.
|
||||
type Candidate = Either Int (Int, Int)
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
input <- readFile . head =<< getArgs
|
||||
putStrLn $ "Part 1: " ++ show (part1 input)
|
||||
putStrLn $ "Part 2: " ++ show (part2 input)
|
||||
|
||||
-- | Maintain a list of candidates (either partial, or complete) and
|
||||
-- then select the greatest one for each line.
|
||||
--
|
||||
-- Insight: By keeping a list of possible candidates we can always
|
||||
-- backtrack out of an accidental corner (like making a partial
|
||||
-- candidate of the last digit).
|
||||
part1 :: String -> Int
|
||||
part1 = sum . map (maximum . map combine . rights . foldl go [] . map digitToInt) . lines
|
||||
where
|
||||
go :: [Candidate] -> Int -> [Candidate]
|
||||
go [] x = pure $ Left x
|
||||
go (Left a : candidates') x
|
||||
| x > a = Left x : Right (a, x) : candidates'
|
||||
| otherwise = Right (a, x) : candidates'
|
||||
go candidates@(Right (a, b) : candidates') x
|
||||
| x > a = Left x : Right (a, x) : candidates
|
||||
| x > b = Right (a, x) : candidates'
|
||||
| otherwise = candidates
|
||||
|
||||
combine :: (Int, Int) -> Int
|
||||
combine (a, b) = a * 10 + b
|
||||
|
||||
part2 :: String -> Int
|
||||
part2 = error "Not implemented"
|
||||
|
||||
testInput :: String
|
||||
testInput =
|
||||
unlines
|
||||
[ "987654321111111",
|
||||
"811111111111119",
|
||||
"234234234234278",
|
||||
"818181911112111"
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue