Metallic ratios

Many people have heard of the '''Golden ratio''', phi ('''φ'''). Phi is just one of a series
of related ratios that are referred to as the "'''Metallic ratios'''".

The '''Golden ratio''' was discovered and named by ancient civilizations as it was
thought to be the most pure and beautiful (like Gold). The '''Silver ratio''' was was
also known to the early Greeks, though was not named so until later as a nod to
the '''Golden ratio''' to which it is closely related. The series has been extended to
encompass all of the related ratios and was given the general name '''Metallic ratios''' (or ''Metallic means'').
''Somewhat incongruously as the original Golden ratio referred to the adjective "golden" rather than the metal "gold".''

'''Metallic ratios''' are the real roots of the general form equation:

          x2 - bx - 1 = 0

where the integer '''b''' determines which specific one it is.

Using the quadratic equation:

          ( -b ± √(b2 - 4ac) ) / 2a = x

Substitute in (from the top equation) '''1''' for '''a''', '''-1''' for '''c''', and recognising that -b is negated we get:

          ( b ± √(b2 + 4) ) ) / 2 = x

We only want the real root:

          ( b + √(b2 + 4) ) ) / 2 = x

When we set '''b''' to '''1''', we get an irrational number: the '''Golden ratio'''.

          ( 1 + √(12 + 4) ) / 2  =  (1 + √5) / 2 = ~1.618033989...

With '''b''' set to '''2''', we get a different irrational number: the '''Silver ratio'''.

          ( 2 + √(22 + 4) ) / 2  =  (2 + √8) / 2 = ~2.414213562...

When the ratio '''b''' is '''3''', it is commonly referred to as the '''Bronze''' ratio, '''4''' and '''5'''
are sometimes called the '''Copper''' and '''Nickel''' ratios, though they aren't as
standard. After that there isn't really any attempt at standardized names. They
are given names here on this page, but consider the names fanciful rather than
canonical.

Note that technically, '''b''' can be '''0''' for a "smaller" ratio than the '''Golden ratio'''.
We will refer to it here as the '''Platinum ratio''', though it is kind-of a
degenerate case.

'''Metallic ratios''' where '''b''' > '''0''' are also defined by the irrational continued fractions:

          [b;b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b...]

So, The first ten '''Metallic ratios''' are:

:::::: {| class="wikitable" style="text-align: center;"
|+ Metallic ratios
!Name!!'''b'''!!Equation!!Value!!Continued fraction!!OEIS link
|-
|Platinum||0||(0 + √4) / 2|| 1||-||-
|-
|Golden||1||(1 + √5) / 2|| 1.618033988749895...||[1;1,1,1,1,1,1,1,1,1,1...]||[[OEIS:A001622]]
|-
|Silver||2||(2 + √8) / 2|| 2.414213562373095...||[2;2,2,2,2,2,2,2,2,2,2...]||[[OEIS:A014176]]
|-
|Bronze||3||(3 + √13) / 2|| 3.302775637731995...||[3;3,3,3,3,3,3,3,3,3,3...]||[[OEIS:A098316]]
|-
|Copper||4||(4 + √20) / 2|| 4.23606797749979...||[4;4,4,4,4,4,4,4,4,4,4...]||[[OEIS:A098317]]
|-
|Nickel||5||(5 + √29) / 2|| 5.192582403567252...||[5;5,5,5,5,5,5,5,5,5,5...]||[[OEIS:A098318]]
|-
|Aluminum||6||(6 + √40) / 2|| 6.16227766016838...||[6;6,6,6,6,6,6,6,6,6,6...]||[[OEIS:A176398]]
|-
|Iron||7||(7 + √53) / 2|| 7.140054944640259...||[7;7,7,7,7,7,7,7,7,7,7...]||[[OEIS:A176439]]
|-
|Tin||8||(8 + √68) / 2|| 8.123105625617661...||[8;8,8,8,8,8,8,8,8,8,8...]||[[OEIS:A176458]]
|-
|Lead||9||(9 + √85) / 2|| 9.109772228646444...||[9;9,9,9,9,9,9,9,9,9,9...]||[[OEIS:A176522]]
|}

There are other ways to find the '''Metallic ratios'''; one, (the focus of this task)
is through '''successive approximations of Lucas sequences'''.

A traditional '''Lucas sequence''' is of the form:

    x''n'' = P * x''n-1'' - Q * x''n-2''

and starts with the first 2 values '''0, 1'''.

For our purposes in this task, to find the metallic ratios we'll use the form:

    x''n'' = b * x''n-1'' + x''n-2''

( '''P''' is set to '''b''' and '''Q''' is set to '''-1'''. ) To avoid "divide by zero" issues we'll start the sequence with the first two terms '''1, 1'''. The initial starting value has very little effect on the final ratio or convergence rate. ''Perhaps it would be more accurate to call it a Lucas-like sequence.''

At any rate, when '''b = 1''' we get:

    x''n'' = x''n-1'' + x''n-2''

    1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144...

more commonly known as the Fibonacci sequence.

When '''b = 2''':

    x''n'' = 2 * x''n-1'' + x''n-2''

    1, 1, 3, 7, 17, 41, 99, 239, 577, 1393...

And so on.

To find the ratio by successive approximations, divide the ('''n+1''')th term by the
'''n'''th. As '''n''' grows larger, the ratio will approach the '''b''' metallic ratio.

For '''b = 1''' (Fibonacci sequence):

    1/1   = 1
    2/1   = 2
    3/2   = 1.5
    5/3   = 1.666667
    8/5   = 1.6
    13/8  = 1.625
    21/13 = 1.615385
    34/21 = 1.619048
    55/34 = 1.617647
    89/55 = 1.618182
    etc.

It converges, but pretty slowly. In fact, the '''Golden ratio''' has the slowest
possible convergence for any irrational number.

;Task

For each of the first '''10 Metallic ratios'''; '''b''' = '''0''' through '''9''':

* Generate the corresponding "Lucas" sequence.
* Show here, on this page, at least the first '''15''' elements of the "Lucas" sequence.
* Using successive approximations, calculate the value of the ratio accurate to '''32''' decimal places.
* Show the '''value''' of the '''approximation''' at the required accuracy.
* Show the '''value''' of '''n''' when the approximation reaches the required accuracy (How many iterations did it take?).

Optional, stretch goal - Show the '''value''' and number of iterations '''n''', to approximate the '''Golden ratio''' to '''256''' decimal places.

You may assume that the approximation has been reached when the next iteration does not cause the value (to the desired places) to change.

;See also
* Wikipedia: Metallic mean
* Wikipedia: Lucas sequence

Solution:
from itertools import count, islice
from _pydecimal import getcontext, Decimal

def metallic_ratio(b):
    m, n = 1, 1
    while True:
        yield m, n
        m, n = m*b + n, m

def stable(b, prec):
    def to_decimal(b):
        for m,n in metallic_ratio(b):
            yield Decimal(m)/Decimal(n)

    getcontext().prec = prec
    last = 0
    for i,x in zip(count(), to_decimal(b)):
        if x == last:
            print(f'after {i} iterations:\n\t{x}')
            break
        last = x

for b in range(4):
    coefs = [n for _,n in islice(metallic_ratio(b), 15)]
    print(f'\nb = {b}: {coefs}')
    stable(b, 32)

print(f'\nb = 1 with 256 digits:')
stable(1, 256)


Metaprogramming

Name and briefly demonstrate any support your language has for metaprogramming. Your demonstration may take the form of cross-references to other tasks on Rosetta Code. When possible, provide links to relevant documentation.

For the purposes of this task, "support for metaprogramming" means any way the user can effectively modify the language's syntax that's built into the language (like Lisp macros) or that's conventionally used with the language (like the C preprocessor). Such facilities need not be very powerful: even user-defined infix operators count. On the other hand, in general, neither operator overloading nor eval count. The task author acknowledges that what qualifies as metaprogramming is largely a judgment call.

Solution:
#include

LIB_GADGET_START

void Muestra_archivo_original();

Main
   Assert (Exist_file("load_matrix.txt"), file_not_found);

   /* recupero informacion del archivo para su apertura segura */
   F_STAT dataFile = Stat_file("load_matrix.txt");
   Assert (dataFile.is_matrix, file_not_matrixable)  // tiene forma de matriz???

   New multitype test;

   /* The data range to be read is established.
      It is possible to read only part of the file using these ranges. */
   Range for test [0:1:dataFile.total_lines-1, 0:1:dataFile.max_tokens_per_line-1];

   /* cargamos el array detectando números enteros como long */
   test = Load_matrix_mt( pSDS(test), "load_matrix.txt", dataFile, DET_LONG);

   /* modifica algunas cosas del archivo */
   Let( $s-test[0,1], "Columna 1");
   $l-test[2,1] = 1000;
   $l-test[2,2] = 2000;

   /* inserto filas */
   /* preparo la fila a insertar */
   New multitype nueva_fila;
   sAppend_mt(nueva_fila,"fila 3.1");  /* sAppend_mt() and Append_mt() are macros */
   Append_mt(nueva_fila,float,0.0);
   Append_mt(nueva_fila,int,0);
   Append_mt(nueva_fila,double,0.0);
   Append_mt(nueva_fila,long, 0L);

   /* insertamos la misma fila en el array, 3 veces */
   test = Insert_row_mt(pSDS(test),pSDS(nueva_fila), 4);
   test = Insert_row_mt(pSDS(test),pSDS(nueva_fila), 4);
   test = Insert_row_mt(pSDS(test),pSDS(nueva_fila), 4);
   Free multitype nueva_fila;

   Print "\nGuardando archivo en \"save_matrix.txt\"...\n";
   DEC_PREC = 20; /* establece precision decimal */

   All range for test;
   Save_matrix_mt(SDS(test), "save_matrix.txt" );

   Free multitype test;

   Print "\nArchivo original:\n";
   Muestra_archivo_original();

   Exception( file_not_found ){
      Msg_red("File not found\n");
   }
   Exception( file_not_matrixable ){
      Msg_red("File is not matrixable\n");
   }

End

void Muestra_archivo_original(){
    String csys;
    csys = `cat load_matrix.txt`;
    Print "\n%s\n", csys;
    Free secure csys;
}


Metaprogramming

Solution:
Metaprogramming is frowned on in Python and considered un-pythonic. The only widely known example of metaprogramming in Python was an implementation of a goto (and comefrom) keyword done as an [http://entrian.com/goto/ April-fools joke].

Another more recent library that shows it can be done in Python is [https://github.com/lihaoyi/macropy MacroPy].


Metaprogramming

Solution:
from macropy.core.macros import *
from macropy.core.quotes import macros, q, ast, u

macros = Macros()

@macros.expr
def expand(tree, **kw):
    addition = 10
    return q[lambda x: x * ast[tree] + u[addition]]


Metronome

right

The task is to implement a   [https://en.wikipedia.org/wiki/Metronomemetronome metronome].

The metronome should be capable of producing high and low audio beats, accompanied by a visual beat indicator, and the beat pattern and tempo should be configurable.

For the purpose of this task, it is acceptable to play sound files for production of the beat notes, and an external player may be used.

However, the playing of the sounds should not interfere with the timing of the metronome.

The visual indicator can simply be a blinking red or green area of the screen (depending on whether a high or low beat is being produced), and the metronome can be implemented using a terminal display, or optionally, a graphical display, depending on the language capabilities.

If the language has no facility to output sound, then it is permissible for this to implemented using just the visual indicator.

Solution:
#include
#include
#include
#include
#include
#include
#include

struct timeval start, last;

inline int64_t tv_to_u(struct timeval s)
{
	return s.tv_sec * 1000000 + s.tv_usec;
}

inline struct timeval u_to_tv(int64_t x)
{
	struct timeval s;
	s.tv_sec = x / 1000000;
	s.tv_usec = x % 1000000;
	return s;
}

void draw(int dir, int64_t period, int64_t cur, int64_t next)
{
	int len = 40 * (next - cur) / period;
	int s, i;

	if (len > 20) len = 40 - len;
	s = 20 + (dir ? len : -len);

	printf("\033[H");
	for (i = 0; i <= 40; i++) putchar(i == 20 ? '|': i == s ? '#' : '-');
}

void beat(int delay)
{
	struct timeval tv = start;
	int dir = 0;
	int64_t d = 0, corr = 0, slp, cur, next = tv_to_u(start) + delay;
	int64_t draw_interval = 20000;
	printf("\033[H\033[J");
	while (1) {
		gettimeofday(&tv, 0);
		slp = next - tv_to_u(tv) - corr;
		usleep(slp);
		gettimeofday(&tv, 0);

		putchar(7); /* bell */
		fflush(stdout);

		printf("\033[5;1Hdrift: %d compensate: %d (usec)   ",
			(int)d, (int)corr);
		dir = !dir;

		cur = tv_to_u(tv);
		d = cur - next;
		corr = (corr + d) / 2;
		next += delay;

		while (cur + d + draw_interval < next) {
			usleep(draw_interval);
			gettimeofday(&tv, 0);
			cur = tv_to_u(tv);
			draw(dir, delay, cur, next);
			fflush(stdout);
		}
	}
}

int main(int c, char**v)
{
	int bpm;

	if (c < 2 || (bpm = atoi(v[1])) <= 0) bpm = 60;
	if (bpm > 600) {
		fprintf(stderr, "frequency %d too high\n", bpm);
		exit(1);
	}

	gettimeofday(&start, 0);
	last = start;
	beat(60 * 1000000 / bpm);

	return 0;
}


Metronome

Solution:
#lang Python
import time

def main(bpm = 72, bpb = 4):
    sleep = 60.0 / bpm
    counter = 0
    while True:
        counter += 1
        if counter % bpb:
            print 'tick'
        else:
            print 'TICK'
        time.sleep(sleep)

main()


Mian-Chowla sequence

The Mian–Chowla sequence is an integer sequence defined recursively.

Mian–Chowla is an infinite instance of a Sidon sequence, and belongs to the class known as B₂ sequences.

The sequence starts with:

::a1 = 1

then for n > 1, an is the smallest positive integer such that every pairwise sum

::ai + aj

is distinct, for all i and j less than or equal to n.

;The Task:

:* Find and display, here, on this page the first 30 terms of the Mian–Chowla sequence.
:* Find and display, here, on this page the 91st through 100th terms of the Mian–Chowla sequence.

Demonstrating working through the first few terms longhand:

::a1 = 1

::1 + 1 = 2

Speculatively try a2 = 2

::1 + 1 = 2
::1 + 2 = 3
::2 + 2 = 4

There are no repeated sums so '''2''' is the next number in the sequence.

Speculatively try a3 = 3

::1 + 1 = 2
::1 + 2 = 3
::1 + 3 = 4
::2 + 2 = 4
::2 + 3 = 5
::3 + 3 = 6

Sum of '''4''' is repeated so '''3''' is rejected.

Speculatively try a3 = 4

::1 + 1 = 2
::1 + 2 = 3
::1 + 4 = 5
::2 + 2 = 4
::2 + 4 = 6
::4 + 4 = 8

There are no repeated sums so '''4''' is the next number in the sequence.

And so on...

;See also:

:* OEIS:A005282 Mian-Chowla sequence

Solution:
#include
#include
#include

#define n 100
#define nn ((n * (n + 1)) >> 1)

bool Contains(int lst[], int item, int size) {
	for (int i = size - 1; i >= 0; i--)
 		if (item == lst[i]) return true;
	return false;
}

int * MianChowla()
{
	static int mc[n]; mc[0] = 1;
	int sums[nn];	sums[0] = 2;
	int sum, le, ss = 1;
	for (int i = 1; i < n; i++) {
		le = ss;
		for (int j = mc[i - 1] + 1; ; j++) {
			mc[i] = j;
			for (int k = 0; k <= i; k++) {
				sum = mc[k] + j;
				if (Contains(sums, sum, ss)) {
					ss = le; goto nxtJ;
				}
				sums[ss++] = sum;
			}
			break;
		nxtJ:;
		}
	}
	return mc;
}

int main() {
	clock_t st = clock(); int * mc; mc = MianChowla();
        double et = ((double)(clock() - st)) / CLOCKS_PER_SEC;
	printf("The first 30 terms of the Mian-Chowla sequence are:\n");
	for (int i = 0; i < 30; i++) printf("%d ", mc[i]);
	printf("\n\nTerms 91 to 100 of the Mian-Chowla sequence are:\n");
	for (int i = 90; i < 100; i++) printf("%d ", mc[i]);
	printf("\n\nComputation time was %f seconds.", et);
}


Mian-Chowla sequence

Solution:
(() => {
    'use strict';

    // main :: IO ()
    const main = () => {
        const genMianChowla = mianChowlas();
        console.log([
            'Mian-Chowla terms 1-30:',
            take(30)(
                genMianChowla
            ),

            '\nMian-Chowla terms 91-100:',
            (
                drop(60)(genMianChowla),
                take(10)(
                    genMianChowla
                )
            )
        ].join('\n') + '\n');
    };

    // mianChowlas :: Gen [Int]
    function* mianChowlas() {
        let
            mcs = [1],
            sumSet = new Set([2]),
            x = 1;
        while (true) {
            yield x;
            [sumSet, mcs, x] = nextMC(sumSet, mcs, x);
        }
    }

    // nextMC :: Set Int -> [Int] -> Int -> (Set Int, [Int], Int)
    const nextMC = (setSums, mcs, n) => {
        // Set of sums -> Series up to n -> Next term in series
        const valid = x => {
            for (const m of mcs) {
                if (setSums.has(x + m)) return false;
            }
            return true;
        };
        const x = until(valid)(x => 1 + x)(n);
        return [
            sumList(mcs)(x)
            .reduce(
                (a, n) => (a.add(n), a),
                setSums
            ),
            mcs.concat(x),
            x
        ];
    };

    // sumList :: [Int] -> Int -> [Int]
    const sumList = xs =>
        // Series so far -> additional term -> new sums
        n => [2 * n].concat(xs.map(x => n + x));

    // ---------------- GENERIC FUNCTIONS ----------------

    // drop :: Int -> [a] -> [a]
    // drop :: Int -> Generator [a] -> Generator [a]
    // drop :: Int -> String -> String
    const drop = n =>
        xs => Infinity > length(xs) ? (
            xs.slice(n)
        ) : (take(n)(xs), xs);

    // 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
        'GeneratorFunction' !== xs.constructor
        .constructor.name ? (
            xs.length
        ) : Infinity;

    // 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];
        }));

    // 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();
})();


Mian-Chowla sequence

Solution:
from itertools import count, islice, chain
import time

def mian_chowla():
    mc = [1]
    yield mc[-1]
    psums = set([2])
    newsums = set([])
    for trial in count(2):
        for n in chain(mc, [trial]):
            sum = n + trial
            if sum in psums:
                newsums.clear()
                break
            newsums.add(sum)
        else:
            psums |= newsums
            newsums.clear()
            mc.append(trial)
            yield trial

def pretty(p, t, s, f):
    print(p, t, " ".join(str(n) for n in (islice(mian_chowla(), s, f))))

if __name__ == '__main__':
    st = time.time()
    ts = "of the Mian-Chowla sequence are:\n"
    pretty("The first 30 terms", ts, 0, 30)
    pretty("\nTerms 91 to 100", ts, 90, 100)
    print("\nComputation time was", (time.time()-st) * 1000, "ms")


Middle three digits

;Task:
Write a function/procedure/subroutine that is called with an integer value and returns the middle three digits of the integer if possible or a clear indication of an error if this is not possible.

Note: The order of the middle digits should be preserved.

Your function should be tested with the following values; the first line should return valid answers, those of the second line should return clear indications of an error:

123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345
1, 2, -1, -10, 2002, -2002, 0

Show your output on this page.

Solution:
#include
#include
#include

void midThree(char arg[])
{
    char output[4];
    int midPoint;
    arg[0]=='-'?midPoint = ((strlen(arg) + 1) / 2):midPoint = ((strlen(arg) + 1) / 2) - 1;

    if(strlen(arg) < 3)
        {
            printf("Error, %d is too short.\n",atoi(arg));
            return ;
        }
        else if(strlen(arg)  == 4 || strlen(arg) == 3)
        {
            printf("Error, %d has %d digits, no 3 middle digits.\n",atoi(arg),arg[0]=='-'?strlen(arg)-1:strlen(arg));
            return ;
        }
    else{
    for(int i=0; i<3; i++)
    {
        output[i] = arg[(midPoint-1) + i];
    }
    output[3] = '\0';
    printf("The middle three digits of %s are %s.\n",arg,output);
}}

int main(int argc, char * argv[])
{
    char input[50];
    int x[] = {123, 12345, 1234567, 987654321, 10001, -10001,
		-123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0,
		1234567890},i;

    if(argc < 2)
    {
        printf("Usage: %s \n",argv[0]);
        printf("Examples with preloaded data shown below :\n");

        for(i=0;i<18;i++)
        {
	        midThree(itoa(x[i],argv[0],10));
	     }
        return 1;
    }
    else
    {
        sprintf(input,"%d",atoi(argv[1]));
            midThree(argv[1]);
            return 0;

    }
}


Middle three digits

Solution:
(() => {
    'use strict';

    // mid3digits :: Int -> Either String String
    const mid3digits = n => {
        const
            m = abs(n),
            s = m.toString();
        return 100 > m ? (
            Left('Less than 3 digits')
        ) : even(length(s)) ? (
            Left('Even digit count')
        ) : Right(take(3, drop(quot(length(s) - 3, 2), s)));
    };

    // TEST -----------------------------------------------
    const main = () => {
        const
            xs = [
                123, 12345, 1234567, 987654321, 10001, -10001, -123,
                -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0
            ],
            w = maximum(map(x => x.toString().length, xs));
        return (
            unlines(map(
                n => justifyRight(w, ' ', n.toString()) + ' -> ' +
                either(
                    s => '(' + s + ')',
                    id,
                    mid3digits(n)
                ),
                xs
            ))
        );
    };

    // GENERIC FUNCTIONS ----------------------------------

    // Left :: a -> Either a b
    const Left = x => ({
        type: 'Either',
        Left: x
    });

    // Right :: b -> Either a b
    const Right = x => ({
        type: 'Either',
        Right: x
    });

    // abs :: Num -> Num
    const abs = Math.abs;

    // drop :: Int -> [a] -> [a]
    // drop :: Int -> Generator [a] -> Generator [a]
    // drop :: Int -> String -> String
    const drop = (n, xs) =>
        Infinity > length(xs) ? (
            xs.slice(n)
        ) : (take(n, xs), xs);

    // either :: (a -> c) -> (b -> c) -> Either a b -> c
    const either = (fl, fr, e) =>
        'Either' === e.type ? (
            undefined !== e.Left ? (
                fl(e.Left)
            ) : fr(e.Right)
        ) : undefined;

    // even :: Int -> Bool
    const even = n => 0 === n % 2;

    // foldl1 :: (a -> a -> a) -> [a] -> a
    const foldl1 = (f, xs) =>
        1 < xs.length ? xs.slice(1)
        .reduce(f, xs[0]) : xs[0];

    // id :: a -> a
    const id = x => x;

    // justifyRight :: Int -> Char -> String -> String
    const justifyRight = (n, cFiller, s) =>
        n > s.length ? (
            s.padStart(n, cFiller)
        ) : s;

    // 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

    // length :: [a] -> Int
    const length = xs =>
        (Array.isArray(xs) || 'string' === typeof xs) ? (
            xs.length
        ) : Infinity;

    // maximum :: Ord a => [a] -> a
    const maximum = xs =>
        0 < xs.length ? (
            foldl1((a, x) => x > a ? x : a, xs)
        ) : undefined;

    // map :: (a -> b) -> [a] -> [b]
    const map = (f, xs) => xs.map(f);

    // quot :: Int -> Int -> Int
    const quot = (n, m) => Math.floor(n / m);

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = (n, 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];
        }));

    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');

    // MAIN ---
    return main();
})();


Middle three digits

Solution:
'''Middle 3 digits'''

# mid3digits :: Int -> Either String String
def mid3digits(n):
    '''Either the middle three digits,
       or an explanatory string.'''
    m = abs(n)
    s = str(m)
    return Left('Less than 3 digits') if (100 > m) else (
        Left('Even digit count') if even(len(s)) else Right(
            s[(len(s) - 3) // 2:][0:3]
        )
    )

# TEST ----------------------------------------------------
def main():
    '''Test'''

    def bracketed(x):
        return '(' + str(x) + ')'

    print(
        tabulated('Middle three digits, where defined:\n')(str)(
            either(bracketed)(str)
        )(mid3digits)([
            123, 12345, 1234567, 987654321, 10001, -10001, -123,
            -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0
        ])
    )

# GENERIC -------------------------------------------------

# Left :: a -> Either a b
def Left(x):
    '''Constructor for an empty Either (option type) value
       with an associated string.'''
    return {'type': 'Either', 'Right': None, 'Left': x}

# Right :: b -> Either a b
def Right(x):
    '''Constructor for a populated Either (option type) value'''
    return {'type': 'Either', 'Left': None, 'Right': x}

# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
def compose(g):
    '''Function composition.'''
    return lambda f: lambda x: g(f(x))

# either :: (a -> c) -> (b -> c) -> Either a b -> c
def either(fl):
    '''The application of fl to e if e is a Left value,
       or the application of fr to e if e is a Right value.'''
    return lambda fr: lambda e: fl(e['Left']) if (
        None is e['Right']
    ) else fr(e['Right'])

# even :: Int -> Bool
def even(x):
    '''Is x even ?'''
    return 0 == x % 2

# tabulated :: String -> (b -> String) -> (a -> b) -> [a] -> String
def tabulated(s):
    '''Heading -> x display function -> fx display function ->
                f -> value list -> tabular string.'''
    def go(xShow, fxShow, f, xs):
        w = max(map(compose(len)(str), xs))
        return s + '\n' + '\n'.join(
            xShow(x).rjust(w, ' ') + ' -> ' + fxShow(f(x)) for x in xs
        )
    return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
        xShow, fxShow, f, xs
    )

if __name__ == '__main__':
    main()


Mind boggling card trick

Matt Parker of the "Stand Up Maths channel" has a   [https://www.youtube.com/watch?v=aNpGxZ_1KXU YouTube video]   of a card trick that creates a semblance of order from chaos.

The task is to simulate the trick in a way that mimics the steps shown in the video.

; 1. Cards.
# Create a common deck of cards of 52 cards    (which are half red, half black).
# Give the pack a good shuffle.
; 2. Deal from the shuffled deck, you'll be creating three piles.
#   Assemble the cards face down.
##   Turn up the   ''top card''   and hold it in your hand.
###    if the card is         black,        then add the   ''next''   card (unseen) to the       "black"      pile.
###    If the card is     red,    then add the   ''next''   card (unseen) to the   "red"  pile.
##   Add the   ''top card''   that you're holding to the '''discard''' pile.   (You might optionally show these discarded cards to get an idea of the randomness).
# Repeat the above for the rest of the shuffled deck.
; 3. Choose a random number   (call it '''X''')   that will be used to swap cards from the "red" and "black" piles.
# Randomly choose   '''X'''   cards from the   "red"  pile (unseen), let's call this the   "red"  bunch.
# Randomly choose   '''X'''   cards from the       "black"      pile (unseen), let's call this the      "black"       bunch.
# Put the     "red"    bunch into the         "black"      pile.
# Put the        "black"        bunch into the      "red"  pile.
# (The above two steps complete the swap of   '''X'''   cards of the "red" and "black" piles.  (Without knowing what those cards are --- they could be red or black, nobody knows).
; 4. Order from randomness?
# Verify (or not) the mathematician's assertion that:
      '''The number of black cards in the "black" pile equals the number of red cards in the "red" pile.'''

(Optionally, run this simulation a number of times, gathering more evidence of the truthfulness of the assertion.)

Show output on this page.

Solution:
#include
#include
#include

#define SIM_N           5  /* Run 5 simulations */
#define PRINT_DISCARDED 1  /* Whether or not to print the discard pile */

#define min(x,y) ((x= n);
    return out;
}

/* Return a random card (0..51) from an uniform distribution */
card_t rand_card() {
    return rand_n(52);
}

/* Print a card */
void print_card(card_t card) {
    static char *suits = "HCDS"; /* hearts, clubs, diamonds and spades */
    static char *cards[] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
    printf(" %s%c", cards[card>>2], suits[card&3]);
}

/* Shuffle a pack */
void shuffle(card_t *pack) {
    int card;
    card_t temp, randpos;
    for (card=0; card<52; card++) {
        randpos = rand_card();
        temp = pack[card];
        pack[card] = pack[randpos];
        pack[randpos] = temp;
    }
}

/* Do the card trick, return whether cards match */
int trick() {
    card_t pack[52];
    card_t blacks[52/4], reds[52/4];
    card_t top, x, card;
    int blackn=0, redn=0, blacksw=0, redsw=0, result;

    /* Create and shuffle a pack */
    for (card=0; card<52; card++) pack[card] = card;
    shuffle(pack);

    /* Deal cards */
#if PRINT_DISCARDED
    printf("Discarded:"); /* Print the discard pile */
#endif
    for (card=0; card<52; card += 2) {
        top = pack[card]; /* Take card */
        if (top & 1) { /* Add next card to black or red pile */
            blacks[blackn++] = pack[card+1];
        } else {
            reds[redn++] = pack[card+1];
        }
#if PRINT_DISCARDED
        print_card(top); /* Show which card is discarded */
#endif
    }
#if PRINT_DISCARDED
    printf("\n");
#endif

    /* Swap an amount of cards */
    x = rand_n(min(blackn, redn));
    for (card=0; card


Mind boggling card trick

Solution:
import random

## 1. Cards
n = 52
Black, Red = 'Black', 'Red'
blacks = [Black] * (n // 2)
reds = [Red] * (n // 2)
pack = blacks + reds
# Give the pack a good shuffle.
random.shuffle(pack)

## 2. Deal from the randomised pack into three stacks
black_stack, red_stack, discard = [], [], []
while pack:
    top = pack.pop()
    if top == Black:
        black_stack.append(pack.pop())
    else:
        red_stack.append(pack.pop())
    discard.append(top)
print('(Discards:', ' '.join(d[0] for d in discard), ')\n')

## 3. Swap the same, random, number of cards between the two stacks.
# We can't swap more than the number of cards in a stack.
max_swaps = min(len(black_stack), len(red_stack))
# Randomly choose the number of cards to swap.
swap_count = random.randint(0, max_swaps)
print('Swapping', swap_count)
# Randomly choose that number of cards out of each stack to swap.
def random_partition(stack, count):
    "Partition the stack into 'count' randomly selected members and the rest"
    sample = random.sample(stack, count)
    rest = stack[::]
    for card in sample:
        rest.remove(card)
    return rest, sample

black_stack, black_swap = random_partition(black_stack, swap_count)
red_stack, red_swap = random_partition(red_stack, swap_count)

# Perform the swap.
black_stack += red_swap
red_stack += black_swap

## 4. Order from randomness?
if black_stack.count(Black) == red_stack.count(Red):
    print('Yeha! The mathematicians assertion is correct.')
else:
    print('Whoops - The mathematicians (or my card manipulations) are flakey')


Minimal steps down to 1

Given:
* A starting, positive integer (greater than one), N.
* A selection of possible integer perfect divisors, D.
* And a selection of possible subtractors, S.
The goal is find the minimum number of steps  necessary to reduce N down to one.

At any step, the number may be:
* Divided by any member of D if it is perfectly divided by D, (remainder zero).
* OR have one of S subtracted from it, if N is greater than the member of S.

There may be many ways to reduce the initial N down to 1. Your program needs to:
* Find the ''minimum'' number of ''steps'' to reach 1.
* Show '''one''' way of getting fron N to 1 in those minimum steps.

;Examples:
No divisors, D. a single subtractor of 1.
:Obviousely N will take N-1 subtractions of 1 to reach 1

Single divisor of 2; single subtractor of 1:
:N = 7 Takes 4 steps N -1=> 6, /2=> 3, -1=> 2, /2=> 1
:N = 23 Takes 7 steps N -1=>22, /2=>11, -1=>10, /2=> 5, -1=> 4, /2=> 2, /2=> 1

Divisors 2 and 3; subtractor 1:
:N = 11 Takes 4 steps N -1=>10, -1=> 9, /3=> 3, /3=> 1

;Task:
Using the possible divisors D, of 2 and 3; together with a possible subtractor S, of 1:

:1. Show the number of steps and possible way of diminishing the numbers 1 to 10 down to 1.
:2. Show a count of, and the numbers that: have the maximum minimal_steps_to_1, in the range 1 to 2,000.

Using the possible divisors D, of 2 and 3; together with a possible subtractor S, of 2:

:3. Show the number of steps and possible way of diminishing the numbers 1 to 10 down to 1.
:4. Show a count of, and the numbers that: have the maximum minimal_steps_to_1, in the range 1 to 2,000.

;Optional stretch goal:
:2a, and 4a: As in 2 and 4 above, but for N in the range 1 to 20_000

;Reference:
* [https://www.youtube.com/watch?v=f2xi3c1S95M Learn Dynamic Programming (Memoization & Tabulation)] Video of similar task.

Solution:
from functools import lru_cache

#%%

DIVS = {2, 3}
SUBS = {1}

class Minrec():
    "Recursive, memoised minimised steps to 1"

    def __init__(self, divs=DIVS, subs=SUBS):
        self.divs, self.subs = divs, subs

    @lru_cache(maxsize=None)
    def _minrec(self, n):
        "Recursive, memoised"
        if n == 1:
            return 0, ['=1']
        possibles = {}
        for d in self.divs:
            if n % d == 0:
                possibles[f'/{d}=>{n // d:2}'] = self._minrec(n // d)
        for s in self.subs:
            if n > s:
                possibles[f'-{s}=>{n - s:2}'] = self._minrec(n - s)
        thiskind, (count, otherkinds) = min(possibles.items(), key=lambda x: x[1])
        ret = 1 + count, [thiskind] + otherkinds
        return ret

    def __call__(self, n):
        "Recursive, memoised"
        ans = self._minrec(n)[1][:-1]
        return len(ans), ans

if __name__ == '__main__':
    for DIVS, SUBS in [({2, 3}, {1}), ({2, 3}, {2})]:
        minrec = Minrec(DIVS, SUBS)
        print('\nMINIMUM STEPS TO 1: Recursive algorithm')
        print('  Possible divisors:  ', DIVS)
        print('  Possible decrements:', SUBS)
        for n in range(1, 11):
            steps, how = minrec(n)
            print(f'    minrec({n:2}) in {steps:2} by: ', ', '.join(how))

        upto = 2000
        print(f'\n    Those numbers up to {upto} that take the maximum, "minimal steps down to 1":')
        stepn = sorted((minrec(n)[0], n) for n in range(upto, 0, -1))
        mx = stepn[-1][0]
        ans = [x[1] for x in stepn if x[0] == mx]
        print('      Taking', mx, f'steps is/are the {len(ans)} numbers:',
              ', '.join(str(n) for n in sorted(ans)))
        #print(minrec._minrec.cache_info())
        print()


Minimum multiple of m where digital sum equals m

Generate the sequence '''a(n)''' when each element is the minimum integer multiple '''m''' such that the digit sum of '''n''' times '''m''' is equal to '''n'''.

;Task

* Find the first 40 elements of the sequence.

;Stretch

* Find the next 30 elements of the sequence.

;See also

;* OEIS:A131382 - Minimal number m such that Sum_digits(n*m)=n

Solution:
#include

unsigned digit_sum(unsigned n) {
    unsigned sum = 0;
    do { sum += n % 10; }
    while(n /= 10);
    return sum;
}

unsigned a131382(unsigned n) {
    unsigned m;
    for (m = 1; n != digit_sum(m*n); m++);
    return m;
}

int main() {
    unsigned n;
    for (n = 1; n <= 70; n++) {
        printf("%9u", a131382(n));
        if (n % 10 == 0) printf("\n");
    }
    return 0;
}


Solution:
'''A131382'''

from itertools import count, islice

# a131382 :: [Int]
def a131382():
    '''An infinite series of the terms of A131382'''
    return (
        elemIndex(x)(
            productDigitSums(x)
        ) for x in count(1)
    )

# productDigitSums :: Int -> [Int]
def productDigitSums(n):
    '''The sum of the decimal digits of n'''
    return (digitSum(n * x) for x in count(0))

# ------------------------- TEST -------------------------
# main :: IO ()
def main():
    '''First 40 terms of A131382'''

    print(
        table(10)([
            str(x) for x in islice(
                a131382(),
                40
            )
        ])
    )

# ----------------------- GENERIC ------------------------

# chunksOf :: Int -> [a] -> [[a]]
def chunksOf(n):
    '''A series of lists of length n, subdividing the
       contents of xs. Where the length of xs is not evenly
       divisible, the final list will be shorter than n.
    '''
    def go(xs):
        return (
            xs[i:n + i] for i in range(0, len(xs), n)
        ) if 0 < n else None
    return go

# digitSum :: Int -> Int
def digitSum(n):
    '''The sum of the digital digits of n.
    '''
    return sum(int(x) for x in list(str(n)))

# elemIndex :: a -> [a] -> (None | Int)
def elemIndex(x):
    '''Just the first index of x in xs,
       or None if no elements match.
    '''
    def go(xs):
        try:
            return next(
                i for i, v in enumerate(xs) if x == v
            )
        except StopIteration:
            return None
    return go

# table :: Int -> [String] -> String
def table(n):
    '''A list of strings formatted as
       right-justified rows of n columns.
    '''
    def go(xs):
        w = len(xs[-1])
        return '\n'.join(
            ' '.join(row) for row in chunksOf(n)([
                s.rjust(w, ' ') for s in xs
            ])
        )
    return go

# MAIN ---
if __name__ == '__main__':
    main()


Minimum positive multiple in base 10 using only 0 and 1

Every positive integer has infinitely many base-10 multiples that only use the digits '''0''' and '''1'''. The goal of this task is to find and display the '''minimum''' multiple that has this property.

This is simple to do, but can be challenging to do efficiently.

To avoid repeating long, unwieldy phrases, the operation "minimum positive multiple of a positive integer n in base 10 that only uses the digits 0 and 1" will hereafter be referred to as "'''B10'''".

;Task:

Write a routine to find the B10 of a given integer.

E.G.

       '''n'''                  '''B10'''      '''n'''  × '''multiplier'''
       1                    1    ( 1  × 1         )
       2                   10    ( 2  × 5         )
       7                 1001    ( 7  x 143       )
       9            111111111    ( 9  x 12345679  )
      10                   10    ( 10 x 1         )

and so on.

Use the routine to find and display here, on this page, the '''B10''' value for:

    1 through 10, 95 through 105, 297, 576, 594, 891, 909, 999

Optionally find '''B10''' for:

    1998, 2079, 2251, 2277

Stretch goal; find '''B10''' for:

    2439, 2997, 4878

There are many opportunities for optimizations, but avoid using magic numbers as much as possible. If you ''do'' use magic numbers, explain briefly why and what they do for your implementation.

;See also:

:* OEIS:A004290 Least positive multiple of n that when written in base 10 uses only 0's and 1's.
:* [https://math.stackexchange.com/questions/388165/how-to-find-the-smallest-number-with-just-0-and-1-which-is-divided-by-a-give How to find Minimum Positive Multiple in base 10 using only 0 and 1]

Solution:
#include
#include
#include
#include

__int128 imax(__int128 a, __int128 b) {
    if (a > b) {
        return a;
    }
    return b;
}

__int128 ipow(__int128 b, __int128 n) {
    __int128 res;
    if (n == 0) {
        return 1;
    }
    if (n == 1) {
        return b;
    }
    res = b;
    while (n > 1) {
        res *= b;
        n--;
    }
    return res;
}

__int128 imod(__int128 m, __int128 n) {
    __int128 result = m % n;
    if (result < 0) {
        result += n;
    }
    return result;
}

bool valid(__int128 n) {
    if (n < 0) {
        return false;
    }
    while (n > 0) {
        int r = n % 10;
        if (r > 1) {
            return false;
        }
        n /= 10;
    }
    return true;
}

__int128 mpm(const __int128 n) {
    __int128 *L;
    __int128 m, k, r, j;

    if (n == 1) {
        return 1;
    }

    L = calloc(n * n, sizeof(__int128));
    L[0] = 1;
    L[1] = 1;
    m = 0;
    while (true) {
        m++;
        if (L[(m - 1) * n + imod(-ipow(10, m), n)] == 1) {
            break;
        }
        L[m * n + 0] = 1;
        for (k = 1; k < n; k++) {
            L[m * n + k] = imax(L[(m - 1) * n + k], L[(m - 1) * n + imod(k - ipow(10, m), n)]);
        }
    }

    r = ipow(10, m);
    k = imod(-r, n);

    for (j = m - 1; j >= 1; j--) {
        if (L[(j - 1) * n + k] == 0) {
            r = r + ipow(10, j);
            k = imod(k - ipow(10, j), n);
        }
    }

    if (k == 1) {
        r++;
    }
    return r / n;
}

void print128(__int128 n) {
    char buffer[64]; // more then is needed, but is nice and round;
    int pos = (sizeof(buffer) / sizeof(char)) - 1;
    bool negative = false;

    if (n < 0) {
        negative = true;
        n = -n;
    }

    buffer[pos] = 0;
    while (n > 0) {
        int rem = n % 10;
        buffer[--pos] = rem + '0';
        n /= 10;
    }
    if (negative) {
        buffer[--pos] = '-';
    }
    printf(&buffer[pos]);
}

void test(__int128 n) {
    __int128 mult = mpm(n);
    if (mult > 0) {
        print128(n);
        printf(" * ");
        print128(mult);
        printf(" = ");
        print128(n * mult);
        printf("\n");
    } else {
        print128(n);
        printf("(no solution)\n");
    }
}

int main() {
    int i;

    // 1-10 (inclusive)
    for (i = 1; i <= 10; i++) {
        test(i);
    }
    // 95-105 (inclusive)
    for (i = 95; i <= 105; i++) {
        test(i);
    }
    test(297);
    test(576);
    test(594); // needs a larger number type (64 bits signed)
    test(891);
    test(909);
    test(999); // needs a larger number type (87 bits signed)

    // optional
    test(1998);
    test(2079);
    test(2251);
    test(2277);

    // stretch
    test(2439);
    test(2997);
    test(4878);

    return 0;
}


Solution:
def getA004290(n):
    if n < 2:
        return 1
    arr = [[0 for _ in range(n)] for _ in range(n)]
    arr[0][0] = 1
    arr[0][1] = 1
    m = 0
    while True:
        m += 1
        if arr[m - 1][-10 ** m % n] == 1:
            break
        arr[m][0] = 1
        for k in range(1, n):
            arr[m][k] = max([arr[m - 1][k], arr[m - 1][k - 10 ** m % n]])
    r = 10 ** m
    k = -r % n
    for j in range((m - 1), 0, -1):
        if arr[j - 1][k] == 0:
            r = r + 10 ** j
            k = (k - 10 ** j) % n
    if k == 1:
        r += 1
    return r

for n in [i for i in range(1, 11)] + \
          [i for i in range(95, 106)] + \
          [297, 576, 594, 891, 909, 999, 1998, 2079, 2251, 2277, 2439, 2997, 4878]:
    result = getA004290(n)
    print(f"A004290({n}) = {result} = {n} * {result // n})")


Minkowski question-mark function

The '''Minkowski question-mark function''' converts the continued fraction representation {{math|[a0; a1, a2, a3, ...]}} of a number into a binary decimal representation in which the integer part {{math|a0}} is unchanged and the {{math|a1, a2, ...}} become alternating runs of binary zeroes and ones of those lengths. The decimal point takes the place of the first zero.

Thus, {{math|?}}(31/7) = 71/16 because 31/7 has the continued fraction representation {{math|[4;2,3]}} giving the binary expansion {{math|4 + 0.01112}}.

Among its interesting properties is that it maps roots of quadratic equations, which have repeating continued fractions, to rational numbers, which have repeating binary digits.

The question-mark function is continuous and monotonically increasing, so it has an inverse.

* Produce a function for {{math|?(x)}}.   Be careful: rational numbers have two possible continued fraction representations:
:::*   {{math|[a0;a1,... an−1,an]}}      and
:::*   {{math|[a0;a1,... an−1,an−1,1]}}
* Choose one of the above that will give a binary expansion ending with a   '''1'''.
* Produce the inverse function {{math|?-1(x)}}
* Verify that {{math|?(φ)}} = 5/3, where {{math|φ}} is the Greek golden ratio.
* Verify that {{math|?-1(-5/9)}} = (√13 - 7)/6
* Verify that the two functions are inverses of each other by showing that {{math|?-1(?(x))}}={{math|x}} and {{math|?(?-1(y))}}={{math|y}} for {{math|x, y}} of your choice

Don't worry about precision error in the last few digits.

;See also:
* Wikipedia entry: Minkowski's question-mark function

Solution:
import math

MAXITER = 151

def minkowski(x):
    if x > 1 or x < 0:
        return math.floor(x) + minkowski(x - math.floor(x))

    p = int(x)
    q = 1
    r = p + 1
    s = 1
    d = 1.0
    y = float(p)

    while True:
        d /= 2
        if y + d == y:
            break

        m = p + r
        if m < 0 or p < 0:
            break

        n = q + s
        if n < 0:
            break

        if x < m / n:
            r = m
            s = n
        else:
            y += d
            p = m
            q = n

    return y + d

def minkowski_inv(x):
    if x > 1 or x < 0:
        return math.floor(x) + minkowski_inv(x - math.floor(x))

    if x == 1 or x == 0:
        return x

    cont_frac = [0]
    current = 0
    count = 1
    i = 0

    while True:
        x *= 2

        if current == 0:
            if x < 1:
                count += 1
            else:
                cont_frac.append(0)
                cont_frac[i] = count

                i += 1
                count = 1
                current = 1
                x -= 1
        else:
            if x > 1:
                count += 1
                x -= 1
            else:
                cont_frac.append(0)
                cont_frac[i] = count

                i += 1
                count = 1
                current = 0

        if x == math.floor(x):
            cont_frac[i] = count
            break

        if i == MAXITER:
            break

    ret = 1.0 / cont_frac[i]
    for j in range(i - 1, -1, -1):
        ret = cont_frac[j] + 1.0 / ret

    return 1.0 / ret

if __name__ == "__main__":
    print(
        "{:19.16f} {:19.16f}".format(
            minkowski(0.5 * (1 + math.sqrt(5))),
            5.0 / 3.0,
        )
    )

    print(
        "{:19.16f} {:19.16f}".format(
            minkowski_inv(-5.0 / 9.0),
            (math.sqrt(13) - 7) / 6,
        )
    )

    print(
        "{:19.16f} {:19.16f}".format(
            minkowski(minkowski_inv(0.718281828)),
            minkowski_inv(minkowski(0.1213141516171819)),
        )
    )


Modified random distribution

Given a random number generator, (rng), generating numbers in the range 0.0 .. 1.0 called rgen, for example; and a function modifier(x)
taking an number in the same range and generating the probability that the input should be generated, in the same range 0..1; then implement the following algorithm for generating random numbers to the probability given by  function modifier:
while True:
    random1 = rgen()
    random2 = rgen()
    if random2 < modifier(random1):
        answer = random1
        break
    endif
endwhile

;Task:
* Create a modifier function that generates a 'V' shaped probability of number generation using something like, for example:
                       modifier(x)  =  2*(0.5 - x)  if x < 0.5  else 2*(x - 0.5)
* Create a generator of random numbers with probabilities modified by the above function.
* Generate >= 10,000 random numbers subject to the probability modification.
* Output a textual histogram with from 11 to 21 bins showing the distribution of the random numbers generated.

Show your output here, on this page.

Solution:
import random
from typing import List, Callable, Optional

def modifier(x: float) -> float:
    """
    V-shaped, modifier(x) goes from 1 at 0 to 0 at 0.5 then back to 1 at 1.0 .

    Parameters
    ----------
    x : float
        Number, 0.0 .. 1.0 .

    Returns
    -------
    float
        Target probability for generating x; between 0 and 1.

    """
    return 2*(.5 - x) if x < 0.5 else 2*(x - .5)

def modified_random_distribution(modifier: Callable[[float], float],
                                 n: int) -> List[float]:
    """
    Generate n random numbers between 0 and 1 subject to modifier.

    Parameters
    ----------
    modifier : Callable[[float], float]
        Target random number gen. 0 <= modifier(x) < 1.0 for 0 <= x < 1.0 .
    n : int
        number of random numbers generated.

    Returns
    -------
    List[float]
        n random numbers generated with given probability.

    """
    d: List[float] = []
    while len(d) < n:
        r1 = prob = random.random()
        if random.random() < modifier(prob):
            d.append(r1)
    return d

if __name__ == '__main__':
    from collections import Counter

    data = modified_random_distribution(modifier, 50_000)
    bins = 15
    counts = Counter(d // (1 / bins) for d in data)
    #
    mx = max(counts.values())
    print("   BIN, COUNTS, DELTA: HISTOGRAM\n")
    last: Optional[float] = None
    for b, count in sorted(counts.items()):
        delta = 'N/A' if last is None else str(count - last)
        print(f"  {b / bins:5.2f},  {count:4},  {delta:>4}: "
              f"{'#' * int(40 * count / mx)}")
        last = count


Modular arithmetic

'''equivalence relation called ''congruence''.

For any positive integer p called the ''congruence modulus'',
two numbers a and b are said to be ''congruent modulo p'' whenever there exists an integer k such that:
:a = b + k\,p

The corresponding set of multiplicative inverse for this task.

Addition and multiplication on this ring have the same algebraic structure as in usual arithmetic, so that a function such as a polynomial expression could receive a ring element as argument and give a consistent result.

The purpose of this task is to show, if your programming language allows it,
how to redefine operators so that they can be used transparently on modular integers.
You can do it either by using a dedicated library, or by implementing your own class.

You will use the following function for demonstration:
:f(x) = x^{100} + x + 1
You will use 13 as the congruence modulus and you will compute f(10).

It is important that the function f is agnostic about whether or not its argument is modular; it should behave the same way with normal and modular integers.
In other words, the function is an algebraic expression that could be used with any ring, not just integers.

Solution:
#include

struct ModularArithmetic {
    int value;
    int modulus;
};

struct ModularArithmetic make(const int value, const int modulus) {
    struct ModularArithmetic r = { value % modulus, modulus };
    return r;
}

struct ModularArithmetic add(const struct ModularArithmetic a, const struct ModularArithmetic b) {
    return make(a.value + b.value, a.modulus);
}

struct ModularArithmetic addi(const struct ModularArithmetic a, const int v) {
    return make(a.value + v, a.modulus);
}

struct ModularArithmetic mul(const struct ModularArithmetic a, const struct ModularArithmetic b) {
    return make(a.value * b.value, a.modulus);
}

struct ModularArithmetic pow(const struct ModularArithmetic b, int pow) {
    struct ModularArithmetic r = make(1, b.modulus);
    while (pow-- > 0) {
        r = mul(r, b);
    }
    return r;
}

void print(const struct ModularArithmetic v) {
    printf("ModularArithmetic(%d, %d)", v.value, v.modulus);
}

struct ModularArithmetic f(const struct ModularArithmetic x) {
    return addi(add(pow(x, 100), x), 1);
}

int main() {
    struct ModularArithmetic input = make(10, 13);
    struct ModularArithmetic output = f(input);

    printf("f(");
    print(input);
    printf(") = ");
    print(output);
    printf("\n");

    return 0;
}


Modular arithmetic

Solution:
import operator
import functools

@functools.total_ordering
class Mod:
    __slots__ = ['val','mod']

    def __init__(self, val, mod):
        if not isinstance(val, int):
            raise ValueError('Value must be integer')
        if not isinstance(mod, int) or mod<=0:
            raise ValueError('Modulo must be positive integer')
        self.val = val % mod
        self.mod = mod

    def __repr__(self):
        return 'Mod({}, {})'.format(self.val, self.mod)

    def __int__(self):
        return self.val

    def __eq__(self, other):
        if isinstance(other, Mod):
            if self.mod == other.mod:
                return self.val==other.val
            else:
                return NotImplemented
        elif isinstance(other, int):
            return self.val == other
        else:
            return NotImplemented

    def __lt__(self, other):
        if isinstance(other, Mod):
            if self.mod == other.mod:
                return self.val


Modular exponentiation

Find the last   '''40'''   decimal digits of   a^b,   where

::*   a = 2988348162058574136915891421498819466320163312926952423791023078876139
::*   b = 2351399303373464486466122544523690094744975233415544072992656881240319

A computer is too slow to find the entire value of   a^b.

Instead, the program must use a fast algorithm for modular exponentiation:   a^b \mod m.

The algorithm must work for any integers   a, b, m,     where   b \ge 0   and   m > 0.

Solution:
#include

int main()
{
	mpz_t a, b, m, r;

	mpz_init_set_str(a,	"2988348162058574136915891421498819466320"
				"163312926952423791023078876139", 0);
	mpz_init_set_str(b,	"2351399303373464486466122544523690094744"
				"975233415544072992656881240319", 0);
	mpz_init(m);
	mpz_ui_pow_ui(m, 10, 40);

	mpz_init(r);
	mpz_powm(r, a, b, m);

	gmp_printf("%Zd\n", r); /* ...16808958343740453059 */

	mpz_clear(a);
	mpz_clear(b);
	mpz_clear(m);
	mpz_clear(r);

	return 0;
}


Modular exponentiation

Solution:
a = 2988348162058574136915891421498819466320163312926952423791023078876139
b = 2351399303373464486466122544523690094744975233415544072992656881240319
m = 10 ** 40
print(pow(a, b, m))


Modular inverse

From [http://en.wikipedia.org/wiki/Modular_multiplicative_inverse Wikipedia]:

In modulo    ''m''    is an integer    ''x''    such that

::a\,x \equiv 1 \pmod{m}.

Or in other words, such that:

::\exists k \in\Z,\qquad a\, x = 1 + k\,m

It can be shown that such an inverse exists   if and only if    ''a''    and    ''m''    are coprime,   but we will ignore this for this task.

;Task:
Either by implementing the algorithm, by using a dedicated library or by using a built-in function in
your language,   compute the modular inverse of   42 modulo 2017.

Solution:
#include

int mul_inv(int a, int b)
{
        int t, nt, r, nr, q, tmp;
        if (b < 0) b = -b;
        if (a < 0) a = b - (-a % b);
        t = 0;  nt = 1;  r = b;  nr = a % b;
        while (nr != 0) {
          q = r/nr;
          tmp = nt;  nt = t - q*nt;  t = tmp;
          tmp = nr;  nr = r - q*nr;  r = tmp;
        }
        if (r > 1) return -1;  /* No inverse */
        if (t < 0) t += b;
        return t;
}
int main(void) {
        printf("%d\n", mul_inv(42, 2017));
        printf("%d\n", mul_inv(40, 1));
        printf("%d\n", mul_inv(52, -217));  /* Pari semantics for negative modulus */
        printf("%d\n", mul_inv(-486, 217));
        printf("%d\n", mul_inv(40, 2018));
        return 0;
}


Modular inverse

Solution:
var modInverse = function(a, b) {
    a %= b;
    for (var x = 1; x < b; x++) {
        if ((a*x)%b == 1) {
            return x;
        }
    }
}


Modular inverse

Solution:
from functools import (reduce)
from itertools import (chain)

# modInv :: Int -> Int -> Maybe Int
def modInv(a):
    return lambda m: (
        lambda ig=gcdExt(a)(m): (
            lambda i=ig[0]: (
                Just(i + m if 0 > i else i) if 1 == ig[2] else (
                    Nothing()
                )
            )
        )()
    )()

# gcdExt :: Int -> Int -> (Int, Int, Int)
def gcdExt(x):
    def go(a, b):
        if 0 == b:
            return (1, 0, a)
        else:
            (q, r) = divmod(a, b)
            (s, t, g) = go(b, r)
        return (t, s - q * t, g)
    return lambda y: go(x, y)

#  TEST ---------------------------------------------------

# Numbers between 2010 and 2015 which do yield modular inverses for 42:

# main :: IO ()
def main():
    print (
        mapMaybe(
            lambda y: bindMay(modInv(42)(y))(
                lambda mInv: Just((y, mInv))
            )
        )(
            enumFromTo(2010)(2025)
        )
    )

# -> [(2011, 814), (2015, 48), (2017, 1969), (2021, 1203)]

# GENERIC ABSTRACTIONS ------------------------------------

# enumFromTo :: Int -> Int -> [Int]
def enumFromTo(m):
    return lambda n: list(range(m, 1 + n))

# bindMay (>>=) :: Maybe  a -> (a -> Maybe b) -> Maybe b
def bindMay(m):
    return lambda mf: (
        m if m.get('Nothing') else mf(m.get('Just'))
    )

# Just :: a -> Maybe a
def Just(x):
    return {'type': 'Maybe', 'Nothing': False, 'Just': x}

# mapMaybe :: (a -> Maybe b) -> [a] -> [b]
def mapMaybe(mf):
    return lambda xs: reduce(
        lambda a, x: maybe(a)(lambda j: a + [j])(mf(x)),
        xs,
        []
    )

# maybe :: b -> (a -> b) -> Maybe a -> b
def maybe(v):
    return lambda f: lambda m: v if m.get('Nothing') else (
        f(m.get('Just'))
    )

# Nothing :: Maybe a
def Nothing():
    return {'type': 'Maybe', 'Nothing': True}

# MAIN ---
main()


Monads/List monad

[[Category:Monads]]

A Monad is a combination of a data-type with two helper functions written for that type.

The data-type can be of any kind which can contain values of some other type – common examples are lists, records, sum-types, even functions or IO streams. The two special functions, mathematically known as '''eta''' and '''mu''', but usually given more expressive names like 'pure', 'return', or 'yield' and 'bind', abstract away some boilerplate needed for pipe-lining or enchaining sequences of computations on values held in the containing data-type.

The bind operator in the List monad enchains computations which return their values wrapped in lists. One application of this is the representation of indeterminacy, with returned lists representing a set of possible values. An empty list can be returned to express incomputability, or computational failure.

A sequence of two list monad computations (enchained with the use of bind) can be understood as the computation of a cartesian product.

The natural implementation of bind for the List monad is a composition of '''concat''' and '''map''', which, used with a function which returns its value as a (possibly empty) list, provides for filtering in addition to transformation or mapping.

Demonstrate in your programming language the following:

#Construct a List Monad by writing the 'bind' function and the 'pure' (sometimes known as 'return') function for that Monad (or just use what the language already has implemented)
#Make two functions, each which take a number and return a monadic number, e.g. Int -> List Int and Int -> List String
#Compose the two functions with bind

Solution:
#include
#include

#define MONAD void*
#define INTBIND(f, g, x) (f((int*)g(x)))
#define RETURN(type,x) &((type)*)(x)

MONAD boundInt(int *x) {
    return (MONAD)(x);
}

MONAD boundInt2str(int *x) {
    char buf[100];
    char*str= malloc(1+sprintf(buf, "%d", *x));
    sprintf(str, "%d", *x);
    return (MONAD)(str);
}

void task(int y) {
    char *z= INTBIND(boundInt2str, boundInt, &y);
    printf("%s\n", z);
    free(z);
}

int main() {
    task(13);
}


Monads/List monad

Solution:
"""A List Monad. Requires Python >= 3.7 for type hints."""
from __future__ import annotations
from itertools import chain

from typing import Any
from typing import Callable
from typing import Iterable
from typing import List
from typing import TypeVar

T = TypeVar("T")

class MList(List[T]):
    @classmethod
    def unit(cls, value: Iterable[T]) -> MList[T]:
        return cls(value)

    def bind(self, func: Callable[[T], MList[Any]]) -> MList[Any]:
        return MList(chain.from_iterable(map(func, self)))

    def __rshift__(self, func: Callable[[T], MList[Any]]) -> MList[Any]:
        return self.bind(func)

if __name__ == "__main__":
    # Chained int and string functions
    print(
        MList([1, 99, 4])
        .bind(lambda val: MList([val + 1]))
        .bind(lambda val: MList([f"${val}.00"]))
    )

    # Same, but using `>>` as the bind operator.
    print(
        MList([1, 99, 4])
        >> (lambda val: MList([val + 1]))
        >> (lambda val: MList([f"${val}.00"]))
    )

    # Cartesian product of [1..5] and [6..10]
    print(
        MList(range(1, 6)).bind(
            lambda x: MList(range(6, 11)).bind(lambda y: MList([(x, y)]))
        )
    )

    # Pythagorean triples with elements between 1 and 25
    print(
        MList(range(1, 26)).bind(
            lambda x: MList(range(x + 1, 26)).bind(
                lambda y: MList(range(y + 1, 26)).bind(
                    lambda z: MList([(x, y, z)])
                    if x * x + y * y == z * z
                    else MList([])
                )
            )
        )
    )


Monads/Maybe monad

[[Category:Monads]]
Demonstrate in your programming language the following:

#Construct a Maybe Monad by writing the 'bind' function and the 'unit' (sometimes known as 'return') function for that Monad (or just use what the language already has implemented)
#Make two functions, each which take a number and return a monadic number, e.g. Int -> Maybe Int and Int -> Maybe String
#Compose the two functions with bind

A Monad is a single type which encapsulates several other types, eliminating boilerplate code. In practice it acts like a dynamically typed computational sequence, though in many cases the type issues can be resolved at compile time.

A Maybe Monad is a monad which specifically encapsulates the type of an undefined value.

Solution:
#include
#include
#include

typedef enum type
{
  INT,
  STRING
} Type;

typedef struct maybe
{
  int i;
  char *s;
  Type t;
  _Bool is_something;
} Maybe;

void print_Maybe(Maybe *m)
{
  if (m->t == INT)
    printf("Just %d : INT\n", m->i);

  else if (m->t == STRING)
    printf("Just \"%s\" : STRING\n", m->s);

  else
    printf("Nothing\n");

}

Maybe *return_maybe(void *data, Type t)
{
  Maybe *m = malloc(sizeof(Maybe));
  if (t == INT)
  {
    m->i = *(int *) data;
    m->s = NULL;
    m->t = INT;
    m->is_something = true;
  }

  else if (t == STRING)
  {
    m->i = 0;
    m->s = data;
    m->t = STRING;
    m->is_something = true;
  }

  else
  {
    m->i = 0;
    m->s = NULL;
    m->t = 0;
    m->is_something = false;
  }

  return m;
}

Maybe *bind_maybe(Maybe *m, Maybe *(*f)(void *))
{
  Maybe *n = malloc(sizeof(Maybe));

  if (f(&(m->i))->is_something)
  {
    n->i = f(&(m->i))->i;
    n->s = f(&(m->i))->s;
    n->t = f(&(m->i))->t;
    n->is_something = true;
  }

  else
  {
    n->i = 0;
    n->s = NULL;
    n->t = 0;
    n->is_something = false;
  }
  return n;
}

Maybe *f_1(void *v) // Int -> Maybe Int
{
  Maybe *m = malloc(sizeof(Maybe));
  m->i = (*(int *) v) * (*(int *) v);
  m->s = NULL;
  m->t = INT;
  m->is_something = true;
  return m;
}

Maybe *f_2(void *v) // :: Int -> Maybe String
{
  Maybe *m = malloc(sizeof(Maybe));
  m->i = 0;
  m->s = malloc(*(int *) v * sizeof(char) + 1);
  for (int i = 0; i < *(int *) v; i++)
  {
    m->s[i] = 'x';
  }
  m->s[*(int *) v + 1] = '\0';
  m->t = STRING;
  m->is_something = true;
  return m;
}

int main()
{
  int i = 7;
  char *s = "lorem ipsum dolor sit amet";

  Maybe *m_1 = return_maybe(&i, INT);
  Maybe *m_2 = return_maybe(s, STRING);

  print_Maybe(m_1); // print value of m_1: Just 49
  print_Maybe(m_2); // print value of m_2 : Just "lorem ipsum dolor sit amet"

  print_Maybe(bind_maybe(m_1, f_1)); // m_1 `bind` f_1 :: Maybe Int
  print_Maybe(bind_maybe(m_1, f_2)); // m_1 `bind` f_2 :: Maybe String

  print_Maybe(bind_maybe(bind_maybe(m_1, f_1), f_2)); // (m_1 `bind` f_1) `bind` f_2 :: Maybe String -- it prints 49 'x' characters in a row
}


Monads/Maybe monad

Solution:
(function () {
    'use strict';

    // START WITH SOME SIMPLE (UNSAFE) PARTIAL FUNCTIONS:

    // Returns Infinity if n === 0
    function reciprocal(n) {
        return 1 / n;
    }

    // Returns NaN if n < 0
    function root(n) {
        return Math.sqrt(n);
    }

    // Returns -Infinity if n === 0
    // Returns NaN if n < 0
    function log(n) {
        return Math.log(n);
    }

    // NOW DERIVE SAFE VERSIONS OF THESE SIMPLE FUNCTIONS:
    // These versions use a validity test, and return a wrapped value
    // with a boolean .isValid property as well as a .value property

    function safeVersion(f, fnSafetyCheck) {
        return function (v) {
            return maybe(fnSafetyCheck(v) ? f(v) : undefined);
        }
    }

    var safe_reciprocal = safeVersion(reciprocal, function (n) {
        return n !== 0;
    });

    var safe_root = safeVersion(root, function (n) {
        return n >= 0;
    });

    var safe_log = safeVersion(log, function (n) {
        return n > 0;
    });

    // THE DERIVATION OF THE SAFE VERSIONS USED THE 'UNIT' OR 'RETURN'
    // FUNCTION OF THE MAYBE MONAD

    // Named maybe() here, the unit function of the Maybe monad wraps a raw value
    // in a datatype with two elements: .isValid (Bool) and .value (Number)

    // a -> Ma
    function maybe(n) {
        return {
            isValid: (typeof n !== 'undefined'),
            value: n
        };
    }

    // THE PROBLEM FOR FUNCTION NESTING (COMPOSITION) OF THE SAFE FUNCTIONS
    // IS THAT THEIR INPUT AND OUTPUT TYPES ARE DIFFERENT

    // Our safe versions of the functions take simple numeric arguments, but return
    // wrapped results. If we feed a wrapped result as an input to another safe function,
    // it will choke on the unexpected type. The solution is to write a higher order
    // function (sometimes called 'bind' or 'chain') which handles composition, taking a
    // a safe function and a wrapped value as arguments,

    // The 'bind' function of the Maybe monad:
    // 1. Applies a 'safe' function directly to the raw unwrapped value, and
    // 2. returns the wrapped result.

    // Ma -> (a -> Mb) -> Mb
    function bind(maybeN, mf) {
        return (maybeN.isValid ? mf(maybeN.value) : maybeN);
    }

    // Using the bind function, we can nest applications of safe_ functions,
    // without their choking on unexpectedly wrapped values returned from
    // other functions of the same kind.
    var rootOneOverFour = bind(
        bind(maybe(4), safe_reciprocal), safe_root
    ).value;

    // -> 0.5

    // We can compose a chain of safe functions (of any length) with a simple foldr/reduceRight
    // which starts by 'lifting' the numeric argument into a Maybe wrapping,
    // and then nests function applications (working from right to left)
    function safeCompose(lstFunctions, value) {
        return lstFunctions
            .reduceRight(function (a, f) {
                return bind(a, f);
            }, maybe(value));
    }

    // TEST INPUT VALUES WITH A SAFELY COMPOSED VERSION OF LOG(SQRT(1/X))

    var safe_log_root_reciprocal = function (n) {
        return safeCompose([safe_log, safe_root, safe_reciprocal], n).value;
    }

    return [-2, -1, -0.5, 0, 1 / Math.E, 1, 2, Math.E, 3, 4, 5].map(
        safe_log_root_reciprocal
    );

})();


Monads/Maybe monad

Solution:
"""A Maybe Monad. Requires Python >= 3.7 for type hints."""
from __future__ import annotations

from typing import Any
from typing import Callable
from typing import Generic
from typing import Optional
from typing import TypeVar
from typing import Union

T = TypeVar("T")

class Maybe(Generic[T]):
    def __init__(self, value: Union[Optional[T], Maybe[T]] = None):
        if isinstance(value, Maybe):
            self.value: Optional[T] = value.value
        else:
            self.value = value

    def __rshift__(self, func: Callable[[Optional[T]], Maybe[Any]]):
        return self.bind(func)

    def bind(self, func: Callable[[Optional[T]], Maybe[Any]]) -> Maybe[Any]:
        return func(self.value)

    def __str__(self):
        return f"{self.__class__.__name__}({self.value!r})"

def plus_one(value: Optional[int]) -> Maybe[int]:
    if value is not None:
        return Maybe[int](value + 1)
    return Maybe[int](None)

def currency(value: Optional[int]) -> Maybe[str]:
    if value is not None:
        return Maybe[str](f"${value}.00")
    return Maybe[str](None)

if __name__ == "__main__":
    test_cases = [1, 99, None, 4]

    for case in test_cases:
        m_int = Maybe[int](case)
        result = m_int >> plus_one >> currency
        # or..
        # result = m_int.bind(plus_one).bind(currency)
        print(f"{str(case):<4} -> {result}")


Monads/Writer monad

[[Category:Monads]]

The Writer monad is a programming design pattern which makes it possible to compose functions which return their result values paired with a log string. The final result of a composed function yields both a value, and a concatenation of the logs from each component function application.

Demonstrate in your programming language the following:

# Construct a Writer monad by writing the 'bind' function and the 'unit' (sometimes known as 'return') function for that monad (or just use what the language already provides)
# Write three simple functions: root, addOne, and half
# Derive Writer monad versions of each of these functions
# Apply a composition of the Writer versions of root, addOne, and half to the integer 5, deriving both a value for the Golden Ratio φ, and a concatenated log of the function applications (starting with the initial value, and followed by the application of root, etc.)

Solution:
(function () {
    'use strict';

    // START WITH THREE SIMPLE FUNCTIONS

    // Square root of a number more than 0
    function root(x) {
        return Math.sqrt(x);
    }

    // Add 1
    function addOne(x) {
        return x + 1;
    }

    // Divide by 2
    function half(x) {
        return x / 2;
    }

    // DERIVE LOGGING VERSIONS OF EACH FUNCTION

    function loggingVersion(f, strLog) {
        return function (v) {
            return {
                value: f(v),
                log: strLog
            };
        }
    }

    var log_root = loggingVersion(root, "obtained square root"),

        log_addOne = loggingVersion(addOne, "added 1"),

        log_half = loggingVersion(half, "divided by 2");

    // UNIT/RETURN and BIND for the the WRITER MONAD

    // The Unit / Return function for the Writer monad:
    // 'Lifts' a raw value into the wrapped form
    // a -> Writer a
    function writerUnit(a) {
        return {
            value: a,
            log: "Initial value: " + JSON.stringify(a)
        };
    }

    // The Bind function for the Writer monad:
    // applies a logging version of a function
    // to the contents of a wrapped value
    // and return a wrapped result (with extended log)

    // Writer a -> (a -> Writer b) -> Writer b
    function writerBind(w, f) {
        var writerB = f(w.value),
            v = writerB.value;

        return {
            value: v,
            log: w.log + '\n' + writerB.log + ' -> ' + JSON.stringify(v)
        };
    }

    // USING UNIT AND BIND TO COMPOSE LOGGING FUNCTIONS

    // We can compose a chain of Writer functions (of any length) with a simple foldr/reduceRight
    // which starts by 'lifting' the initial value into a Writer wrapping,
    // and then nests function applications (working from right to left)
    function logCompose(lstFunctions, value) {
        return lstFunctions.reduceRight(
            writerBind,
            writerUnit(value)
        );
    }

    var half_of_addOne_of_root = function (v) {
        return logCompose(
            [log_half, log_addOne, log_root], v
        );
    };

    return half_of_addOne_of_root(5);
})();


Monads/Writer monad

Solution:
"""A Writer Monad. Requires Python >= 3.7 for type hints."""
from __future__ import annotations

import functools
import math
import os

from typing import Any
from typing import Callable
from typing import Generic
from typing import List
from typing import TypeVar
from typing import Union

T = TypeVar("T")

class Writer(Generic[T]):
    def __init__(self, value: Union[T, Writer[T]], *msgs: str):
        if isinstance(value, Writer):
            self.value: T = value.value
            self.msgs: List[str] = value.msgs + list(msgs)
        else:
            self.value = value
            self.msgs = list(f"{msg}: {self.value}" for msg in msgs)

    def bind(self, func: Callable[[T], Writer[Any]]) -> Writer[Any]:
        writer = func(self.value)
        return Writer(writer, *self.msgs)

    def __rshift__(self, func: Callable[[T], Writer[Any]]) -> Writer[Any]:
        return self.bind(func)

    def __str__(self):
        return f"{self.value}\n{os.linesep.join(reversed(self.msgs))}"

    def __repr__(self):
        return f"Writer({self.value}, \"{', '.join(reversed(self.msgs))}\")"

def lift(func: Callable, msg: str) -> Callable[[Any], Writer[Any]]:
    """Return a writer monad version of the simple function `func`."""

    @functools.wraps(func)
    def wrapped(value):
        return Writer(func(value), msg)

    return wrapped

if __name__ == "__main__":
    square_root = lift(math.sqrt, "square root")
    add_one = lift(lambda x: x + 1, "add one")
    half = lift(lambda x: x / 2, "div two")

    print(Writer(5, "initial") >> square_root >> add_one >> half)


Move-to-front algorithm

Given a symbol table of a ''zero-indexed'' array of all possible input symbols
this algorithm reversibly transforms a sequence
of input symbols into an array of output numbers (indices).

The transform in many cases acts to give frequently repeated input symbols
lower indices which is  useful in some compression algorithms.

;Encoding algorithm:

    for each symbol of the input sequence:
        output the index of the symbol in the symbol table
        move that symbol to the front of the symbol table

;Decoding algorithm:

    # Using the same starting symbol table
    for each index of the input sequence:
        output the symbol at that index of the symbol table
        move that symbol to the front of the symbol table

;Example:
Encoding the string of character symbols 'broood' using a symbol table of the lowercase characters   '''a'''-to-'''z'''

:::::{| class="wikitable" border="1"
|-
! Input
! Output
! SymbolTable
|-
| '''b'''roood
| 1
| 'abcdefghijklmnopqrstuvwxyz'
|-
| b'''r'''oood
| 1 17
| 'bacdefghijklmnopqrstuvwxyz'
|-
| br'''o'''ood
| 1 17 15
| 'rbacdefghijklmnopqstuvwxyz'
|-
| bro'''o'''od
| 1 17 15 0
| 'orbacdefghijklmnpqstuvwxyz'
|-
| broo'''o'''d
| 1 17 15 0 0
| 'orbacdefghijklmnpqstuvwxyz'
|-
| brooo'''d'''
| 1 17 15 0 0 5
| 'orbacdefghijklmnpqstuvwxyz'
|}

Decoding the indices back to the original symbol order:
:::::{| class="wikitable" border="1"
|-
! Input
! Output
! SymbolTable
|-
|  '''1''' 17 15 0 0 5
| b
| 'abcdefghijklmnopqrstuvwxyz'
|-
| 1 '''17''' 15 0 0 5
| br
| 'bacdefghijklmnopqrstuvwxyz'
|-
| 1 17 '''15''' 0 0 5
| bro
| 'rbacdefghijklmnopqstuvwxyz'
|-
| 1 17 15 '''0''' 0 5
| broo
| 'orbacdefghijklmnpqstuvwxyz'
|-
| 1 17 15 0 '''0''' 5
| brooo
| 'orbacdefghijklmnpqstuvwxyz'
|-
| 1 17 15 0 0 '''5'''
| broood
| 'orbacdefghijklmnpqstuvwxyz'
|}

;Task:
:*   Encode and decode the following three strings of characters using the symbol table of the lowercase characters   '''a'''-to-'''z'''   as above.
:*   Show the strings and their encoding here.
:*   Add a check to ensure that the decoded string is the same as the original.

The strings are:

    broood
 bananaaa
 hiphophiphop
(Note the misspellings in the above strings.)

Solution:
#include
#include
#include

#define MAX_SIZE 100

int move_to_front(char *str,char c)
{
    char *q,*p;
    int shift=0;
    p=(char *)malloc(strlen(str)+1);
    strcpy(p,str);
    q=strchr(p,c); //returns pointer to location of char c in string str
    shift=q-p;      // no of characters from 0 to position of c in str
    strncpy(str+1,p,shift);
    str[0]=c;
    free(p);
  //  printf("\n%s\n",str);
    return shift;
}

void decode(int* pass,int size,char *sym)
{
    int i,index;
    char c;
    char table[]="abcdefghijklmnopqrstuvwxyz";
    for(i=0;i


Move-to-front algorithm

Solution:
var encodeMTF = function (word) {
  var init = {wordAsNumbers: [], charList: 'abcdefghijklmnopqrstuvwxyz'.split('')};

  return word.split('').reduce(function (acc, char) {
    var charNum = acc.charList.indexOf(char); //get index of char
    acc.wordAsNumbers.push(charNum); //add original index to acc
    acc.charList.unshift(acc.charList.splice(charNum, 1)[0]); //put at beginning of list
    return acc;
  }, init).wordAsNumbers; //return number list
};

var decodeMTF = function (numList) {
  var init = {word: '', charList: 'abcdefghijklmnopqrstuvwxyz'.split('')};

  return numList.reduce(function (acc, num) {
    acc.word += acc.charList[num];
    acc.charList.unshift(acc.charList.splice(num, 1)[0]); //put at beginning of list
    return acc;
  }, init).word;
};

//test our algorithms
var words = ['broood', 'bananaaa', 'hiphophiphop'];
var encoded = words.map(encodeMTF);
var decoded = encoded.map(decodeMTF);

//print results
console.log("from encoded:");
console.log(encoded);
console.log("from decoded:");
console.log(decoded);


Move-to-front algorithm

Solution:
from __future__ import print_function
from string import ascii_lowercase

SYMBOLTABLE = list(ascii_lowercase)

def move2front_encode(strng, symboltable):
    sequence, pad = [], symboltable[::]
    for char in strng:
        indx = pad.index(char)
        sequence.append(indx)
        pad = [pad.pop(indx)] + pad
    return sequence

def move2front_decode(sequence, symboltable):
    chars, pad = [], symboltable[::]
    for indx in sequence:
        char = pad[indx]
        chars.append(char)
        pad = [pad.pop(indx)] + pad
    return ''.join(chars)

if __name__ == '__main__':
    for s in ['broood', 'bananaaa', 'hiphophiphop']:
        encode = move2front_encode(s, SYMBOLTABLE)
        print('%14r encodes to %r' % (s, encode), end=', ')
        decode = move2front_decode(encode, SYMBOLTABLE)
        print('which decodes back to %r' % decode)
        assert s == decode, 'Whoops!'


Multi-dimensional array

For the purposes of this task, the actual memory layout or access method of this data structure is not mandated.

It is enough to:
# State the number and extent of each index to the array.
# Provide specific, ordered, integer indices for all dimensions of the array together with a new value to update the indexed value.
# Provide specific, ordered, numeric indices for all dimensions of the array to obtain the arrays value at that indexed position.

;Task:
* State if the language supports multi-dimensional arrays in its syntax and usual implementation.
* State whether the language uses [https://en.wikipedia.org/wiki/Row-major_order row-major or column major order] for multi-dimensional array storage, or any other relevant kind of storage.
* Show how to create a four dimensional array in your language and set, access, set to another value; and access the new value of an integer-indexed item of the array. The idiomatic method for the language is preferred.
:* The array should allow a range of five, four, three and two (or two three four five if convenient), in each of the indices, in order. (For example, ''if'' indexing starts at zero for the first index then a range of 0..4 inclusive would suffice).
* State if memory allocation is optimised for the array - especially if contiguous memory is likely to be allocated.
* If the language has exceptional native multi-dimensional array support such as optional bounds checking, reshaping, or being able to state both the lower and upper bounds of index ranges, then this is the task to mention them.

Show all output here, (but you may judiciously use ellipses to shorten repetitive output text).

Solution:
#include
#include

/*The stdlib header file is required for the malloc and free functions*/

int main()
{
	/*Declaring a four fold integer pointer, also called
	a pointer to a pointer to a pointer to an integer pointer*/

	int**** hyperCube, i,j,k;

	/*We will need i,j,k for the memory allocation*/

	/*First the five lines*/

	hyperCube = (int****)malloc(5*sizeof(int***));

	/*Now the four planes*/

	for(i=0;i<5;i++){
		hyperCube[i] = (int***)malloc(4*sizeof(int**));

		/*Now the 3 cubes*/

		for(j=0;j<4;j++){
			hyperCube[i][j] = (int**)malloc(3*sizeof(int*));

			/*Now the 2 hypercubes (?)*/

			for(k=0;k<3;k++){
				hyperCube[i][j][k] = (int*)malloc(2*sizeof(int));
			}
		}
	}

	/*All that looping and function calls may seem futile now,
	but imagine real applications when the dimensions of the dataset are
	not known beforehand*/

	/*Yes, I just copied the rest from the first program*/

	hyperCube[4][3][2][1] = 1;

	/*IMPORTANT : C ( and hence C++ and Java and everyone of the family ) arrays are zero based.
	The above element is thus actually the last element of the hypercube.*/

	/*Now we print out that element*/

	printf("\n%d",hyperCube[4][3][2][1]);

	/*But that's not the only way to get at that element*/
	printf("\n%d",*(*(*(*(hyperCube + 4) + 3) + 2) + 1));

	/*Yes, I know, it's beautiful*/
	*(*(*(*(hyperCube+3)+2)+1)) = 3;

	printf("\n%d",hyperCube[3][2][1][0]);

	/*Always nice to clean up after you, yes memory is cheap, but C is 45+ years old,
	and anyways, imagine you are dealing with terabytes of data, or more...*/

	free(hyperCube);

	return 0;
}


Multi-dimensional array

Solution:
>>> from numpy import *
>>>
>>> mdarray = zeros((2, 3, 4, 5), dtype=int8, order='F')

>>> mdarray
array([[[[0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0]],

        [[0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0]],

        [[0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0]]],

       [[[0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0]],

        [[0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0]],

        [[0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0]]]], dtype=int8)
>>> mdarray[0, 1, 2, 3]
0
>>> mdarray[0, 1, 2, 3] = 123
>>> mdarray[0, 1, 2, 3]
123
>>> mdarray[0, 1, 2, 3] = 666
>>> mdarray[0, 1, 2, 3]
-102
>>> mdarray[0, 1, 2, 3] = 255
>>> mdarray[0, 1, 2, 3]
-1
>>> mdarray[0, 1, 2, 3] = -128
>>> mdarray[0, 1, 2, 3]
-128
>>> mdarray
array([[[[   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0]],

        [[   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0],
         [   0,    0,    0, -128,    0],
         [   0,    0,    0,    0,    0]],

        [[   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0]]],

       [[[   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0]],

        [[   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0]],

        [[   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0],
         [   0,    0,    0,    0,    0]]]], dtype=int8)
>>>


Multifactorial

The factorial of a number, written as n!, is defined as n! = n(n-1)(n-2)...(2)(1).

[http://mathworld.wolfram.com/Multifactorial.html Multifactorials] generalize factorials as follows:
: n! = n(n-1)(n-2)...(2)(1)
: n!! = n(n-2)(n-4)...
: n!! ! = n(n-3)(n-6)...
: n!! !! = n(n-4)(n-8)...
: n!! !! ! = n(n-5)(n-10)...

In all cases, the terms in the products are positive integers.

If we define the degree of the multifactorial as the difference in successive terms that are multiplied together for a multifactorial (the number of exclamation marks), then the task is twofold:
# Write a function that given n and the degree, calculates the multifactorial.
# Use the function to generate and display here a table of the first ten members (1 to 10) of the first five degrees of multifactorial.

'''Note:''' The wikipedia entry on multifactorials gives a different formula. This task uses the [http://mathworld.wolfram.com/Multifactorial.html Wolfram mathworld definition].

Solution:
/* Include statements and constant definitions */
#include
#define HIGHEST_DEGREE 5
#define LARGEST_NUMBER 10

/* Recursive implementation of multifactorial function */
int multifact(int n, int deg){
   return n <= deg ? n : n * multifact(n - deg, deg);
}

/* Iterative implementation of multifactorial function */
int multifact_i(int n, int deg){
   int result = n;
   while (n >= deg + 1){
      result *= (n - deg);
      n -= deg;
   }
   return result;
}

/* Test function to print out multifactorials */
int main(void){
   int i, j;
   for (i = 1; i <= HIGHEST_DEGREE; i++){
      printf("\nDegree %d: ", i);
      for (j = 1; j <= LARGEST_NUMBER; j++){
         printf("%d ", multifact(j, i));
      }
   }
}


Multifactorial

Solution:
function test (n, deg) {
	for (var i = 1; i <= deg; i ++) {
		var results = '';
		for (var j = 1; j <= n; j ++) {
			results += multifact(j, i) + ' ';
		}
		console.log('Degree ' + i + ': ' + results);
	}
}


Multifactorial

Solution:
>>> from functools import reduce
>>> from operator import mul
>>> def mfac(n, m): return reduce(mul, range(n, 0, -m))

>>> for m in range(1, 11): print("%2i: %r" % (m, [mfac(n, m) for n in range(1, 11)]))

 1: [1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
 2: [1, 2, 3, 8, 15, 48, 105, 384, 945, 3840]
 3: [1, 2, 3, 4, 10, 18, 28, 80, 162, 280]
 4: [1, 2, 3, 4, 5, 12, 21, 32, 45, 120]
 5: [1, 2, 3, 4, 5, 6, 14, 24, 36, 50]
 6: [1, 2, 3, 4, 5, 6, 7, 16, 27, 40]
 7: [1, 2, 3, 4, 5, 6, 7, 8, 18, 30]
 8: [1, 2, 3, 4, 5, 6, 7, 8, 9, 20]
 9: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
10: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>>


Multiple distinct objects

Create a [[sequence]] (array, list, whatever) consisting of n distinct, initialized items of the same type. n should be determined at runtime.

By ''distinct'' we mean that if they are mutable, changes to one do not affect all others; if there is an appropriate equality operator they are considered unequal; etc. The code need not specify a particular kind of distinction, but do not use e.g. a numeric-range generator which does not generalize.

By ''initialized'' we mean that each item must be in a well-defined state appropriate for its type, rather than e.g. arbitrary previous memory contents in an array allocation. Do not show only an initialization technique which initializes only to "zero" values (e.g. calloc() or int a[n] = {}; in C), unless user-defined types can provide definitions of "zero" for that type.

This task was inspired by the common error of intending to do this, but instead creating a sequence of n references to the ''same'' mutable object; it might be informative to show the way to do that as well, both as a negative example and as how to do it when that's all that's actually necessary.

This task is most relevant to languages operating in the pass-references-by-value style (most object-oriented, garbage-collected, and/or 'dynamic' languages).

See also: [[Closures/Value capture]]

Solution:
foo *foos = malloc(n * sizeof(*foos));
for (int i = 0; i < n; i++)
  init_foo(&foos[i]);


Multiple distinct objects

Solution:
(n => {

    let nObjects = n => Array.from({
            length: n + 1
        }, (_, i) => {
            // optionally indexed object constructor
            return {
                index: i
            };
        });

    return nObjects(6);

})(6);


Multiple distinct objects

Solution: [Foo()] * n # here Foo() can be any expression that returns a new object


Multisplit

It is often necessary to split a string into pieces
based on several different (potentially multi-character) separator strings,
while still retaining the information about which separators were present in the input.

This is particularly useful when doing small parsing tasks.
The task is to write code to demonstrate this.

The function (or procedure or method, as appropriate) should
take an input string and an ordered collection of separators.

The order of the separators is significant:
The delimiter order represents priority in matching, with the first defined delimiter having the highest priority.
In cases where there would be an ambiguity as to
which separator to use at a particular point
(e.g., because one separator is a prefix of another)
the separator with the highest priority should be used.
Delimiters can be reused and the output from the function should be an ordered sequence of substrings.

Test your code using the input string “a!===b=!=c” and the separators “==”, “!=” and “=”.

For these inputs the string should be parsed as "a" (!=) "" (==) "b" (=) "" (!=) "c", where matched delimiters are shown in parentheses, and separated strings are quoted, so our resulting output is "a", empty string, "b", empty string, "c".
Note that the quotation marks are shown for clarity and do not form part of the output.

'''Extra Credit:''' provide information that indicates which separator was matched at each separation point and where in the input string that separator was matched.

Solution:
#include
#include

void parse_sep(const char *str, const char *const *pat, int len)
{
	int i, slen;
	while (*str != '\0') {
		for (i = 0; i < len || !putchar(*(str++)); i++) {
			slen = strlen(pat[i]);
			if (strncmp(str, pat[i], slen)) continue;
			printf("{%.*s}", slen, str);
			str += slen;
			break;
		}
	}
}

int main()
{
	const char *seps[] = { "==", "!=", "=" };
	parse_sep("a!===b=!=c", seps, 3);

	return 0;
}


Multisplit

Solution:
(() => {

    /// Delimiter list -> String -> list of parts, delimiters, offsets

    // multiSplit :: [String] -> String ->
    //      [{part::String, delim::String, offset::Int}]
    const multiSplit = (ds, s) => {
        const
            dcs = map(chars, ds),
            xs = chars(s),
            dct = foldl(
                (a, c, i, s) => {
                    const
                        inDelim = a.offset > i,
                        mb = inDelim ? (
                            nothing('')
                        ) : find(d => isPrefixOf(d, drop(i, xs)), dcs);
                    return mb.nothing ? {
                        tokens: a.tokens.concat(inDelim ? (
                            []
                        ) : [c]),
                        parts: a.parts,
                        offset: a.offset
                    } : {
                        tokens: [],
                        parts: append(a.parts, [{
                            part: intercalate('', a.tokens),
                            delim: intercalate('', mb.just),
                            offset: i
                        }]),
                        offset: i + length(mb.just)
                    };
                }, {
                    tokens: [],
                    parts: [],
                    offset: 0
                }, xs
            );
        return append(dct.parts, [{
            part: intercalate('', dct.tokens),
            delim: "",
            offset: length(s)
        }]);
    };

    // GENERIC FUNCTIONS -----------------------------------------------------

    // append (++) :: [a] -> [a] -> [a]
    const append = (xs, ys) => xs.concat(ys);

    // chars :: String -> [Char]
    const chars = s => s.split('');

    // drop :: Int -> [a] -> [a]
    // drop :: Int -> String -> String
    const drop = (n, xs) => xs.slice(n);

    // find :: (a -> Bool) -> [a] -> Maybe a
    const find = (p, xs) => {
        for (var i = 0, lng = xs.length; i < lng; i++) {
            var x = xs[i];
            if (p(x)) return just(x);
        }
        return nothing('Not found');
    };

    // foldl :: (a -> b -> a) -> a -> [b] -> a
    const foldl = (f, a, xs) => xs.reduce(f, a);

    // intercalate :: String -> [String] -> String
    const intercalate = (s, xs) => xs.join(s);

    // isPrefixOf takes two lists or strings and returns
    // true iff the first is a prefix of the second.
    // isPrefixOf :: [a] -> [a] -> Bool
    // isPrefixOf :: String -> String -> Bool
    const isPrefixOf = (xs, ys) => {
        const pfx = (xs, ys) => xs.length ? (
            ys.length ? xs[0] === ys[0] && pfx(
                xs.slice(1), ys.slice(1)
            ) : false
        ) : true;
        return typeof xs !== 'string' ? pfx(xs, ys) : ys.startsWith(xs);
    };

    // just :: a -> Just a
    const just = x => ({
        nothing: false,
        just: x
    });

    // length :: [a] -> Int
    const length = xs => xs.length;

    // map :: (a -> b) -> [a] -> [b]
    const map = (f, xs) => xs.map(f);

    // nothing :: () -> Nothing
    const nothing = (optionalMsg) => ({
        nothing: true,
        msg: optionalMsg
    });

    // show :: Int -> a -> Indented String
    // show :: a -> String
    const show = (...x) =>
        JSON.stringify.apply(
            null, x.length > 1 ? [x[1], null, x[0]] : x
        );

    // TEST ------------------------------------------------------------------
    const
        strTest = 'a!===b=!=c',
        delims = ['==', '!=', '='];

    return show(2,
        multiSplit(delims, strTest)
    );
})();


Multisplit

Solution:
def min_pos(List):
	return List.index(min(List))

def find_all(S, Sub, Start = 0, End = -1, IsOverlapped = 0):
	Res = []
	if End == -1:
		End = len(S)
	if IsOverlapped:
		DeltaPos = 1
	else:
		DeltaPos = len(Sub)
	Pos = Start
	while True:
		Pos = S.find(Sub, Pos, End)
		if Pos == -1:
			break
		Res.append(Pos)
		Pos += DeltaPos
	return Res

def multisplit(S, SepList):
	SepPosListList = []
	SLen = len(S)
	SepNumList = []
	ListCount = 0
	for i, Sep in enumerate(SepList):
		SepPosList = find_all(S, Sep, 0, SLen, IsOverlapped = 1)
		if SepPosList != []:
			SepNumList.append(i)
			SepPosListList.append(SepPosList)
			ListCount += 1
	if ListCount == 0:
		return [S]
	MinPosList = []
	for i in range(ListCount):
		MinPosList.append(SepPosListList[i][0])
	SepEnd = 0
	MinPosPos = min_pos(MinPosList)
	Res = []
	while True:
		Res.append( S[SepEnd : MinPosList[MinPosPos]] )
		Res.append([SepNumList[MinPosPos], MinPosList[MinPosPos]])
		SepEnd = MinPosList[MinPosPos] + len(SepList[SepNumList[MinPosPos]])
		while True:
			MinPosPos = min_pos(MinPosList)
			if MinPosList[MinPosPos] < SepEnd:
				del SepPosListList[MinPosPos][0]
				if len(SepPosListList[MinPosPos]) == 0:
					del SepPosListList[MinPosPos]
					del MinPosList[MinPosPos]
					del SepNumList[MinPosPos]
					ListCount -= 1
					if ListCount == 0:
						break
				else:
					MinPosList[MinPosPos] = SepPosListList[MinPosPos][0]
			else:
				break
		if ListCount == 0:
			break
	Res.append(S[SepEnd:])
	return Res

S = "a!===b=!=c"
multisplit(S, ["==", "!=", "="]) # output: ['a', [1, 1], '', [0, 3], 'b', [2, 6], '', [1, 7], 'c']
multisplit(S, ["=", "!=", "=="]) # output: ['a', [1, 1], '', [0, 3], '', [0, 4], 'b', [0, 6], '', [1, 7], 'c']


Multisplit

Solution:
'''Multisplit'''

from functools import reduce

# multiSplit :: [String] -> String -> [(String, String, Int)]
def multiSplit(separators):
    '''List of triples:
       [(token, separator, start index of separator].
    '''
    def go(s):
        def f(tokensPartsOffset, ic):
            tokens, parts, offset = tokensPartsOffset
            i, c = ic
            inDelim = offset > i
            return maybe(
                (
                    tokens if inDelim
                    else c + tokens, parts, offset
                )
            )(
                lambda x: (
                    '',
                    [(tokens, x, i)] + parts,
                    i + len(x)
                )
            )(
                None if inDelim else find(
                    s[i:].startswith
                )(separators)
            )
        ts, ps, _ = reduce(f, enumerate(s), ('', [], 0))
        return list(reversed(ps)) + [(ts, '', len(s))]
    return go

# ------------------------- TEST -------------------------
# main :: IO ()
def main():
    '''String split on three successive separators.'''
    print(
        multiSplit(['==', '!=', '='])(
            'a!===b=!=c'
        )
    )

# ------------------ GENERIC FUNCTIONS -------------------

# find :: (a -> Bool) -> [a] -> (a | None)
def find(p):
    '''Just the first element in the list that matches p,
       or None if no elements match.
    '''
    def go(xs):
        try:
            return next(x for x in xs if p(x))
        except StopIteration:
            return None
    return go

# maybe :: b -> (a -> b) -> (a | None) -> b
def maybe(v):
    '''Either the default value v, if m is None,
       or the application of f to x.
    '''
    return lambda f: lambda m: v if (
        None is m
    ) else f(m)

# MAIN ---
if __name__ == '__main__':
    main()


Munchausen numbers

A Munchausen number is a natural number ''n'' the sum of whose digits (in base 10), each raised to the power of itself, equals ''n''.

('''Munchausen''' is also spelled: '''Münchhausen'''.)

For instance:    3435 = 33 + 44 + 33 + 55

;Task
Find all Munchausen numbers between   '''1'''   and   '''5000'''.

;Also see:
:* The OEIS entry:  A046253
:* The Wikipedia entry:  Perfect digit-to-digit invariant, redirected from ''Munchausen Number''

Solution:
#include
#include

int main() {
    for (int i = 1; i < 5000; i++) {
        // loop through each digit in i
        // e.g. for 1000 we get 0, 0, 0, 1.
        int sum = 0;
        for (int number = i; number > 0; number /= 10) {
            int digit = number % 10;
            // find the sum of the digits
            // raised to themselves
            sum += pow(digit, digit);
        }
        if (sum == i) {
            // the sum is equal to the number
            // itself; thus it is a
            // munchausen number
            printf("%i\n", i);
        }
    }
    return 0;
}


Munchausen numbers

Solution:
for (let i of [...Array(5000).keys()]
	.filter(n => n == n.toString().split('')
	.reduce((a, b) => a+Math.pow(parseInt(b),parseInt(b)), 0)))
    console.log(i);


Munchausen numbers

Solution:
for i in range(5000):
    if i == sum(int(x) ** int(x) for x in str(i)):
        print(i)