{-# Language QuasiQuotes, ImportQualifiedPost, NumDecimals #-}
module Main where
import Advent (format)
import Data.List (elemIndices, foldl', scanl')
import Data.Sequence (Seq)
import Data.Sequence qualified as Seq
main :: IO ()
IO ()
main =
do Int
input <- [format|2017 17 %u%n|]
Int -> IO ()
forall a. Show a => a -> IO ()
print (Int -> Seq Int -> Int
elemAfter Int
2017 (Int -> Int -> Seq Int
makeSequence Int
input Int
2017))
Int -> IO ()
forall a. Show a => a -> IO ()
print (Int -> Int
part2 Int
input)
elemAfter ::
Int ->
Seq Int ->
Int
elemAfter :: Int -> Seq Int -> Int
elemAfter Int
x Seq Int
xs = Seq Int -> Int -> Int
forall a. Seq a -> Int -> a
Seq.index Seq Int
xs ( (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`rem` Seq Int -> Int
forall a. Seq a -> Int
Seq.length Seq Int
xs )
where
Just Int
i = Int -> Seq Int -> Maybe Int
forall a. Eq a => a -> Seq a -> Maybe Int
Seq.elemIndexL Int
x Seq Int
xs
makeSequence ::
Int ->
Int ->
Seq Int
makeSequence :: Int -> Int -> Seq Int
makeSequence Int
jump Int
sz
= (Seq Int -> (Int, Int) -> Seq Int)
-> Seq Int -> [(Int, Int)] -> Seq Int
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Seq Int
xs (Int
x,Int
i) -> Int -> Int -> Seq Int -> Seq Int
forall a. Int -> a -> Seq a -> Seq a
Seq.insertAt Int
i Int
x Seq Int
xs) Seq Int
forall a. Seq a
Seq.empty
([(Int, Int)] -> Seq Int) -> [(Int, Int)] -> Seq Int
forall a b. (a -> b) -> a -> b
$ [Int] -> [Int] -> [(Int, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..Int
sz]
([Int] -> [(Int, Int)]) -> [Int] -> [(Int, Int)]
forall a b. (a -> b) -> a -> b
$ Int -> [Int]
cursors Int
jump
cursors ::
Int ->
[Int]
cursors :: Int -> [Int]
cursors Int
jump = (Int -> Int -> Int) -> Int -> [Int] -> [Int]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl' Int -> Int -> Int
nextCursor Int
0 [Int
1..]
where
nextCursor :: Int -> Int -> Int
nextCursor Int
cursor Int
size = (Int
cursorInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
jump)Int -> Int -> Int
forall a. Integral a => a -> a -> a
`rem`Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
{-# Inline cursors #-}
part2 ::
Int ->
Int
part2 :: Int -> Int
part2 = [Int] -> Int
forall a. HasCallStack => [a] -> a
last ([Int] -> Int) -> (Int -> [Int]) -> Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Int] -> [Int]
forall a. Eq a => a -> [a] -> [Int]
elemIndices Int
1 ([Int] -> [Int]) -> (Int -> [Int]) -> Int -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
5e7 ([Int] -> [Int]) -> (Int -> [Int]) -> Int -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Int]
cursors