Skip to main content
Italic codeblocks render strangly on some browsers removed it from the question. Feel free to revert
Source Link
Wheat Wizard
  • 100k
  • 22
  • 282
  • 661

Haskell, 61 bytes

import Data.Numbers.Primes
until=<<((==)=<<)$sum.primeFactors

Try it online!

Explanation

until=<<((==)=<<) takes a function f and applies it to input x until a fix point is reached, that is f x equals x. primeFactors returns the list of prime factors of a number, sum yields the sum of a list of numbers.

But wait, why does until=<<((==)=<<) the until=<<((==)=<<) the job and looks so weird?

If we assume f=sum.primeFactors, a more natural definition would be until(\x->f x==x)f, because until takes a predicate (a function which returns a boolean), a function which has the same input and return type (e.g. Int -> Int) and value of this type, and then applies the function to the value until the predicate is fulfilled.

until(\x->f x==x)f is the same as until(\x->(==)(f x)x)f, and as it holds that g (h x) x is the same as (g=<<h)x, we get until(\x->((==)=<<f)x)f. After Eta conversion, this becomes until((==)=<<f)f. But if we now treat (==)=<< as a function which is applied to f, we can see that until(((==)=<<)f)f is again of the form g (h x) x, with g=until, h=((==)=<<) and x=f, so it can be rewritten to (until=<<((==)=<<))f. Using the $ operator to get rid of the outer parentheses and substituting f with sum.primeFactors yields the solution from above.

Haskell, 61 bytes

import Data.Numbers.Primes
until=<<((==)=<<)$sum.primeFactors

Try it online!

Explanation

until=<<((==)=<<) takes a function f and applies it to input x until a fix point is reached, that is f x equals x. primeFactors returns the list of prime factors of a number, sum yields the sum of a list of numbers.

But wait, why does until=<<((==)=<<) the job and looks so weird?

If we assume f=sum.primeFactors, a more natural definition would be until(\x->f x==x)f, because until takes a predicate (a function which returns a boolean), a function which has the same input and return type (e.g. Int -> Int) and value of this type, and then applies the function to the value until the predicate is fulfilled.

until(\x->f x==x)f is the same as until(\x->(==)(f x)x)f, and as it holds that g (h x) x is the same as (g=<<h)x, we get until(\x->((==)=<<f)x)f. After Eta conversion, this becomes until((==)=<<f)f. But if we now treat (==)=<< as a function which is applied to f, we can see that until(((==)=<<)f)f is again of the form g (h x) x, with g=until, h=((==)=<<) and x=f, so it can be rewritten to (until=<<((==)=<<))f. Using the $ operator to get rid of the outer parentheses and substituting f with sum.primeFactors yields the solution from above.

Haskell, 61 bytes

import Data.Numbers.Primes
until=<<((==)=<<)$sum.primeFactors

Try it online!

Explanation

until=<<((==)=<<) takes a function f and applies it to input x until a fix point is reached, that is f x equals x. primeFactors returns the list of prime factors of a number, sum yields the sum of a list of numbers.

But wait, why does until=<<((==)=<<) the job and looks so weird?

If we assume f=sum.primeFactors, a more natural definition would be until(\x->f x==x)f, because until takes a predicate (a function which returns a boolean), a function which has the same input and return type (e.g. Int -> Int) and value of this type, and then applies the function to the value until the predicate is fulfilled.

until(\x->f x==x)f is the same as until(\x->(==)(f x)x)f, and as it holds that g (h x) x is the same as (g=<<h)x, we get until(\x->((==)=<<f)x)f. After Eta conversion, this becomes until((==)=<<f)f. But if we now treat (==)=<< as a function which is applied to f, we can see that until(((==)=<<)f)f is again of the form g (h x) x, with g=until, h=((==)=<<) and x=f, so it can be rewritten to (until=<<((==)=<<))f. Using the $ operator to get rid of the outer parentheses and substituting f with sum.primeFactors yields the solution from above.

added 1312 characters in body
Source Link
Laikoni
  • 26.3k
  • 6
  • 52
  • 115

Haskell, 61 bytes

import Data.Numbers.Primes
until=<<((==)=<<)$sum.primeFactors

Try it online!

Explanation

until=<<((==)=<<) takes a function f and applies it to input x until a fix point is reached, that is f x equals x. primeFactors returns the list of prime factors of a number, sum yields the sum of a list of numbers.

But wait, why does until=<<((==)=<<) the job and looks so weird?

If we assume f=sum.primeFactors, a more natural definition would be until(\x->f x==x)f, because until takes a predicate (a function which returns a boolean), a function which has the same input and return type (e.g. Int -> Int) and value of this type, and then applies the function to the value until the predicate is fulfilled.

until(\x->f x==x)f is the same as until(\x->(==)(f x)x)f, and as it holds that g (h x) x is the same as (g=<<h)x, we get until(\x->((==)=<<f)x)f. After Eta conversion, this becomes until((==)=<<f)f. But if we now treat (==)=<< as a function which is applied to f, we can see that until(((==)=<<)f)f is again of the form g (h x) x, with g=until, h=((==)=<<) and x=f, so it can be rewritten to (until=<<((==)=<<))f. Using the $ operator to get rid of the outer parentheses and substituting f with sum.primeFactors yields the solution from above.

Haskell, 61 bytes

import Data.Numbers.Primes
until=<<((==)=<<)$sum.primeFactors

Try it online!

Haskell, 61 bytes

import Data.Numbers.Primes
until=<<((==)=<<)$sum.primeFactors

Try it online!

Explanation

until=<<((==)=<<) takes a function f and applies it to input x until a fix point is reached, that is f x equals x. primeFactors returns the list of prime factors of a number, sum yields the sum of a list of numbers.

But wait, why does until=<<((==)=<<) the job and looks so weird?

If we assume f=sum.primeFactors, a more natural definition would be until(\x->f x==x)f, because until takes a predicate (a function which returns a boolean), a function which has the same input and return type (e.g. Int -> Int) and value of this type, and then applies the function to the value until the predicate is fulfilled.

until(\x->f x==x)f is the same as until(\x->(==)(f x)x)f, and as it holds that g (h x) x is the same as (g=<<h)x, we get until(\x->((==)=<<f)x)f. After Eta conversion, this becomes until((==)=<<f)f. But if we now treat (==)=<< as a function which is applied to f, we can see that until(((==)=<<)f)f is again of the form g (h x) x, with g=until, h=((==)=<<) and x=f, so it can be rewritten to (until=<<((==)=<<))f. Using the $ operator to get rid of the outer parentheses and substituting f with sum.primeFactors yields the solution from above.

Source Link
Laikoni
  • 26.3k
  • 6
  • 52
  • 115

Haskell, 61 bytes

import Data.Numbers.Primes
until=<<((==)=<<)$sum.primeFactors

Try it online!