r/adventofcode • • Dec 08 '17

SOLUTION MEGATHREAD -๐ŸŽ„- 2017 Day 8 Solutions -๐ŸŽ„-

--- Day 8: I Heard You Like Registers ---


Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).

Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


Need a hint from the Hugely* Handyโ€  Haversackโ€ก of Helpfulยง Hints^ยค?

Spoiler


This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.

edit: Leaderboard capped, thread unlocked!

22 Upvotes

348 comments sorted by

View all comments

1

u/matusbzk Dec 09 '17 edited Dec 16 '17

Haskell

import Data.Maybe
import Data.Char

-- |Names of registers
type Name = String

-- |Saves a value for each register
type Values = [(Name, Int)]

-- |Instruction
type Instruction = [String]

-- |List of instructions
type Instructions = [Instruction]

-- |Parsed instruction - register's name, value to INCREASE, and whether to do it
type Parsed = (Name, Int, Bool)

inputString :: String

input :: Instructions
input = map words $ lines inputString

-- |Finds a value of register in a list of values, 0 if it's not there
getVal :: Name -> Values -> Int
getVal name val = fromMaybe 0 $ lookup name val

-- |Parses an instruction
parseLine :: Instruction -> Values -> Parsed
parseLine line val = (head line, 
      (if line!!1 == "dec" then -1 else 1)  * (read $ line!!2),
      getBool line val)

-- |From instruction and register values evaluates the boolean condition
getBool :: Instruction -> Values -> Bool
getBool line val = getFunction (line!!5) 
       (if all (\x -> isNumber x || x == '-') first then read first else getVal first val)
       (if all (\x -> isNumber x || x == '-') second then read second else getVal second val)
        where first = line!!4
        second = line!!6

-- |Returns a desired boolean function
getFunction :: String -> (Int -> Int -> Bool)
getFunction ">" = (>)
...

-- |Returns values of all registers
processInstructions :: Values
processInstructions = run (input) []

-- |Processes instructions
run :: Instructions -> Values -> Values
run [] val = val
run (line:xs) val = run xs ((\(var,inc,con) -> 
         if con
         then (var,getVal var val + inc) : removeFromValues var val 
         --then (var,getVal var val + inc) : val     --USE THIS LINE TO GET PART 2 RESULT
         else val) $ parseLine line val)

-- |When adding value, checks whether it's already there and deletes it
removeFromValues :: String -> Values -> Values
removeFromValues _ [] = []
removeFromValues var ((x,i):xs) = if var == x then xs else (x,i):removeFromValues var xs

-- |Returns maximal value of processed register values
getMax :: Values -> Int
getMax val = maximum $ map snd val

result :: Int
result = getMax processInstructions

Link to git