From 7b2828487e722abee9cb15e65eeed9043fa53a2b Mon Sep 17 00:00:00 2001 From: Eric Mertens Date: Sun, 15 Dec 2019 22:00:58 -0800 Subject: [PATCH] Day 16 --- advent2019.cabal | 6 ++++++ execs/Day16.hs | 54 ++++++++++++++++++++++++++++++++++++++++++++++ inputs/input16.txt | 1 + 3 files changed, 61 insertions(+) create mode 100644 execs/Day16.hs create mode 100644 inputs/input16.txt diff --git a/advent2019.cabal b/advent2019.cabal index 4813668..e8a5216 100644 --- a/advent2019.cabal +++ b/advent2019.cabal @@ -145,3 +145,9 @@ executable Day15 build-depends: advent2019, base, containers hs-source-dirs: execs default-language: Haskell2010 + +executable Day16 + main-is: Day16.hs + build-depends: advent2019, base, containers, vector + hs-source-dirs: execs + default-language: Haskell2010 diff --git a/execs/Day16.hs b/execs/Day16.hs new file mode 100644 index 0000000..b26aa98 --- /dev/null +++ b/execs/Day16.hs @@ -0,0 +1,54 @@ +{-| +Module : Main +Description : Day 16 solution +Copyright : (c) Eric Mertens, 2019 +License : ISC +Maintainer : emertens@gmail.com + + + +This code is not fast but if you let it run it will finish. +I still want to figure out a more efficient solution. + +-} +module Main (main) where + +import Advent +import Control.Applicative +import qualified Data.Vector.Unboxed as V + +main :: IO () +main = + do [inp] <- getParsedLines 16 (many anySingle) + let ns = digits inp + + putStrLn $ concatMap show $ V.toList $ V.take 8 $ iterate fft ns !! 100 + + let offset = read (take 7 inp) + + let ns' = V.concat (replicate 10000 ns) + putStrLn $ concatMap show $ V.toList $ V.take 8 $ V.drop offset $ iterate fft ns' !! 100 + +digits :: String -> V.Vector Int +digits = V.fromList . map (read . pure) + +fft :: V.Vector Int -> V.Vector Int +fft xs = V.generate (V.length xs) one + where + n = V.length xs + ps = V.scanl (+) 0 xs + factors i = takeWhile (\(Region _ a _) -> a < n) (regions i) + + one i = abs $ sum [ m * (ps V.! min n end - ps V.! start) | Region m start end <- factors i] + `rem` 10 + +data Region = Region !Int !Int !Int + deriving Show + +regions :: Int -> [Region] +regions i = go 0 + where + n = i + 1 + go offset = Region 1 (offset + i) (offset + i+n) + : Region (-1) (offset + i + n*2) (offset + i+n*2+ n) + : go (offset + 4 * n) diff --git a/inputs/input16.txt b/inputs/input16.txt new file mode 100644 index 0000000..11bbe52 --- /dev/null +++ b/inputs/input16.txt @@ -0,0 +1 @@ +59782619540402316074783022180346847593683757122943307667976220344797950034514416918778776585040527955353805734321825495534399127207245390950629733658814914072657145711801385002282630494752854444244301169223921275844497892361271504096167480707096198155369207586705067956112600088460634830206233130995298022405587358756907593027694240400890003211841796487770173357003673931768403098808243977129249867076581200289745279553289300165042557391962340424462139799923966162395369050372874851854914571896058891964384077773019120993386024960845623120768409036628948085303152029722788889436708810209513982988162590896085150414396795104755977641352501522955134675