Day 11: a lot
This commit is contained in:
parent
af59b6d393
commit
09aad5b368
3 changed files with 157 additions and 0 deletions
55
day11long
Normal file
55
day11long
Normal file
|
@ -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
|
27
day11short
Normal file
27
day11short
Normal file
|
@ -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
|
75
day11ungolfed.hs
Normal file
75
day11ungolfed.hs
Normal file
|
@ -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))
|
Loading…
Add table
Reference in a new issue