2017-12-12 17:28:55 +00:00
|
|
|
import Data.Foldable (toList)
|
|
|
|
import Data.HashMap (Map, member, insert, findWithDefault, empty)
|
|
|
|
import Data.Sequence (Seq, length, update, fromList, foldlWithIndex, mapWithIndex)
|
2017-12-12 17:28:43 +00:00
|
|
|
|
|
|
|
type Bank = Seq Int
|
2017-12-12 17:28:52 +00:00
|
|
|
type HashableBank = [Int]
|
2017-12-12 17:28:55 +00:00
|
|
|
type Config = (Bank, Map HashableBank Int)
|
2017-12-12 17:28:43 +00:00
|
|
|
|
|
|
|
(%) :: Int -> Int -> Int
|
|
|
|
(%) = mod
|
|
|
|
|
2017-12-12 17:28:52 +00:00
|
|
|
(//) :: Int -> Int -> Int
|
|
|
|
(//) = div
|
|
|
|
|
2017-12-12 17:28:43 +00:00
|
|
|
getMaxMem :: Bank -> (Int, Int)
|
|
|
|
getMaxMem bank =
|
|
|
|
foldlWithIndex (\(currIndex, currMax) index value -> if value > currMax then (index, value) else (currIndex, currMax)) (0, 0) bank
|
|
|
|
|
|
|
|
nextBank :: Bank -> Bank
|
|
|
|
nextBank bank =
|
|
|
|
let len = Data.Sequence.length bank
|
|
|
|
(index, value) = getMaxMem bank
|
2017-12-12 17:28:55 +00:00
|
|
|
zeroedBank = update index 0 bank
|
2017-12-12 17:28:52 +00:00
|
|
|
mappedBank = fmap (+ value // len) zeroedBank
|
|
|
|
indicesToUpdate = fmap ((% len) . (+ index)) [1..value % len]
|
2017-12-12 17:28:43 +00:00
|
|
|
in mapWithIndex (\i v -> if i `elem` indicesToUpdate then v + 1 else v) mappedBank
|
|
|
|
|
|
|
|
|
2017-12-12 17:28:47 +00:00
|
|
|
cycles :: Int -> Config -> (Int, Int)
|
2017-12-12 17:28:52 +00:00
|
|
|
cycles prevCount (prevBank, banks) =
|
|
|
|
let count = prevCount + 1
|
|
|
|
bank = nextBank prevBank
|
2017-12-12 17:28:55 +00:00
|
|
|
hashableBank = toList bank
|
2017-12-12 17:28:52 +00:00
|
|
|
in if member hashableBank banks
|
|
|
|
then (count, count - findWithDefault undefined hashableBank banks)
|
|
|
|
else cycles count (bank, insert hashableBank count banks)
|
2017-12-12 17:28:43 +00:00
|
|
|
|
|
|
|
main :: IO ()
|
|
|
|
main = do
|
|
|
|
input <- readFile "6.txt"
|
2017-12-12 17:28:55 +00:00
|
|
|
let bank = fromList $ fmap read $ words input :: Bank
|
|
|
|
print $ cycles 0 (bank, empty)
|