How to resolve the algorithm Yellowstone sequence step by step in the JavaScript programming language
How to resolve the algorithm Yellowstone sequence step by step in the JavaScript programming language
Table of Contents
Problem Statement
The Yellowstone sequence, also called the Yellowstone permutation, is defined as: For n <= 3, For n >= 4,
The sequence is a permutation of the natural numbers, and gets its name from what its authors felt was a spiking, geyser like appearance of a plot of the sequence.
a(4) is 4 because 4 is the smallest number following 1, 2, 3 in the sequence that is relatively prime to the entry before it (3), and is not relatively prime to the number two entries before it (2).
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Yellowstone sequence step by step in the JavaScript programming language
This code is a JavaScript program that generates the Yellowstone sequence, which is a non-finite stream of terms in the Yellowstone permutation of the natural numbers. The Yellowstone permutation is an ordering of the natural numbers such that no two consecutive terms are relatively prime (i.e., have no common factors other than 1).
The program uses a generator function to produce the Yellowstone sequence. A generator function is a function that returns a generator object, which can be iterated over to produce a sequence of values. The generator function in this program uses a recursive algorithm to generate the Yellowstone sequence. The algorithm starts with a list of three numbers: 2, 3, and 4. It then repeatedly applies a transformation to the list to generate the next term in the sequence. The transformation involves finding the first number in the list that is relatively prime to the previous two numbers and adding it to the end of the list.
The program uses a number of helper functions to implement the Yellowstone sequence generator. The relativelyPrime
function checks if two numbers are relatively prime. The iterate
function creates a generator that repeatedly applies a function to a given value. The fmapGen
function applies a function to each element of a generator. The take
function takes the first n elements of a generator or list. The uncons
function extracts the first element of a list or generator, if it exists.
The main function of the program simply calls the Yellowstone sequence generator and prints the first 30 terms.
Here is a breakdown of the code:
- The
yellowstone
function is a generator function that generates the Yellowstone sequence. - The
relativelyPrime
function checks if two numbers are relatively prime. - The
main
function calls the Yellowstone sequence generator and prints the first 30 terms. - The
Just
andNothing
functions are used to represent optional values. - The
Tuple
function creates a tuple, which is a pair of values. - The
abs
function returns the absolute value of a number. - The
cons
function adds an element to the beginning of a list. - The
enumFrom
function creates a generator that generates a sequence of numbers starting from a given value. - The
fmapGen
function applies a function to each element of a generator. - The
gcd
function calculates the greatest common divisor of two numbers. - The
iterate
function creates a generator that repeatedly applies a function to a given value. - The
length
function returns the length of a list or generator. - The
secondArrow
function lifts a function over a simple value to a function over a tuple. - The
take
function takes the first n elements of a generator or list. - The
uncons
function extracts the first element of a list or generator, if it exists.
Source code in the javascript programming language
(() => {
'use strict';
// yellowstone :: Generator [Int]
function* yellowstone() {
// A non finite stream of terms in the
// Yellowstone permutation of the natural numbers.
// OEIS A098550
const nextWindow = ([p2, p1, rest]) => {
const [rp2, rp1] = [p2, p1].map(
relativelyPrime
);
const go = xxs => {
const [x, xs] = Array.from(
uncons(xxs).Just
);
return rp1(x) && !rp2(x) ? (
Tuple(x)(xs)
) : secondArrow(cons(x))(
go(xs)
);
};
return [p1, ...Array.from(go(rest))];
};
const A098550 = fmapGen(x => x[1])(
iterate(nextWindow)(
[2, 3, enumFrom(4)]
)
);
yield 1
yield 2
while (true)(
yield A098550.next().value
)
};
// relativelyPrime :: Int -> Int -> Bool
const relativelyPrime = a =>
// True if a is relatively prime to b.
b => 1 === gcd(a)(b);
// ------------------------TEST------------------------
const main = () => console.log(
take(30)(
yellowstone()
)
);
// -----------------GENERIC FUNCTIONS------------------
// Just :: a -> Maybe a
const Just = x => ({
type: 'Maybe',
Nothing: false,
Just: x
});
// Nothing :: Maybe a
const Nothing = () => ({
type: 'Maybe',
Nothing: true,
});
// Tuple (,) :: a -> b -> (a, b)
const Tuple = a =>
b => ({
type: 'Tuple',
'0': a,
'1': b,
length: 2
});
// abs :: Num -> Num
const abs =
// Absolute value of a given number - without the sign.
Math.abs;
// cons :: a -> [a] -> [a]
const cons = x =>
xs => Array.isArray(xs) ? (
[x].concat(xs)
) : 'GeneratorFunction' !== xs
.constructor.constructor.name ? (
x + xs
) : ( // cons(x)(Generator)
function*() {
yield x;
let nxt = xs.next()
while (!nxt.done) {
yield nxt.value;
nxt = xs.next();
}
}
)();
// 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;
}
}
// fmapGen <$> :: (a -> b) -> Gen [a] -> Gen [b]
const fmapGen = f =>
function*(gen) {
let v = take(1)(gen);
while (0 < v.length) {
yield(f(v[0]))
v = take(1)(gen)
}
};
// gcd :: Int -> Int -> Int
const gcd = x => y => {
const
_gcd = (a, b) => (0 === b ? a : _gcd(b, a % b)),
abs = Math.abs;
return _gcd(abs(x), abs(y));
};
// iterate :: (a -> a) -> a -> Gen [a]
const iterate = f =>
function*(x) {
let v = x;
while (true) {
yield(v);
v = f(v);
}
};
// 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;
// secondArrow :: (a -> b) -> ((c, a) -> (c, b))
const secondArrow = f => xy =>
// A function over a simple value lifted
// to a function over a tuple.
// f (a, b) -> (a, f(b))
Tuple(xy[0])(
f(xy[1])
);
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = n =>
// The first n elements of a list,
// string of characters, or stream.
xs => 'GeneratorFunction' !== xs
.constructor.constructor.name ? (
xs.slice(0, n)
) : [].concat.apply([], Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
// uncons :: [a] -> Maybe (a, [a])
const uncons = xs => {
// Just a tuple of the head of xs and its tail,
// Or Nothing if xs is an empty list.
const lng = length(xs);
return (0 < lng) ? (
Infinity > lng ? (
Just(Tuple(xs[0])(xs.slice(1))) // Finite list
) : (() => {
const nxt = take(1)(xs);
return 0 < nxt.length ? (
Just(Tuple(nxt[0])(xs))
) : Nothing();
})() // Lazy generator
) : Nothing();
};
// MAIN ---
return main();
})();
You may also check:How to resolve the algorithm Delegates step by step in the Vorpal programming language
You may also check:How to resolve the algorithm Echo server step by step in the Racket programming language
You may also check:How to resolve the algorithm Bulls and cows step by step in the REXX programming language
You may also check:How to resolve the algorithm URL parser step by step in the Ruby programming language
You may also check:How to resolve the algorithm Cholesky decomposition step by step in the Maple programming language