RosettaCodeData/Task/Cyclotomic-polynomial/Haskell/cyclotomic-polynomial-2.hs
2023-07-01 13:44:08 -04:00

36 lines
1.2 KiB
Haskell

showPoly [] = "0"
showPoly p = foldl1 (\r -> (r ++) . term) $
dropWhile null $
foldMap (\(c, n) -> [show c ++ expt n]) $
zip (reverse p) [0..]
where
expt = \case 0 -> ""
1 -> "*x"
n -> "*x^" ++ show n
term = \case [] -> ""
'0':'*':t -> ""
'-':'1':'*':t -> " - " ++ t
'1':'*':t -> " + " ++ t
'-':t -> " - " ++ t
t -> " + " ++ t
main = do
mapM_ (print . showPoly . cyclotomic) [1..30]
putStrLn $ replicate 40 '-'
mapM_ showLine $ take 4 task2
where
showLine (j, i, l) = putStrLn $ concat [ show j
, " appears in CM(", show i
, ") of length ", show l ]
-- in order to make computations faster we leave only each 5-th polynomial
task2 = (1,1,2) : tail (search 1 $ zip [0,5..] $ skipBy 5 cyclotomics)
where
search i ((k, p):ps) = if i `notElem` (abs <$> p)
then search i ps
else (i, k, length p) : search (i+1) ((k, p):ps)
skipBy n [] = []
skipBy n lst = let (x:_, b) = splitAt n lst in x:skipBy n b