38 lines
1.2 KiB
Haskell
38 lines
1.2 KiB
Haskell
import Data.Foldable (toList)
|
|
import Data.Maybe
|
|
import Data.HashMap (Map, member, insert, findWithDefault, empty)
|
|
import Data.Sequence (Seq, update, fromList, elemIndexL, mapWithIndex)
|
|
import qualified Data.Sequence as S (length)
|
|
|
|
type Bank = Seq Int
|
|
type Config = (Bank, Map [Int] Int)
|
|
(%) = mod
|
|
(//) = div
|
|
|
|
getMaxMem :: Bank -> (Int, Int)
|
|
getMaxMem bank =
|
|
(fromJust $ elemIndexL (maximum bank) bank, maximum bank)
|
|
|
|
nextBank :: Bank -> Bank
|
|
nextBank bank =
|
|
let len = S.length bank
|
|
(index, value) = getMaxMem bank
|
|
newBank = fmap (+ value // len) $ update index 0 bank
|
|
indices = fmap (% len) [index + 1..index + value % len]
|
|
in mapWithIndex (\i v -> v + fromEnum (i `elem` indices)) newBank
|
|
|
|
|
|
cycles :: Int -> Config -> (Int, Int)
|
|
cycles prevCount (prevBank, banks) =
|
|
let count = prevCount + 1
|
|
bank = nextBank prevBank
|
|
hashableBank = toList bank
|
|
in if member hashableBank banks
|
|
then (count, count - findWithDefault undefined hashableBank banks)
|
|
else cycles count (bank, insert hashableBank count banks)
|
|
|
|
main :: IO ()
|
|
main = do
|
|
bank <- fmap (fromList . map read . words) $ readFile "06.txt"
|
|
print $ cycles 0 (bank, empty)
|