module PolyDivisors ( findPolyDiv
, isPolyMod
, isPolyMod'
, isPolyMod''
) where
import Data.List (permutations)
findPolyDiv :: Int -> [Int]
findPolyDiv :: Int -> [Int]
findPolyDiv = (Int -> Bool) -> [Int] -> [Int]
forall a. (a -> Bool) -> [a] -> [a]
filter Int -> Bool
isPolyMod ([Int] -> [Int]) -> (Int -> [Int]) -> Int -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Int]
perms
perms :: Int -> [Int]
perms :: Int -> [Int]
perms Int
xs = (String -> Int) -> [String] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map String -> Int
forall a. Read a => String -> a
read (String -> [String]
forall a. [a] -> [[a]]
permutations (Int -> String
forall a. Show a => a -> String
show Int
xs))
isPolyMod :: Int -> Bool
isPolyMod :: Int -> Bool
isPolyMod Int
x = ((Int, Int) -> Bool -> Bool) -> Bool -> [(Int, Int)] -> Bool
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Bool -> Bool -> Bool
(&&) (Bool -> Bool -> Bool)
-> ((Int, Int) -> Bool) -> (Int, Int) -> Bool -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, Int) -> Bool
isModLen) Bool
True [(Int, Int)]
xs
where
n :: Int
n = String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Int -> String
forall a. Show a => a -> String
show Int
x)
xs :: [(Int, Int)]
xs = (Int -> (Int, Int)) -> [Int] -> [(Int, Int)]
forall a b. (a -> b) -> [a] -> [b]
map (\Int
p -> (Int
x Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
10 Int -> Int -> Int
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
p, Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
p) ) [Int
0..Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
isModLen :: (Int, Int) -> Bool
isModLen :: (Int, Int) -> Bool
isModLen (Int, Int)
xn = (Int -> Int -> Int) -> (Int, Int) -> Int
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> Int -> Int
forall a. Integral a => a -> a -> a
mod (Int, Int)
xn Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
isPolyMod' :: Int -> Bool
isPolyMod' :: Int -> Bool
isPolyMod' Int
x = (Int -> Bool) -> [Int] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (Int -> Int -> [Int]
polyMod Int
n Int
x)
where
n :: Int
n = String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Int -> String
forall a. Show a => a -> String
show Int
x)
polyMod :: Int -> Int -> [Int]
polyMod :: Int -> Int -> [Int]
polyMod Int
m Int
a
| Int
m Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = [Int
0]
| Bool
otherwise = Int
a Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
m Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: Int -> Int -> [Int]
polyMod (Int
m Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (Int
a Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
10)
isPolyMod'' :: Int -> Bool
isPolyMod'' :: Int -> Bool
isPolyMod'' Int
x = (Int -> Bool) -> [Int] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) [Int]
xs
where
n :: Int
n = String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Int -> String
forall a. Show a => a -> String
show Int
x)
xs :: [Int]
xs = (Int -> Int) -> [Int] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (\Int
p -> Int
x Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
10 Int -> Int -> Int
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
p Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
p) ) [Int
0..Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]