Day 15
This commit is contained in:
parent
20db7749dc
commit
14bf6df148
5 changed files with 115 additions and 1 deletions
|
@ -2,7 +2,7 @@
|
|||
--
|
||||
-- see: https://github.com/sol/hpack
|
||||
--
|
||||
-- hash: ea04591b11d049b24eb195b76d379646dcfbc1c5bf4ee126d894309a7a7a3708
|
||||
-- hash: c000ca3243983619481d89396b163acf8fb77f12488850d0f27e659ab2f1bd40
|
||||
|
||||
name: adventofcode
|
||||
version: 0.1.0.0
|
||||
|
@ -44,6 +44,7 @@ library
|
|||
Day12
|
||||
Day13
|
||||
Day14
|
||||
Day15
|
||||
other-modules:
|
||||
Paths_adventofcode
|
||||
build-depends:
|
||||
|
|
10
app/Main.hs
10
app/Main.hs
|
@ -22,6 +22,7 @@ import qualified Day11
|
|||
import qualified Day12
|
||||
import qualified Day13
|
||||
import qualified Day14
|
||||
import qualified Day15
|
||||
|
||||
showSol :: [Char] -> Doc -> IO ()
|
||||
showSol txt d = putText . toS . render $
|
||||
|
@ -49,6 +50,7 @@ solutions = Map.fromList [(["01"], day01)
|
|||
,(["12"], day12)
|
||||
,(["13"], day13)
|
||||
,(["14"], day14)
|
||||
,(["15"], day15)
|
||||
]
|
||||
|
||||
|
||||
|
@ -173,3 +175,11 @@ day14 = do
|
|||
showSol "Solution 1" (int (fromMaybe 0 sol1))
|
||||
sol2 <- Day14.solution2 Day14.input
|
||||
showSol "Solution 2" (int sol2)
|
||||
|
||||
day15 :: IO ()
|
||||
day15 = do
|
||||
putText "Day 15:"
|
||||
let sol1 = Day15.solution1 Day15.input
|
||||
showSol "Solution 1" (int sol1)
|
||||
let sol2 = Day15.solution2 Day15.input
|
||||
showSol "Solution 1" (int sol2)
|
||||
|
|
|
@ -27,6 +27,7 @@ library:
|
|||
- Day12
|
||||
- Day13
|
||||
- Day14
|
||||
- Day15
|
||||
dependencies:
|
||||
- base >=4.7 && <5
|
||||
- protolude
|
||||
|
|
88
src/Day15.hs
Normal file
88
src/Day15.hs
Normal file
|
@ -0,0 +1,88 @@
|
|||
{-# LANGUAGE NoImplicitPrelude #-}
|
||||
{-|
|
||||
description:
|
||||
|
||||
--- Day 15: Dueling Generators ---
|
||||
|
||||
Here, you encounter a pair of dueling generators. The generators, called
|
||||
generator A and generator B, are trying to agree on a sequence of numbers.
|
||||
However, one of them is malfunctioning, and so the sequences don't always match.
|
||||
|
||||
As they do this, a judge waits for each of them to generate its next value,
|
||||
compares the lowest 16 bits of both values, and keeps track of the number of
|
||||
times those parts of the values match.
|
||||
|
||||
The generators both work on the same principle. To create its next value, a
|
||||
generator will take the previous value it produced, multiply it by a factor
|
||||
(generator A uses 16807; generator B uses 48271), and then keep the remainder of
|
||||
dividing that resulting product by 2147483647. That final remainder is the value
|
||||
it produces next.
|
||||
|
||||
To calculate each generator's first value, it instead uses a specific starting
|
||||
value as its "previous value" (as listed in your puzzle input).
|
||||
|
||||
For example, suppose that for starting values, generator A uses 65, while
|
||||
generator B uses 8921. Then, the first five pairs of generated values are:
|
||||
|
||||
--Gen. A-- --Gen. B--
|
||||
1092455 430625591
|
||||
1181022009 1233683848
|
||||
245556042 1431495498
|
||||
1744312007 137874439
|
||||
1352636452 285222916
|
||||
In binary, these pairs are (with generator A's value first in each pair):
|
||||
|
||||
00000000000100001010101101100111
|
||||
00011001101010101101001100110111
|
||||
|
||||
01000110011001001111011100111001
|
||||
01001001100010001000010110001000
|
||||
|
||||
00001110101000101110001101001010
|
||||
01010101010100101110001101001010
|
||||
|
||||
01100111111110000001011011000111
|
||||
00001000001101111100110000000111
|
||||
|
||||
01010000100111111001100000100100
|
||||
00010001000000000010100000000100
|
||||
|
||||
Here, you can see that the lowest (here, rightmost) 16 bits of the third value
|
||||
match: 1110001101001010. Because of this one match, after processing these five
|
||||
pairs, the judge would have added only 1 to its total.
|
||||
|
||||
To get a significant sample, the judge would like to consider 40 million pairs.
|
||||
(In the example above, the judge would eventually find a total of 588 pairs that
|
||||
match in their lowest 16 bits.)
|
||||
|
||||
After 40 million pairs, what is the judge's final count?
|
||||
|
||||
|-}
|
||||
module Day15 where
|
||||
|
||||
import Protolude
|
||||
|
||||
input :: (Int64,Int64)
|
||||
input = (618,814)
|
||||
|
||||
testInput :: (Int64,Int64)
|
||||
testInput = (65,8921)
|
||||
|
||||
generatorA :: Int64 -> Int64
|
||||
generatorA x = x * 16807 `rem` 2147483647
|
||||
|
||||
generatorB :: Int64 -> Int64
|
||||
generatorB x = x * 48271 `rem` 2147483647
|
||||
|
||||
toInt16 :: Int64 -> Int16
|
||||
toInt16 = fromIntegral
|
||||
|
||||
solution1 input =
|
||||
let lst1 = map toInt16 $ iterate generatorA (fst input)
|
||||
lst2 = map toInt16 $ iterate generatorB (snd input)
|
||||
in length (filter (uncurry (==)) (take 40000000 (zip lst1 lst2)))
|
||||
|
||||
solution2 input =
|
||||
let lst1 = map toInt16 . filter ((== 0) . (`rem` 4)) $ iterate generatorA (fst input)
|
||||
lst2 = map toInt16 . filter ((== 0) . (`rem` 8)) $ iterate generatorB (snd input)
|
||||
in length (filter (uncurry (==)) (take 5000000 (zip lst1 lst2)))
|
14
test/Spec.hs
14
test/Spec.hs
|
@ -19,6 +19,7 @@ import qualified Day11
|
|||
import qualified Day12
|
||||
import qualified Day13
|
||||
import qualified Day14
|
||||
import qualified Day15
|
||||
|
||||
main :: IO ()
|
||||
main = defaultMain $
|
||||
|
@ -37,6 +38,7 @@ main = defaultMain $
|
|||
, testDay12
|
||||
, testDay13
|
||||
, testDay14
|
||||
, testDay15
|
||||
]
|
||||
|
||||
testDay01 =
|
||||
|
@ -259,3 +261,15 @@ testDay14 =
|
|||
(assertFailure "Should be 1242 groups")
|
||||
]
|
||||
]
|
||||
|
||||
testDay15 =
|
||||
testGroup "Day 15"
|
||||
[ testGroup "Solution 1"
|
||||
[ testCase "Example" $
|
||||
Day15.solution1 Day15.testInput @?= 588
|
||||
]
|
||||
, testGroup "Solution 2"
|
||||
[ testCase "Example" $
|
||||
Day15.solution2 Day15.testInput @?= 309
|
||||
]
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue