diff --git a/day11long b/day11long new file mode 100644 index 0000000..0f98d52 --- /dev/null +++ b/day11long @@ -0,0 +1,55 @@ +Monkey 0: + Starting items: 52, 60, 85, 69, 75, 75 + Operation: new = old * 17 + Test: divisible by 13 + If true: throw to monkey 6 + If false: throw to monkey 7 + +Monkey 1: + Starting items: 96, 82, 61, 99, 82, 84, 85 + Operation: new = old + 8 + Test: divisible by 7 + If true: throw to monkey 0 + If false: throw to monkey 7 + +Monkey 2: + Starting items: 95, 79 + Operation: new = old + 6 + Test: divisible by 19 + If true: throw to monkey 5 + If false: throw to monkey 3 + +Monkey 3: + Starting items: 88, 50, 82, 65, 77 + Operation: new = old * 19 + Test: divisible by 2 + If true: throw to monkey 4 + If false: throw to monkey 1 + +Monkey 4: + Starting items: 66, 90, 59, 90, 87, 63, 53, 88 + Operation: new = old + 7 + Test: divisible by 5 + If true: throw to monkey 1 + If false: throw to monkey 0 + +Monkey 5: + Starting items: 92, 75, 62 + Operation: new = old * old + Test: divisible by 3 + If true: throw to monkey 3 + If false: throw to monkey 4 + +Monkey 6: + Starting items: 94, 86, 76, 67 + Operation: new = old + 1 + Test: divisible by 11 + If true: throw to monkey 5 + If false: throw to monkey 2 + +Monkey 7: + Starting items: 57 + Operation: new = old + 2 + Test: divisible by 17 + If true: throw to monkey 6 + If false: throw to monkey 2 diff --git a/day11short b/day11short new file mode 100644 index 0000000..30e09e5 --- /dev/null +++ b/day11short @@ -0,0 +1,27 @@ +Monkey 0: + Starting items: 79, 98 + Operation: new = old * 19 + Test: divisible by 23 + If true: throw to monkey 2 + If false: throw to monkey 3 + +Monkey 1: + Starting items: 54, 65, 75, 74 + Operation: new = old + 6 + Test: divisible by 19 + If true: throw to monkey 2 + If false: throw to monkey 0 + +Monkey 2: + Starting items: 79, 60, 97 + Operation: new = old * old + Test: divisible by 13 + If true: throw to monkey 1 + If false: throw to monkey 3 + +Monkey 3: + Starting items: 74 + Operation: new = old + 3 + Test: divisible by 17 + If true: throw to monkey 0 + If false: throw to monkey 1 diff --git a/day11ungolfed.hs b/day11ungolfed.hs new file mode 100644 index 0000000..6bca4a2 --- /dev/null +++ b/day11ungolfed.hs @@ -0,0 +1,75 @@ +import Control.Monad.State.Strict +import Data.List + +data Monkey = Monkey {items :: [Int], operation :: Int -> Int, test :: (Int, Int, Int), inspected :: Int} + +op :: String -> Int -> Int -> Int +op "*" = (*) +op "+" = (+) + +pread "old" old = old +pread i _ = read i + +parseOp :: [String] -> Int -> Int +parseOp [a,o,b] = \old -> op o (pread a old) (pread b old) + +parseDiv :: String -> Int +parseDiv = read.last.words + +parse [_,i,o,d,t,f] = Monkey (read$"["++drop 18 i++"]")(parseOp $ words$drop 19 o) (parseDiv d, parseDiv t, parseDiv f) 0 + +instance Show Monkey where + show (Monkey i o t ins) = "Monkey {items = " ++ show i ++ "} ("++ show ins ++")" + +instance Eq Monkey where + m1 == m2 = inspected m1 == inspected m2 + +instance Ord Monkey where + m1<=m2 = inspected m1 <= inspected m2 + +type MState = [Monkey] + +extract :: Int -> [a] -> ([a], a, [a]) +extract i m|(f,(c:b))<-splitAt i m=(f,c,b) + +addTo :: Int -> Int -> State MState () +addTo monkeyId item = do + monkeys <- get + let (f,monkey,b) = extract monkeyId monkeys + let newMonkey = monkey {items = items monkey ++ [item]} + put $ f ++ (newMonkey:b) + + +step :: (Int -> Int) -> Int -> State MState () +step op monkeyId = do + monkeys <- get + let monkey = monkeys !! monkeyId + let newInspected = inspected monkey + length (items monkey) + forM_ (items monkey) $ \item -> do + let new = operation monkey item + let unworried = op new + let (divis, mtrue, mfalse) = test monkey + if unworried `mod` divis == 0 + then addTo mtrue unworried + else addTo mfalse unworried + let newMonkey = monkey {items = [], inspected = newInspected} + m <- get + let (f,c,b) = extract monkeyId m + put (f ++ (newMonkey:b)) + +monkeyRound :: (Int -> Int) -> State MState () +monkeyRound op = do + l <- length<$>get + forM_ [0..l-1] $ step op + +monkeyRounds i op = do + forM_ [1..i] $ \_-> monkeyRound op + +maxdivis = product.map((\(a,b,c)->a).test) + +compute monkeys n op = product $ map inspected$ take 2$reverse$sort$execState (monkeyRounds n op) monkeys + +main = do + monkeyFile <- map (parse.filter (/="")).groupBy(const (/="")).lines<$>readFile "day11long" + print $ compute monkeyFile 20 (`div` 3) + print $ compute monkeyFile 10000 (`mod` (maxdivis monkeyFile))