-- stack --resolver lts-18.14 ghc -- --make -Wall -O TestSingle.hs
-- stack --resolver lts-18.14 ghc -- --make -Wall -O TestSingle.hs -threaded -rtsopts -eventlog
-- stack ghc -- -O2 -Wall TestSingle.hs -threaded -rtsopts -eventlog
-- ./TestSingle +RTS -N2 -s -ls < test_input/input1.in
-- threadscope TestSingle.eventlog
-- stack test multpoly:multpoly-test
-- add in package.yaml

-- [1, 2, 3] -> 1 + 2x + 3x^2
{-
1 2 3 
4 5 6 7 8
[4.0,13.0,28.0,34.0,40.0,37.0,24.0]
-}

import System.IO(Handle, hGetLine, stdin)
import qualified BruteForce.MultPoly(mult_polys)
import qualified BruteForce.MapReduce(mult_polys)
import qualified BruteForce.ParMultPoly(mult_polys)
import qualified FFT.FMultPoly(mult_polys)
import qualified FFT.CTMultPoly(mult_polys)
import qualified FFT.ParFMultPoly(mult_polys)
import qualified FFT.ParCTMultPoly(mult_polys)
import qualified FFT.ParCTMultPoly(be_fft) -- TODO
import qualified FFT.ParFMultPoly(fft)
import FFT.FMultPoly(convert) -- TODO

import Data.Complex

-- get_nums :: Handle -> IO [Float]
get_nums :: Handle -> IO [Double]
get_nums = to_nums . hGetLine
  where
    to_nums line = do
      line_str <- line
      return $ map read $ words line_str

main :: IO ()
main = do
  x <- get_nums stdin
  y <- get_nums stdin
  -- mapM_ print (BruteForce.MultPoly.mult_polys x y)
  -- putStrLn $ show $ length $ BruteForce.MultPoly.mult_polys x y
  -- mapM_ print (BruteForce.ParMultPoly.mult_polys x y)
  -- putStrLn $ show $ length $ BruteForce.ParMultPoly.mult_polys x y
  -- mapM_ print (BruteForce.MapReduce.mult_polys x y)
  putStrLn $ show $ length $ BruteForce.MapReduce.mult_polys 4 x y
  -- mapM_ print (FFT.FMultPoly.mult_polys x y)
  -- putStrLn $ show $ length $ FFT.FMultPoly.mult_polys x y
  -- mapM_ print (FFT.CTMultPoly.mult_polys x y)
  -- mapM_ print (FFT.ParFMultPoly.mult_polys x y)
  -- putStrLn $ show $ length $ FFT.ParFMultPoly.mult_polys x y
  -- mapM_ print (FFT.ParCTMultPoly.mult_polys x y)
  -- putStrLn $ show $ length $ FFT.ParCTMultPoly.mult_polys x y
  -- mapM_ print (FFT.ParFMultPoly.fft (convert x ((2 ^ (ceiling $ logBase 2 (fromIntegral (2 * (length x))))) - (length x))) (2 ^ (ceiling $ logBase 2 (fromIntegral (2 * (length x))))) (exp (- 2 * pi * (0 :+ 1) / (fromIntegral (length x)))))
  -- mapM_ print (FFT.ParCTMultPoly.be_fft (convert x (2 ^ (ceiling $ logBase 2 (fromIntegral (2 * (length x)))) - (length x))) 4)
  