Euler problem 28.2

e28a :: Integer
e28a = 1 + sum [4*(n-2)^2 + 10*(n-1)
               | n <- [3, 5 .. 1001]]


e28b :: Integer
e28b = let n = 500
           sumSquares = n*(n+1)*(2*n+1) `div` 6
           sumLinear = n*(n+1) `div` 2
       in 16*sumSquares + 4*sumLinear + 4*n + 1
λ> :set +s
λ> e28a
669171001
(0.00 secs, 617,688 bytes)

λ> e28b
669171001
(0.00 secs, 82,400 bytes)
λ> 

— Me@2025-11-17 12:00:22 AM

.

.

2025.11.17 Monday (c) All rights reserved by ACHK

Euler problem 27.2.2

p_27 = -(2 * a - 1) * (a ^ 2 - a + 41)
  where
    n = 1000
    m = head $ filter (\x -> x ^ 2 - x + 41 > n) [1 ..]
    a = m - 1

Euler Problem 27 asks us to find a quadratic equation of the form (n^2 + a \cdot n + b) that generates the most consecutive prime numbers starting from n = 0, with the constraints |a| < 1000 and |b| \leq 1000. The final answer is the product a \cdot b for the winning pair. The “official” Haskell solution looks cryptic, but there’s a clever trick behind it. Let’s break it down step-by-step in a way that’s easier to follow.

A Handy Math Trick: Shifting the Quadratic

Imagine we tweak our quadratic (n^2 + a \cdot n + b) by replacing n with n - x. When we expand it out, we get:

(n - x)^2 + a(n - x) + b = n^2 + (a - 2x)n + (x^2 - ax + b)

This is still a quadratic in n, but now the coefficients are:

  • a_{\text{new}} = a - 2x
  • b_{\text{new}} = x^2 - ax + b

By choosing the right x, we can transform any quadratic into a simpler form, like n^2 + d or n^2 + n + d. This is our starting point.

Which Form Works Best?

  • Form 1: n^2 + d
    This one’s a dud. Plug in n = 0, 1, 2, 3, and you’ll see every other number is even (e.g., d, d+1, d+4, d+9). With so many evens, it can’t produce a long run of primes—primes are mostly odd (except 2).
  • Form 2: n^2 + n + d
    This is more promising. A mathematician named Rabinowitz proved that for this form to generate the longest sequence of primes, 4d - 1 must be a special number called a Heegner number. There are only six possibilities, and after testing, n^2 + n + 41 comes out on top. It spits out 40 primes from n = 0 to n = 39. The runner-up, n^2 + n + 17, doesn’t do as well.

So, n^2 + n + 41 is our golden ticket. But there’s more to it.

The Symmetry Bonus

Here’s a cool trick with n^2 + n + 41:

(-1 - n)^2 + (-1 - n) + 41 = n^2 + n + 41

This means if n = 2 gives a prime (like 47), then n = -3 (i.e., -1 - 2) does too (also 47). The sequence works both ways—positive and negative n. Starting at n = 0, we get 40 primes up to n = 39, but we can also count backward with negative n. Our goal is to shift this quadratic so we capture more of these primes from n = 0 onward, while keeping a and b within the problem’s limits.

Fitting It Into the Rules

Let’s start with n^2 + n + 41 (where a = 1, b = 41) and shift it using our trick:

  • New quadratic: n^2 + (1 - 2x)n + (x^2 - x + 41)
  • New a = 1 - 2x
  • New b = x^2 - x + 41

The problem says |a| < 1000 and |b| \leq 1000, so:

  • |1 - 2x| < 1000
  • |x^2 - x + 41| \leq 1000

The second condition is trickier because x^2 grows fast. We need the biggest x where x^2 - x + 41 \leq 1000.

Crunching the Numbers

Let’s test some x values:

  • x = 31: 31^2 - 31 + 41 = 961 - 31 + 41 = 971 (under 1000)
  • x = 32: 32^2 - 32 + 41 = 1024 - 32 + 41 = 1033 (over 1000)

So, x = 31 is the largest value that works. Now calculate:

  • a = 1 - 2 \cdot 31 = 1 - 62 = -61
  • b = 971 (from above)

Check the constraints:

  • |a| = |-61| = 61 < 1000
  • |b| = 971 \leq 1000

The Haskell Code Explained

That’s where this funky code comes in:

n = 1000
m = head $ filter (\x -> x ^ 2 - x + 41 > n) [1 ..]
a = m - 1

It finds m = 32 (first x where x^2 - x + 41 > 1000). Then x = m - 1 = 31.

The final line:

p_27 = -(2 * a - 1) * (a ^ 2 - a + 41)

This is a bit off. It uses a = 31, but we need a = 1 - 2x = -61. The correct product should be:

  • a = -61
  • b = 971
  • a \cdot b = -61 \cdot 971 = -59231

The code’s formula seems to be a typo or a leftover from a different derivation. It should just compute (1 - 2x) \cdot (x^2 - x + 41).

Why It Works

With a = -61, b = 971, the quadratic n^2 - 61n + 971 generates 71 primes from n = 0 to n = 70. This shift captures more of the n^2 + n + 41 sequence’s primes in the positive direction, thanks to the negative a. The product -59231 is the answer.

Wrapping Up

This solution is sneaky—it starts with a prime-generating champ, shifts it just right, and fits the problem’s rules. It’s not the brute-force way (testing every a and b), but a math shortcut that lands on the perfect answer. Pretty cool, right?

— Me@2025-03-24 12:25:20 PM

.

.

2025.03.30 Sunday (c) All rights reserved by ACHK

Euler problem 26.2.2

import Data.List (elemIndex, maximumBy) 
import Data.Ord (comparing)
import Data.Maybe (fromJust)

recurringCycle :: Int -> Int
recurringCycle d = remainders 1 []
  where
    remainders r rs
      | r == 0          = 0
      | s `elem` rs     = 1 + fromJust (elemIndex s rs)
      | otherwise       = remainders ((r * 10) `mod` d) (s : rs)
      where s = r `mod` d

p26 :: Int
p26 = fst $ maximumBy (comparing snd) [(n, recurringCycle n) | n <- [1,3..999], n `mod` 5 /= 0]

λ> :set +s
λ> p26
983
(0.11 secs, 29,770,480 bytes)
λ> 

— Me@2025-02-06 08:29:54 AM

.

.

2025.02.06 Thursday (c) All rights reserved by ACHK

Euler problem 25.2.2

import System.CPUTime
import Text.Printf (printf)
import Data.List (findIndex)

time :: (Show a) => a -> IO a
time result = do
    start <- getCPUTime
    let computed = result
    end <- computed `seq` getCPUTime
    let diff = (fromIntegral (end - start)::Float)/(10^12)
    printf "Result: %s\n Time taken: %.6f seconds\n" (show computed) diff
    return computed
    
matrixMultiply :: Num a => [(a, a)] -> [(a, a)] -> [(a, a)]
matrixMultiply [(a11, a12), (a21, a22)] [(b11, b12), (b21, b22)] =
  [ (a11*b11 + a12*b21, a11*b12 + a12*b22)
  , (a21*b11 + a22*b21, a21*b12 + a22*b22) ]
 
matrixPower :: Num a => [(a, a)] -> Int -> [(a, a)]
matrixPower m 1 = m
matrixPower m n =
  let half = matrixPower m (n `div` 2)
      squared = matrixMultiply half half
  in if odd n then matrixMultiply squared m else squared
 
digitsInNumber :: (Show a, Integral a) => a -> Int
digitsInNumber = length . show
 
fibNth :: Integral a => a -> a
fibNth n 
  | n <= 2    = 1
  | otherwise = fst $ head $ matrixPower [(1, 1), (1, 0)] (fromIntegral (n - 1))
 
fibUpperBound :: Int -> Integer
fibUpperBound digitCount =
  let phi = 1.618033988749895
      logPhi = logBase 10 phi
      log5 = logBase 10 5
  in ceiling $ (fromIntegral digitCount - 1 + (log5 / 2)) / logPhi
 
binarySearchFibIndex :: Int -> Maybe Integer
binarySearchFibIndex digitCount =
  let upperBound = fibUpperBound digitCount
      binarySearch left right 
        | left > right = Nothing
        | otherwise =
            let mid = left + (right - left) `div` 2
                midFib = fibNth mid
                midDigits = digitsInNumber midFib
            in case compare midDigits digitCount of
                 EQ ->
                   let prevDigits = digitsInNumber $ fibNth (mid - 1)
                   in if prevDigits < digitCount then Just mid else binarySearch left (mid - 1)
                 LT -> binarySearch (mid + 1) right
                 GT -> binarySearch left (mid - 1)
  in binarySearch 1 upperBound

λ> time $ binarySearchFibIndex 1000
Result: Just 4782
 Time taken: 0.000852 seconds
Just 4782
λ> 
λ> time $ binarySearchFibIndex 1000
Result: Just 4782
 Time taken: 0.006747 seconds
Just 4782
λ> 

— Me@2024-12-25 07:00:13 AM

.

.

2025.01.01 Wednesday (c) All rights reserved by ACHK

Euler problem 25.2.1

import System.CPUTime
import Text.Printf (printf)

-- | Times the execution of a pure function and prints the result.
time :: (Show a) => a -> IO a
time result = do
    start <- getCPUTime
    let computed = result
    end <- computed `seq` getCPUTime
    let diff = (fromIntegral (end - start)::Float)/(10^12)
    printf "Result: %s\n Time taken: %.6f seconds\n" (show computed) diff
    return computed

fibs :: [Integer]
fibs = 0:1:zipWith (+) fibs (tail fibs)

t :: Integer
t = 10^999
 
p25 :: Int
p25 = length w
    where
      w = takeWhile (< t) fibs

λ> time p25
Result: 4782
 Time taken: 0.000496 seconds
4782
λ> 
λ> time p25
Result: 4782
 Time taken: 0.002918 seconds
4782
λ> 

— Me@2024-12-25 07:00:13 AM

.

.

2024.12.26 Thursday (c) All rights reserved by ACHK

Euler problem 24.2

import Data.List ( delete )

fac :: (Eq t, Num t) => t -> t
fac n = f n 1
  where
    f 0 acc = acc
    f m acc = f (m - 1) (m * acc)

perms :: Eq a => [a] -> Int -> [a] -> [a]
perms [] _ acc = reverse acc
perms xs n acc
  = perms (delete x xs) (mod n m) (x : acc)
  where 
    m = fac $ length xs - 1
    y = div n m
    x = xs !! y

p24 :: [Char]
p24 = perms "0123456789" 999999 []

λ> :set +s
λ> p24
"2783915460"
(0.02 secs, 121,968 bytes)
λ> 

— Me@2024-11-18 07:22:15 PM

.

.

2024.11.19 Tuesday (c) All rights reserved by ACHK

Euler problem 23.2

import Data.Array as Array ( Array )
import Data.Array.Base ( (!), listArray )
import Data.List (group)

primes :: [Int]
primes = 2 : filter (null . tail . (pfa !)) [3, 5 ..]

ub :: Int
ub = 28123

pfa :: Array Int [Int]
pfa = listArray (2, ub) $ map pf [2..ub]

pf :: Int -> [Int]
pf n = factor n primes
  where
    factor n (p : ps)
      | p * p > n = [n]
      | n `mod` p == 0 = p : pfa ! (n `div` p)
      | otherwise = factor n ps

groupFactors :: [Int] -> [[Int]]
groupFactors xs = [[head x, length x] | x <- group xs]

genDiv :: [[Int]] -> [Int]
genDiv = foldr combine [1]
  where
    combine [p, n] acc
      = [x * p^e | x <- acc, e <- [0..n]]

sumProperDivisors :: Int -> Int
sumProperDivisors n
  = -n + sum (genDiv $ groupFactors $ pfa ! n)

isAbundant :: Int -> Bool
isAbundant n = sumProperDivisors n > n

abdSieve :: Array Int Bool
abdSieve = listArray (2, ub) $ map isAbundant [2..ub]

abundantNumbers :: Int -> [Int]
abundantNumbers m
  | m > ub = filter isAbundant [2..m]
  | otherwise = filter (abdSieve !) [2..m]

abundantList :: [Int]
abundantList = abundantNumbers ub

isAbundantSum :: Int -> Bool
isAbundantSum n 
  = any (\a -> abdSieve ! (n-a))
    $ takeWhile (<= n `div` 2) abundantList

notAbundantSumsList :: Int -> [Int]
notAbundantSumsList m
  = filter (not . isAbundantSum) [1..m]

λ> :set +s
λ> sum (notAbundantSumsList ub)
4179871
(1.14 secs, 1,772,425,584 bytes)
λ> 

— Me@2024-10-19 09:53:30 PM

.

.

2024.10.21 Monday (c) All rights reserved by ACHK

Euler problem 22.2

import Data.Char (ord)
import Data.List (sort)

score word
  = sum $ map (\char -> ord char - ord 'A' + 1) word

nameScore filename = do
  content <- readFile filename
  let    
    names = read $ "[" ++ content ++ "]"       
  return $
    sum $ zipWith (*) [1..] $ map score $ sort names

λ> nameScore "names.txt"
871198282
λ> 

— Me@2024-09-09 03:40:11 PM

.

.

2024.09.10 Tuesday (c) All rights reserved by ACHK

Euler problem 21.2.2

import Data.Array ( (!), accumArray )

-- ...
    
p21 :: Integer -> Integer
p21 max_ = sum $ filter isAmicable [1 .. max_ - 1]
  where     
    gen n | n > max_ = []
          | otherwise = [(i*n, n) | i <- [2 .. max_ `div` n]] ++ gen (n+1)
    arr = accumArray (+) 0 (0, max_) (gen 1)
    arrb b | b < max_ = arr!b
           | otherwise = sumProperDivisors b
    isAmicable a = let b = (arr!a)
                     in b /= a && arrb b == a

λ> :set +s
λ> p21 10000
31626
(0.06 secs, 71,654,248 bytes)
λ> p21 100000
852810
(0.69 secs, 911,377,712 bytes)
λ> p21 1000000
27220963
(9.84 secs, 11,333,936,728 bytes)
λ> p21 10000000
649734295
(134.77 secs, 139,491,977,584 bytes)
λ> 

— Me@2024-08-18 07:32:17 AM

.

.

2024.08.18 Sunday (c) All rights reserved by ACHK

Watermelon 2

Euler problem 21.2.1

.

primes :: [Integer]
primes = 2 : filter (null . tail . primeFactors) [3, 5 ..]

primeFactors :: Integer -> [Integer]
primeFactors n = factor n primes
  where
    factor n (p : ps)
      | p * p > n = [n]
      | n `mod` p == 0 = p : factor (n `div` p) (p : ps)
      | otherwise = factor n ps

groupFactors :: [Integer] -> [[Integer]]
groupFactors = gf []
  where
    gf acc lst
      | null lst = reverse acc
      | null acc = gf [[p,1]] ps
      --
      | p == head (head acc) =
        gf ([p, head (tail (head acc)) + 1]:tail acc) ps
      --  
      | otherwise = gf ([p,1]:acc) ps
      where
        p = head lst
        ps = tail lst

generateDivisors :: Integral b => [[b]] -> [b]
generateDivisors xs = go xs 1
  where
    go [] acc = [acc]
    go (pe:ps) acc = concat [go ps (acc*p^e) | e <- [0..n]]
      where
        p = head pe
        n = pe !! 1

sumProperDivisors :: Integer -> Integer
sumProperDivisors n
  = -n + sum (generateDivisors
              (groupFactors (primeFactors n)))

amicableNumbers :: Integer -> [Integer]
amicableNumbers limit
  = [a | a <- [1..(limit-1)],
      let b = sumProperDivisors a, 
            a == sumProperDivisors b,
            a /= b]

λ> :set +s
λ> sum (amicableNumbers 10000)
31626
(0.35 secs, 511,950,576 bytes)
λ> sum (amicableNumbers 100000)
852810
(4.73 secs, 6,902,354,168 bytes)
λ> sum (amicableNumbers 1000000)
27220963
(66.07 secs, 93,880,279,320 bytes)
λ> 

— Me@2024-08-11 10:40:06 AM

.

.

2024.08.12 Monday (c) All rights reserved by ACHK

World Cup 94, 2

Find the sum of the digits in the number \displaystyle{100!}.

import Data.Char ( digitToInt )

p_20 = sum
       $ map digitToInt
       $ show $ product [1..100]

λ> p_20
648

— Haskell official

— Me@2024-07-17 03:44:42 PM

.

.

2024.07.18 Thursday (c) All rights reserved by ACHK

Euler problem 19.2

How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

isLeap :: Int -> Bool
isLeap year
  = (mod year 4 == 0
     && mod year 100 /= 0)
  || mod year 400 == 0

daysInMonth :: Int -> Int -> Int
daysInMonth year month
  | month `elem` [1, 3, 5, 7, 8, 10, 12] = 31
  | month `elem` [4, 6, 9, 11] = 30
  | month == 2 = if isLeap year
                 then 29
                 else 28

nextMonth :: Int -> Int -> Int -> Int
nextMonth dayOfWeek y m 
  = (dayOfWeek + daysInMonth y m) `mod` 7

countSundays :: Int -> Int -> Int -> Int -> Int
countSundays startYear startMonth dayOfWeek sundays
  | y > 2000  = sundays
  | m > 12    = countSundays (y+1) 1 dayOfWeek sundays
  | otherwise = countSundays y (m+1) nextDayOfWeek sun
  where
    y = startYear
    m = startMonth
    nextDayOfWeek = nextMonth dayOfWeek y m 
    sun | dayOfWeek == 0 = sundays + 1
        | otherwise      = sundays

e19 :: Int
e19 = countSundays 1901 1 2 0
-- The third argument is dayOfWeek.
-- Its value is 2 here  
-- because 1 Jan 1901 was a Tuesday. 

λ> e19
171
λ> 

— Me@2024-02-10 12:00:39 PM

.

.

2024.02.11 Sunday (c) All rights reserved by ACHK

Euler problem 18.2

tri = [[75],
       [95,64],
       [17,47,82],
       [18,35,87,10],
       [20,04,82,47,65],
       [19,01,23,75,03,34],
       [88,02,77,73,07,63,67],
       [99,65,04,28,06,16,70,92],
       [41,41,26,56,83,40,80,70,33],
       [41,48,72,33,47,32,37,16,94,29],
       [53,71,44,65,25,43,91,52,97,51,14],
       [70,11,33,28,77,73,17,78,39,68,17,57],
       [91,71,52,38,17,14,91,43,58,50,27,29,48],
       [63,66,04,68,89,53,67,30,73,16,69,87,40,31],
       [04,62,98,27,23,09,70,98,73,93,38,53,60,04,23]]
  
pathAddItem x (y:ys) (z:zs)
  = (x+m):x:ms
  where 
    (m:ms) | y > z = y:ys
           | otherwise = z:zs
           
listApplyPathAddItem xs ys
  = zipWith3 f xs ys $ tail ys 
  where
    f = pathAddItem
   
e18 = foldr g acc (init tri) 
  where
    toPair x = [x,x]
    g = listApplyPathAddItem
    acc = map toPair $ last tri

— Me@2023-12-28 11:25:22 AM

.

.

2023.12.28 Thursday (c) All rights reserved by ACHK

Euler problem 17.2

import Data.Char ( digitToInt )

one :: [String]
one =
  [ "one",
    "two",
    "three",
    "four",
    "five",
    "six",
    "seven",
    "eight",
    "nine",
    "ten",
    "eleven",
    "twelve",
    "thirteen",
    "fourteen",
    "fifteen",
    "sixteen",
    "seventeen",
    "eighteen",
    "nineteen"
  ]

ty :: [String]
ty =
  [ "twenty",
    "thirty",
    "forty",
    "fifty",
    "sixty",
    "seventy",
    "eighty",
    "ninety"
  ]

english :: Int -> [Char]
english x
  | x == 0 = []
  | x < 20 = one !! (x - 1)
  | x >= 20 && x < 100 =
      ty !! (firstDigit x - 2)
        ++ " "
        ++ english (x - firstDigit x * 10)
        
  | x < 1000 && x `mod` 100 == 0 =
      one !! (firstDigit x - 1)
        ++ " hundred"
      
  | x > 100 && x <= 999 =
      one !! (firstDigit x - 1)
        ++ " hundred and "
        ++ english (x - firstDigit x * 100)
        
  | x == 1000 = "one thousand"
  | otherwise = "error"
  where
    firstDigit = digitToInt . head . show

removeSpace :: [Char] -> [Char]
removeSpace = filter (`notElem` " ")

engCat :: [Int] -> [Char]
engCat = concatMap english

e17 :: Int
e17 = length . removeSpace $ engCat [1..1000]

— based on Haskell official

λ> e17
21124

— colorized by palette fm

— Me@2023-11-07 11:24:03 PM

.

.

2023.11.08 Wednesday (c) All rights reserved by ACHK

Euler problem 14.2

import Data.Array ( listArray, (!) )
import Data.List ( elemIndex )

collatzLengthList m = collatzLengthArray
  where
    collatzLengthArray
      = listArray (1,m) $ 1:map collatzLength [2..m]
      where
        collatzLength n
          | b<=m = 1 + collatzLengthArray ! b
          | otherwise = 1 + collatzLength b
          where
            b
              | even n = n `div` 2 
              | otherwise = 3*n+1

e14 :: (Maybe Int, Integer)
e14 = (n, m)
  where
    m = maximum cArray
    cArray = collatzLengthList p
    p = 1000000
    n = elemIndex m cList
      where
        cList = 0:[cArray ! x | x <- [1..p]]

λ> :set +s
λ> e14
(Just 837799,525)
(1.74 secs, 2,193,219,920 bytes)

— Me@2023-07-25 11:55:41 PM

.

.

2023.07.26 Wednesday (c) All rights reserved by ACHK

Euler problem 13.2

e13 :: IO ()
e13 = do
  str <- readFile "n.txt"
  let sList = lines str
      nList = map (\x -> read x :: Integer) sList
   in print $ take 10 . show . sum $ nList

— Me@2023-06-06 11:37:32 AM

.

.

2023.06.06 Tuesday (c) All rights reserved by ACHK

Euler problem 12.2

primes :: [Integer]
primes = 2 : filter (null . tail . primeFactors) [3, 5 ..]

primeFactors :: Integer -> [Integer]
primeFactors n = factor n primes
  where
    factor n (p : ps)
      | p * p > n = [n]
      | n `mod` p == 0 = p : factor (n `div` p) (p : ps)
      | otherwise = factor n ps

groupFactors :: [Integer] -> [[Integer]]
groupFactors = gf []
  where
    gf acc lst
      | null lst = reverse acc
      | null acc = gf [[p,1]] ps
      --
      | p == head (head acc) =
        gf ([p, head (tail (head acc)) + 1]:tail acc) ps
      --  
      | otherwise = gf ([p,1]:acc) ps
      where
        p = head lst
        ps = tail lst
        
nDiv :: Integer -> Integer
nDiv n = product (map ((1+) . head . tail)
                  (groupFactors (primeFactors n)))

fm :: Integer -> Integer -> Integer
fm m n
  | triDiv n > m = n*(n+1) `div` 2
  | otherwise = fm m (n+1)
  where
    triDiv n
      | even n = nDiv (n `div` 2)*nDiv (n+1)
      | otherwise = nDiv n*nDiv ((n+1) `div` 2)

λ> :set +s
λ> fm 500 1
76576500
(0.20 secs, 199,313,728 bytes)
λ> 

— Me@2023-05-04 09:51:19 AM

.

.

2023.05.04 Thursday (c) All rights reserved by ACHK

Euler problem 10.2

Find the sum of all the primes below two million.

removeIf :: (a -> Bool) -> [a] -> [a]
removeIf p = filter (not . p)

sieveIter :: Integral a => [a] -> [a] -> [a]
sieveIter [] (x:xs) = x:xs
sieveIter (x:xs) acc
  | x^2 > last (x:xs) = reverse acc++(x:xs)
  | otherwise = sieveIter xss (x:acc)
  where
    xss = removeIf (\n -> n `mod` x == 0) xs

primeList :: Integral a => [a] -> [a]
primeList xs = sieveIter xs []

pL :: [Integer]
pL = primeList [2..2000000]

f :: Integer
f = sum (takeWhile (< 2000000) pL)

— colorized by palette fm

— Me@2023-02-25 12:35:57 PM

.

.

2023.02.26 Sunday (c) All rights reserved by ACHK

Direct from Dell

Euler problem 9.2

.

There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the product abc.

g p =
  [ [a, b, c]
    | m <- [2 .. limit],
      n <- [1 .. (m - 1)],
      let a = m ^ 2 - n ^ 2,
      let b = 2 * m * n,
      let c = m ^ 2 + n ^ 2,
      a + b + c == p
  ]
  where
    limit = floor . sqrt . fromIntegral $ p

— based on Haskell official

.

Euclid’s formula is a fundamental formula for generating Pythagorean triples given an arbitrary pair of integers m and n with m > n > 0. The formula states that the integers

\displaystyle{ a=m^{2}-n^{2},\ \,b=2mn,\ \,c=m^{2}+n^{2}}

form a Pythagorean triple. The triple generated by Euclid’s formula is primitive if and only if m and n are coprime and one of them is even. When both m and n are odd, then a, b, and c will be even, and the triple will not be primitive; however, dividing a, b, and c by 2 will yield a primitive triple when m and n are coprime.

Every primitive triple arises (after the exchange of a and b, if a is even) from a unique pair of coprime numbers m, n, one of which is even.

— Wikipedia on Pythagorean triple

— Me@2022-12-10 09:57:27 PM

.

.

2022.12.11 Sunday (c) All rights reserved by ACHK