How to resolve the algorithm Attractive numbers step by step in the JavaScript programming language
How to resolve the algorithm Attractive numbers step by step in the JavaScript programming language
Table of Contents
Problem Statement
A number is an attractive number if the number of its prime factors (whether distinct or not) is also prime.
The number 20, whose prime decomposition is 2 × 2 × 5, is an attractive number because the number of its prime factors (3) is also prime.
Show sequence items up to 120.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Attractive numbers step by step in the JavaScript programming language
The given script is written in JavaScript and implements a function called attractiveNumbers
that generates a sequence of attractive numbers. An attractive number is a positive integer that satisfies the following conditions:
- It is a prime number.
- The number of prime factors of the number is prime.
The script also includes several utility functions, such as isPrime
check if a number is prime, primeFactors
to find the prime factors of a number, and other generic functions like enumFrom
, enumFromThenTo
, filter
, ge
, justifyRight
, last
, length
, map
, showCols
, str
, takeWhile
, unlines
, and until
.
Here's a breakdown of the code:
-
attractiveNumbers
: This function generates an infinite series of attractive numbers using theisPrime
andprimeFactors
functions. It returns a generator that yields attractive numbers. -
isPrime
: This function checks whether a given number is prime. It uses a series of checks to efficiently determine if a number is prime or not. -
primeFactors
: This function finds the prime factors of a given number. It uses a loop to iteratively find the prime factors and returns a list of those factors. -
enumFrom
: This function generates an infinite succession of enumerable values starting from a given value. It is used to generate the sequence of attractive numbers. -
enumFromThenTo
: This function generates a finite range of values from a starting value to an ending value. It is used to generate the sequence of attractive numbers within a specific range. -
filter
: This function filters a list of values based on a predicate function. It returns a new list containing only the values that satisfy the predicate. -
ge
: This function checks if one value is greater than or equal to another. -
justifyRight
: This function justifies a string to the right by adding padding characters. It is used to align the output of the attractive numbers. -
last
: This function returns the last item of a list. -
length
: This function returns the length of a list. -
map
: This function applies a function to each element of a list and returns a new list with the transformed values. -
showCols
: This function displays a list of values in columns. It is used to format the output of the attractive numbers. -
str
: This function converts a value to a string. -
takeWhile
: This function takes a list and a predicate function and returns a new list containing the elements from the original list while the predicate function returnstrue
. -
unlines
: This function concatenates a list of strings into a single string, with each string separated by a newline character. -
until
: This function takes a predicate function and a function that takes a value and returns a new value and applies the function repeatedly to the value until the predicate function returnstrue
.
In the main
function, the attractiveNumbers
function is called to generate a sequence of attractive numbers. The sequence is then filtered to include only numbers greater than or equal to 120 using the takeWhile
function. Finally, the showCols
function is used to format and display the attractive numbers in columns.
Source code in the javascript programming language
(() => {
'use strict';
// attractiveNumbers :: () -> Gen [Int]
const attractiveNumbers = () =>
// An infinite series of attractive numbers.
filter(
compose(isPrime, length, primeFactors)
)(enumFrom(1));
// ----------------------- TEST -----------------------
// main :: IO ()
const main = () =>
showCols(10)(
takeWhile(ge(120))(
attractiveNumbers()
)
);
// ---------------------- PRIMES ----------------------
// isPrime :: Int -> Bool
const isPrime = n => {
// True if n is prime.
if (2 === n || 3 === n) {
return true
}
if (2 > n || 0 === n % 2) {
return false
}
if (9 > n) {
return true
}
if (0 === n % 3) {
return false
}
return !enumFromThenTo(5)(11)(
1 + Math.floor(Math.pow(n, 0.5))
).some(x => 0 === n % x || 0 === n % (2 + x));
};
// primeFactors :: Int -> [Int]
const primeFactors = n => {
// A list of the prime factors of n.
const
go = x => {
const
root = Math.floor(Math.sqrt(x)),
m = until(
([q, _]) => (root < q) || (0 === (x % q))
)(
([_, r]) => [step(r), 1 + r]
)([
0 === x % 2 ? (
2
) : 3,
1
])[0];
return m > root ? (
[x]
) : ([m].concat(go(Math.floor(x / m))));
},
step = x => 1 + (x << 2) - ((x >> 1) << 1);
return go(n);
};
// ---------------- GENERIC FUNCTIONS -----------------
// chunksOf :: Int -> [a] -> [[a]]
const chunksOf = n =>
xs => enumFromThenTo(0)(n)(
xs.length - 1
).reduce(
(a, i) => a.concat([xs.slice(i, (n + i))]),
[]
);
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
const compose = (...fs) =>
fs.reduce(
(f, g) => x => f(g(x)),
x => x
);
// enumFrom :: Enum a => a -> [a]
function* enumFrom(x) {
// A non-finite succession of enumerable
// values, starting with the value x.
let v = x;
while (true) {
yield v;
v = 1 + v;
}
}
// enumFromThenTo :: Int -> Int -> Int -> [Int]
const enumFromThenTo = x1 =>
x2 => y => {
const d = x2 - x1;
return Array.from({
length: Math.floor(y - x2) / d + 2
}, (_, i) => x1 + (d * i));
};
// filter :: (a -> Bool) -> Gen [a] -> [a]
const filter = p => xs => {
function* go() {
let x = xs.next();
while (!x.done) {
let v = x.value;
if (p(v)) {
yield v
}
x = xs.next();
}
}
return go(xs);
};
// ge :: Ord a => a -> a -> Bool
const ge = x =>
// True if x >= y
y => x >= y;
// justifyRight :: Int -> Char -> String -> String
const justifyRight = n =>
// The string s, preceded by enough padding (with
// the character c) to reach the string length n.
c => s => n > s.length ? (
s.padStart(n, c)
) : s;
// last :: [a] -> a
const last = xs =>
// The last item of a list.
0 < xs.length ? xs.slice(-1)[0] : undefined;
// length :: [a] -> Int
const length = xs =>
// Returns Infinity over objects without finite
// length. This enables zip and zipWith to choose
// the shorter argument when one is non-finite,
// like cycle, repeat etc
(Array.isArray(xs) || 'string' === typeof xs) ? (
xs.length
) : Infinity;
// map :: (a -> b) -> [a] -> [b]
const map = f =>
// The list obtained by applying f
// to each element of xs.
// (The image of xs under f).
xs => (
Array.isArray(xs) ? (
xs
) : xs.split('')
).map(f);
// showCols :: Int -> [a] -> String
const showCols = w => xs => {
const
ys = xs.map(str),
mx = last(ys).length;
return unlines(chunksOf(w)(ys).map(
row => row.map(justifyRight(mx)(' ')).join(' ')
))
};
// str :: a -> String
const str = x =>
x.toString();
// takeWhile :: (a -> Bool) -> Gen [a] -> [a]
const takeWhile = p => xs => {
const ys = [];
let
nxt = xs.next(),
v = nxt.value;
while (!nxt.done && p(v)) {
ys.push(v);
nxt = xs.next();
v = nxt.value
}
return ys;
};
// unlines :: [String] -> String
const unlines = xs =>
// A single string formed by the intercalation
// of a list of strings with the newline character.
xs.join('\n');
// until :: (a -> Bool) -> (a -> a) -> a -> a
const until = p => f => x => {
let v = x;
while (!p(v)) v = f(v);
return v;
};
// MAIN ---
return main();
})();
You may also check:How to resolve the algorithm Literals/Integer step by step in the Kotlin programming language
You may also check:How to resolve the algorithm Thue-Morse step by step in the XLISP programming language
You may also check:How to resolve the algorithm Inheritance/Single step by step in the Clojure programming language
You may also check:How to resolve the algorithm Stern-Brocot sequence step by step in the Factor programming language
You may also check:How to resolve the algorithm Imaginary base numbers step by step in the C# programming language