Find Chess960 starting position identifier

As described on the '''Starting Position Identifier number ("SP-ID"), and generate the corresponding position.

;Task:
This task is to go the other way: given a starting array of pieces (provided in any form that suits your implementation, whether string or list or array, of letters or Unicode chess symbols or enum values, etc.), derive its unique SP-ID. For example, given the starting array '''QNRBBNKR''' (or '''♕♘♖♗♗♘♔♖''' or '''♛♞♜♝♝♞♚♜'''), which we assume is given as seen from White's side of the board from left to right, your (sub)program should return 105; given the starting lineup of standard chess, it should return 518.

You may assume the input is a valid Chess960 position; detecting invalid input (including illegal characters or starting arrays with the bishops on the same color square or the king not between the two rooks) is optional.

;Algorithm:

The derivation is the inverse of the algorithm given at Wikipedia, and goes like this (we'll use the standard chess setup as an example).

1. Ignoring the Queen and Bishops, find the positions of the Knights within the remaining five spaces (in the standard array they're in the second and fourth positions), and then find the index number of that combination. There's a table at the above Wikipedia article, but it's just the possible positions sorted left to right and numbered 0 to 9: 0='''NN---''', 1='''N-N--''', 2='''N--N-''', 3='''N---N''', 4='''-NN--''', etc; our pair is combination number 5. Call this number N. '''N=5'''

2. Still ignoring the Bishops, find the position of the Queen in the remaining 6 spaces; number them 0..5 from left to right and call the index of the Queen's position Q. In our example, '''Q=2'''.

3. Finally, find the positions of the two bishops within their respective sets of four like-colored squares. It's important to note here that the board in chess is placed such that the leftmost position on the home row is on a dark square and the rightmost a light. So if we number the squares of each color 0..3 from left to right, the dark bishop in the standard position is on square 1 ('''D=1'''), and the light bishop is on square 2 ('''L=2''').

4. Then the position number is given by '''4(4(6N + Q)+D)+L''', which reduces to '''96N + 16Q + 4D + L'''. In our example, that's 96×5 + 16×2 + 4×1 + 2 = 480 + 32 + 4 + 2 = 518.

Note that an earlier iteration of this page contained an incorrect description of the algorithm which would give the same SP-ID for both of the following two positions.

    RQNBBKRN = 601
    RNQBBKRN = 617

Solution:
# optional, but task function depends on it as written
def validate_position(candidate: str):
    assert (
        len(candidate) == 8
    ), f"candidate position has invalide len = {len(candidate)}"

    valid_pieces = {"R": 2, "N": 2, "B": 2, "Q": 1, "K": 1}
    assert {
        piece for piece in candidate
    } == valid_pieces.keys(), f"candidate position contains invalid pieces"
    for piece_type in valid_pieces.keys():
        assert (
            candidate.count(piece_type) == valid_pieces[piece_type]
        ), f"piece type '{piece_type}' has invalid count"

    bishops_pos = [index for index,
                   value in enumerate(candidate) if value == "B"]
    assert (
        bishops_pos[0] % 2 != bishops_pos[1] % 2
    ), f"candidate position has both bishops in the same color"

    assert [piece for piece in candidate if piece in "RK"] == [
        "R",
        "K",
        "R",
    ], "candidate position has K outside of RR"

def calc_position(start_pos: str):
    try:
        validate_position(start_pos)
    except AssertionError:
        raise AssertionError
    # step 1
    subset_step1 = [piece for piece in start_pos if piece not in "QB"]
    nights_positions = [
        index for index, value in enumerate(subset_step1) if value == "N"
    ]
    nights_table = {
        (0, 1): 0,
        (0, 2): 1,
        (0, 3): 2,
        (0, 4): 3,
        (1, 2): 4,
        (1, 3): 5,
        (1, 4): 6,
        (2, 3): 7,
        (2, 4): 8,
        (3, 4): 9,
    }
    N = nights_table.get(tuple(nights_positions))

    # step 2
    subset_step2 = [piece for piece in start_pos if piece != "B"]
    Q = subset_step2.index("Q")

    # step 3
    dark_squares = [
        piece for index, piece in enumerate(start_pos) if index in range(0, 9, 2)
    ]
    light_squares = [
        piece for index, piece in enumerate(start_pos) if index in range(1, 9, 2)
    ]
    D = dark_squares.index("B")
    L = light_squares.index("B")

    return 4 * (4 * (6*N + Q) + D) + L

if __name__ == '__main__':
    for example in ["QNRBBNKR", "RNBQKBNR", "RQNBBKRN", "RNQBBKRN"]:
        print(f'Position: {example}; Chess960 PID= {calc_position(example)}')


Find duplicate files

In a large directory structure it is easy to inadvertently leave unnecessary copies of files around, which can use considerable disk space and create confusion.

;Task:
Create a program which, given a minimum size and a folder/directory, will find all files of at least ''size'' bytes with duplicate contents under the directory and output or show the sets of duplicate files in order of decreasing size.

The program may be command-line or graphical, and duplicate content may be determined by direct comparison or by calculating a hash of the data.

Specify which filesystems or operating systems your program works with if it has any filesystem- or OS-specific requirements.

Identify hard links (filenames referencing the same content) in the output if applicable for the filesystem.

For extra points, detect when whole directory sub-trees are identical, or optionally remove or link identical files.

Solution:
from __future__ import print_function
import os
import hashlib
import datetime

def FindDuplicateFiles(pth, minSize = 0, hashName = "md5"):
    knownFiles = {}

    #Analyse files
    for root, dirs, files in os.walk(pth):
        for fina in files:
            fullFina = os.path.join(root, fina)
            isSymLink = os.path.islink(fullFina)
            if isSymLink:
                continue # Skip symlinks
            si = os.path.getsize(fullFina)
            if si < minSize:
                continue
            if si not in knownFiles:
                knownFiles[si] = {}
            h = hashlib.new(hashName)
            h.update(open(fullFina, "rb").read())
            hashed = h.digest()
            if hashed in knownFiles[si]:
                fileRec = knownFiles[si][hashed]
                fileRec.append(fullFina)
            else:
                knownFiles[si][hashed] = [fullFina]

    #Print result
    sizeList = list(knownFiles.keys())
    sizeList.sort(reverse=True)
    for si in sizeList:
        filesAtThisSize = knownFiles[si]
        for hashVal in filesAtThisSize:
            if len(filesAtThisSize[hashVal]) < 2:
                continue
            fullFinaLi = filesAtThisSize[hashVal]
            print ("=======Duplicate=======")
            for fullFina in fullFinaLi:
                st = os.stat(fullFina)
                isHardLink = st.st_nlink > 1
                infoStr = []
                if isHardLink:
                    infoStr.append("(Hard linked)")
                fmtModTime = datetime.datetime.utcfromtimestamp(st.st_mtime).strftime('%Y-%m-%dT%H:%M:%SZ')
                print (fmtModTime, si, os.path.relpath(fullFina, pth), " ".join(infoStr))

if __name__=="__main__":

    FindDuplicateFiles('/home/tim/Dropbox', 1024*1024)


Find if a point is within a triangle

[[Category:Geometry]]
[[Category:Collision detection]]

Find if a point is within a triangle.

;Task:

::*   Assume points are on a plane defined by (x, y) real number coordinates.

::*   Given a point P(x, y) and a triangle formed by points A, B, and C, determine if P is within triangle ABC.

::*   You may use any algorithm.

::*   Bonus: explain why the algorithm you chose works.

;Related tasks:
*   [[Determine_if_two_triangles_overlap]]

;Also see:
:* Discussion of several methods. [[http://totologic.blogspot.com/2014/01/accurate-point-in-triangle-test.html]]
:* Determine if a point is in a polygon [[https://en.wikipedia.org/wiki/Point_in_polygon]]
:* Triangle based coordinate systems [[https://en.wikipedia.org/wiki/Barycentric_coordinate_system]]
:* Wolfram entry [[https://mathworld.wolfram.com/TriangleInterior.html]]

Solution:
#include
#include
#include

const double EPS = 0.001;
const double EPS_SQUARE = 0.000001;

double side(double x1, double y1, double x2, double y2, double x, double y) {
    return (y2 - y1) * (x - x1) + (-x2 + x1) * (y - y1);
}

bool naivePointInTriangle(double x1, double y1, double x2, double y2, double x3, double y3, double x, double y) {
    double checkSide1 = side(x1, y1, x2, y2, x, y) >= 0;
    double checkSide2 = side(x2, y2, x3, y3, x, y) >= 0;
    double checkSide3 = side(x3, y3, x1, y1, x, y) >= 0;
    return checkSide1 && checkSide2 && checkSide3;
}

bool pointInTriangleBoundingBox(double x1, double y1, double x2, double y2, double x3, double y3, double x, double y) {
    double xMin = min(x1, min(x2, x3)) - EPS;
    double xMax = max(x1, max(x2, x3)) + EPS;
    double yMin = min(y1, min(y2, y3)) - EPS;
    double yMax = max(y1, max(y2, y3)) + EPS;
    return !(x < xMin || xMax < x || y < yMin || yMax < y);
}

double distanceSquarePointToSegment(double x1, double y1, double x2, double y2, double x, double y) {
    double p1_p2_squareLength = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
    double dotProduct = ((x - x1) * (x2 - x1) + (y - y1) * (y2 - y1)) / p1_p2_squareLength;
    if (dotProduct < 0) {
        return (x - x1) * (x - x1) + (y - y1) * (y - y1);
    } else if (dotProduct <= 1) {
        double p_p1_squareLength = (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y);
        return p_p1_squareLength - dotProduct * dotProduct * p1_p2_squareLength;
    } else {
        return (x - x2) * (x - x2) + (y - y2) * (y - y2);
    }
}

bool accuratePointInTriangle(double x1, double y1, double x2, double y2, double x3, double y3, double x, double y) {
    if (!pointInTriangleBoundingBox(x1, y1, x2, y2, x3, y3, x, y)) {
        return false;
    }
    if (naivePointInTriangle(x1, y1, x2, y2, x3, y3, x, y)) {
        return true;
    }
    if (distanceSquarePointToSegment(x1, y1, x2, y2, x, y) <= EPS_SQUARE) {
        return true;
    }
    if (distanceSquarePointToSegment(x2, y2, x3, y3, x, y) <= EPS_SQUARE) {
        return true;
    }
    if (distanceSquarePointToSegment(x3, y3, x1, y1, x, y) <= EPS_SQUARE) {
        return true;
    }
    return false;
}

void printPoint(double x, double y) {
    printf("(%f, %f)", x, y);
}

void printTriangle(double x1, double y1, double x2, double y2, double x3, double y3) {
    printf("Triangle is [");
    printPoint(x1, y1);
    printf(", ");
    printPoint(x2, y2);
    printf(", ");
    printPoint(x3, y3);
    printf("] \n");
}

void test(double x1, double y1, double x2, double y2, double x3, double y3, double x, double y) {
    printTriangle(x1, y1, x2, y2, x3, y3);
    printf("Point ");
    printPoint(x, y);
    printf(" is within triangle? ");
    if (accuratePointInTriangle(x1, y1, x2, y2, x3, y3, x, y)) {
        printf("true\n");
    } else {
        printf("false\n");
    }
}

int main() {
    test(1.5, 2.4, 5.1, -3.1, -3.8, 1.2, 0, 0);
    test(1.5, 2.4, 5.1, -3.1, -3.8, 1.2, 0, 1);
    test(1.5, 2.4, 5.1, -3.1, -3.8, 1.2, 3, 1);
    printf("\n");

    test(0.1, 0.1111111111111111, 12.5, 33.333333333333336, 25, 11.11111111111111, 5.414285714285714, 14.349206349206348);
    printf("\n");

    test(0.1, 0.1111111111111111, 12.5, 33.333333333333336, -12.5, 16.666666666666668, 5.414285714285714, 14.349206349206348);
    printf("\n");

    return 0;
}


Find if a point is within a triangle

Solution:
""" find if point is in a triangle """

from sympy.geometry import Point, Triangle

def sign(pt1, pt2, pt3):
    """ which side of plane cut by line (pt2, pt3) is pt1 on? """
    return (pt1.x - pt3.x) * (pt2.y - pt3.y) - (pt2.x - pt3.x) * (pt1.y - pt3.y)

def iswithin(point, pt1, pt2, pt3):
    """
    Determine if point is within triangle formed by points p1, p2, p3.
    If so, the point will be on the same side of each of the half planes
    defined by vectors p1p2, p2p3, and p3p1. zval is positive if outside,
    negative if inside such a plane. All should be positive or all negative
    if point is within the triangle.
    """
    zval1 = sign(point, pt1, pt2)
    zval2 = sign(point, pt2, pt3)
    zval3 = sign(point, pt3, pt1)
    notanyneg = zval1 >= 0 and zval2 >= 0 and zval3 >= 0
    notanypos = zval1 <= 0 and zval2 <= 0 and zval3 <= 0
    return notanyneg or notanypos

if __name__ == "__main__":
    POINTS = [Point(0, 0)]
    TRI = Triangle(Point(1.5, 2.4), Point(5.1, -3.1), Point(-3.8, 0.5))
    for pnt in POINTS:
        a, b, c = TRI.vertices
        isornot = "is" if iswithin(pnt, a, b, c) else "is not"
        print("Point", pnt, isornot, "within the triangle", TRI)


Find limit of recursion

[[Category:Basic language learning]]
[[Category:Programming environment operations]]
[[Category:Simple]]

;Task:
Find the limit of recursion.

Solution:
#include

char * base;
void get_diff()
{
	char x;
	if (base - &x < 200)
		printf("%p %d\n", &x, base - &x);
}

void recur()
{
	get_diff();
	recur();
}

int main()
{
	char v = 32;
	printf("pos of v: %p\n", base = &v);
	recur();
	return 0;
}


Find limit of recursion

Solution:
function recurse(depth)
{
 try
 {
  return recurse(depth + 1);
 }
 catch(ex)
 {
  return depth;
 }
}

var maxRecursion = recurse(1);
document.write("Recursion depth on this system is " + maxRecursion);


Find limit of recursion

Solution:
def recurseDeeper(counter):
    try:
        print(counter)
        recurseDeeper(counter + 1)
    except RecursionError:
        print("RecursionError at depth", counter)
        recurseDeeper(counter + 1)


Find palindromic numbers in both binary and ternary bases

;Task:

*   Find and show (in decimal) the first six numbers (non-negative integers) that are   palindromes   in   ''both'':
:::*   base 2
:::*   base 3
*   Display   '''0'''   (zero) as the first number found, even though some other definitions ignore it.
*   Optionally, show the decimal number found in its binary and ternary form.
*   Show all output here.

It's permissible to assume the first two numbers and simply list them.

;See also
*   Sequence A60792,   numbers that are palindromic in bases 2 and 3 on ''The On-Line Encyclopedia of Integer Sequences''.

Solution:
#include
typedef unsigned long long xint;

int is_palin2(xint n)
{
	xint x = 0;
	if (!(n&1)) return !n;
	while (x < n) x = x<<1 | (n&1), n >>= 1;
	return n == x || n == x>>1;
}

xint reverse3(xint n)
{
	xint x = 0;
	while (n) x = x*3 + (n%3), n /= 3;
	return x;
}

void print(xint n, xint base)
{
	putchar(' ');
	// printing digits backwards, but hey, it's a palindrome
	do { putchar('0' + (n%base)), n /= base; } while(n);
	printf("(%lld)", base);
}

void show(xint n)
{
	printf("%llu", n);
	print(n, 2);
	print(n, 3);
	putchar('\n');
}

xint min(xint a, xint b) { return a < b ? a : b; }
xint max(xint a, xint b) { return a > b ? a : b; }

int main(void)
{
	xint lo, hi, lo2, hi2, lo3, hi3, pow2, pow3, i, n;
	int cnt;

	show(0);
	cnt = 1;

	lo = 0;
	hi = pow2 = pow3 = 1;

	while (1) {
		for (i = lo; i < hi; i++) {
			n = (i * 3 + 1) * pow3 + reverse3(i);
			if (!is_palin2(n)) continue;
			show(n);
			if (++cnt >= 7) return 0;
		}

		if (i == pow3)
			pow3 *= 3;
		else
			pow2 *= 4;

		while (1) {
			while (pow2 <= pow3) pow2 *= 4;

			lo2 = (pow2 / pow3 - 1) / 3;
			hi2 = (pow2 * 2 / pow3 - 1) / 3 + 1;
			lo3 = pow3 / 3;
			hi3 = pow3;

			if (lo2 >= hi3)
				pow3 *= 3;
			else if (lo3 >= hi2)
				pow2 *= 4;
			else {
				lo = max(lo2, lo3);
				hi = min(hi2, hi3);
				break;
			}
		}
	}
	return 0;
}


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

    // GENERIC FUNCTIONS

    // range :: Int -> Int -> [Int]
    const range = (m, n) =>
        Array.from({
            length: Math.floor(n - m) + 1
        }, (_, i) => m + i);

    // compose :: (b -> c) -> (a -> b) -> (a -> c)
    const compose = (f, g) => x => f(g(x));

    // listApply :: [(a -> b)] -> [a] -> [b]
    const listApply = (fs, xs) =>
        [].concat.apply([], fs.map(f =>
        [].concat.apply([], xs.map(x => [f(x)]))));

    // pure :: a -> [a]
    const pure = x => [x];

    // curry :: Function -> Function
    const curry = (f, ...args) => {
        const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :
            function () {
                return go(xs.concat([].slice.apply(arguments)));
            };
        return go([].slice.call(args, 1));
    };

    // transpose :: [[a]] -> [[a]]
    const transpose = xs =>
        xs[0].map((_, iCol) => xs.map(row => row[iCol]));

    // reverse :: [a] -> [a]
    const reverse = xs =>
        typeof xs === 'string' ? (
            xs.split('')
            .reverse()
            .join('')
        ) : xs.slice(0)
        .reverse();

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

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

    // maximum :: [a] -> a
    const maximum = xs =>
        xs.reduce((a, x) => (x > a || a === undefined ? x : a), undefined);

    // quotRem :: Integral a => a -> a -> (a, a)
    const quotRem = (m, n) => [Math.floor(m / n), m % n];

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

    // justifyLeft :: Int -> Char -> Text -> Text
    const justifyLeft = (n, cFiller, strText) =>
        n > strText.length ? (
            (strText + cFiller.repeat(n))
            .substr(0, n)
        ) : strText;

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

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

    // BASES AND PALINDROMES

    // show, showBinary, showTernary :: Int -> String
    const show = n => n.toString(10);
    const showBinary = n => n.toString(2);
    const showTernary = n => n.toString(3);

    // readBase3 :: String -> Int
    const readBase3 = s => parseInt(s, 3);

    // base3Palindrome :: Int -> String
    const base3Palindrome = n => {
        const s = showTernary(n);
        return s + '1' + reverse(s);
    };

    // isBinPal :: Int -> Bool
    const isBinPal = n => {
        const
            s = showBinary(n),
            [q, r] = quotRem(s.length, 2);
        return (r !== 0) && drop(q + 1, s) === reverse(take(q, s));
    };

    // solutions :: [Int]
    const solutions = [0, 1].concat(range(1, 10E5)
        .map(compose(readBase3, base3Palindrome))
        .filter(isBinPal));

    // TABULATION

    // cols :: [[Int]]
    const cols = transpose(
        [
            ['Decimal', 'Ternary', 'Binary']
        ].concat(
            solutions.map(
                compose(
                    xs => listApply([show, showTernary, showBinary], xs),
                    pure
                )
            )
        )
    );

    return unlines(
        transpose(cols.map(col => col.map(
            curry(justifyLeft)(maximum(col.map(length)) + 1, ' ')
        )))
        .map(unwords));
})();


Solution:
from itertools import islice

digits = "0123456789abcdefghijklmnopqrstuvwxyz"

def baseN(num,b):
  if num == 0: return "0"
  result = ""
  while num != 0:
    num, d = divmod(num, b)
    result += digits[d]
  return result[::-1] # reverse

def pal2(num):
    if num == 0 or num == 1: return True
    based = bin(num)[2:]
    return based == based[::-1]

def pal_23():
    yield 0
    yield 1
    n = 1
    while True:
        n += 1
        b = baseN(n, 3)
        revb = b[::-1]
        #if len(b) > 12: break
        for trial in ('{0}{1}'.format(b, revb), '{0}0{1}'.format(b, revb),
                      '{0}1{1}'.format(b, revb), '{0}2{1}'.format(b, revb)):
            t = int(trial, 3)
            if pal2(t):
                yield t

for pal23 in islice(pal_23(), 6):
    print(pal23, baseN(pal23, 3), baseN(pal23, 2))


Find the intersection of a line with a plane

Finding the intersection of an infinite ray with a plane in 3D is an important topic in collision detection.

;Task:
Find the point of intersection for the infinite ray with direction   (0, -1, -1)   passing through position   (0, 0, 10)   with the infinite plane with a normal vector of   (0, 0, 1)   and which passes through [0, 0, 5].

Solution:
#include

typedef struct{
	double x,y,z;
}vector;

vector addVectors(vector a,vector b){
	return (vector){a.x+b.x,a.y+b.y,a.z+b.z};
}

vector subVectors(vector a,vector b){
	return (vector){a.x-b.x,a.y-b.y,a.z-b.z};
}

double dotProduct(vector a,vector b){
	return a.x*b.x + a.y*b.y + a.z*b.z;
}

vector scaleVector(double l,vector a){
	return (vector){l*a.x,l*a.y,l*a.z};
}

vector intersectionPoint(vector lineVector, vector linePoint, vector planeNormal, vector planePoint){
	vector diff = subVectors(linePoint,planePoint);

	return addVectors(addVectors(diff,planePoint),scaleVector(-dotProduct(diff,planeNormal)/dotProduct(lineVector,planeNormal),lineVector));
}

int main(int argC,char* argV[])
{
	vector lV,lP,pN,pP,iP;

	if(argC!=5)
		printf("Usage : %s ");
	else{
		sscanf(argV[1],"(%lf,%lf,%lf)",&lV.x,&lV.y,&lV.z);
		sscanf(argV[3],"(%lf,%lf,%lf)",&pN.x,&pN.y,&pN.z);

		if(dotProduct(lV,pN)==0)
			printf("Line and Plane do not intersect, either parallel or line is on the plane");
		else{
			sscanf(argV[2],"(%lf,%lf,%lf)",&lP.x,&lP.y,&lP.z);
			sscanf(argV[4],"(%lf,%lf,%lf)",&pP.x,&pP.y,&pP.z);

			iP = intersectionPoint(lV,lP,pN,pP);

			printf("Intersection point is (%lf,%lf,%lf)",iP.x,iP.y,iP.z);
		}
	}

	return 0;
}


Solution:
#!/bin/python
from __future__ import print_function
import numpy as np

def LinePlaneCollision(planeNormal, planePoint, rayDirection, rayPoint, epsilon=1e-6):

	ndotu = planeNormal.dot(rayDirection)
	if abs(ndotu) < epsilon:
		raise RuntimeError("no intersection or line is within plane")

	w = rayPoint - planePoint
	si = -planeNormal.dot(w) / ndotu
	Psi = w + si * rayDirection + planePoint
	return Psi

if __name__=="__main__":
	#Define plane
	planeNormal = np.array([0, 0, 1])
	planePoint = np.array([0, 0, 5]) #Any point on the plane

	#Define ray
	rayDirection = np.array([0, -1, -1])
	rayPoint = np.array([0, 0, 10]) #Any point along the ray

	Psi = LinePlaneCollision(planeNormal, planePoint, rayDirection, rayPoint)
	print ("intersection at", Psi)


Find the intersection of two lines

;Task:
Find the point of intersection of two lines in 2D.

The 1st     line passes though    (4,0)    and    (6,10) .
The 2nd line passes though    (0,3)    and    (10,7) .

Solution:
#include
#include
#include

typedef struct{
	double x,y;
}point;

double lineSlope(point a,point b){

	if(a.x-b.x == 0.0)
		return NAN;
	else
		return (a.y-b.y)/(a.x-b.x);
}

point extractPoint(char* str){
	int i,j,start,end,length;
	char* holder;
	point c;

	for(i=0;str[i]!=00;i++){
		if(str[i]=='(')
			start = i;
		if(str[i]==','||str[i]==')')
		{
			end = i;

			length = end - start;

			holder = (char*)malloc(length*sizeof(char));

			for(j=0;j",argV[0]);
	else{
		c = intersectionPoint(extractPoint(argV[1]),extractPoint(argV[2]),extractPoint(argV[3]),extractPoint(argV[4]));

		if(isnan(c.x))
			printf("The lines do not intersect, they are either parallel or co-incident.");
		else
			printf("Point of intersection : (%lf,%lf)",c.x,c.y);
	}

	return 0;
}


Find the intersection of two lines

Solution:
(() => {
    'use strict';
    // INTERSECTION OF TWO LINES ----------------------------------------------

    // intersection :: Line -> Line -> Either String (Float, Float)
    const intersection = (ab, pq) => {
        const
            delta = f => x => f(fst(x)) - f(snd(x)),
            [abDX, pqDX, abDY, pqDY] = apList(
                [delta(fst), delta(snd)], [ab, pq]
            ),
            determinant = abDX * pqDY - abDY * pqDX;

        return determinant !== 0 ? Right((() => {
            const [abD, pqD] = map(
                ([a, b]) => fst(a) * snd(b) - fst(b) * snd(a),
                [ab, pq]
            );
            return apList(
                [([pq, ab]) =>
                    (abD * pq - ab * pqD) / determinant
                ], [
                    [pqDX, abDX],
                    [pqDY, abDY]
                ]
            );
        })()) : Left('(Parallel lines – no intersection)');
    };

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

    // A list of functions applied to a list of arguments
    // <*> :: [(a -> b)] -> [a] -> [b]
    const apList = (fs, xs) => //
        [].concat.apply([], fs.map(f => //
            [].concat.apply([], xs.map(x => [f(x)]))));

    // fst :: (a, b) -> a
    const fst = tpl => tpl[0];

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

    // snd :: (a, b) -> b
    const snd = tpl => tpl[1];

    // show :: a -> String
    const show = x => JSON.stringify(x); //, null, 2);

    // TEST --------------------------------------------------

    // lrIntersection ::Either String Point
    const lrIntersection = intersection([
        [4.0, 0.0],
        [6.0, 10.0]
    ], [
        [0.0, 3.0],
        [10.0, 7.0]
    ]);
    return show(lrIntersection.Left || lrIntersection.Right);
})();


Find the intersection of two lines

Solution:
def line_intersect(Ax1, Ay1, Ax2, Ay2, Bx1, By1, Bx2, By2):
    """ returns a (x, y) tuple or None if there is no intersection """
    d = (By2 - By1) * (Ax2 - Ax1) - (Bx2 - Bx1) * (Ay2 - Ay1)
    if d:
        uA = ((Bx2 - Bx1) * (Ay1 - By1) - (By2 - By1) * (Ax1 - Bx1)) / d
        uB = ((Ax2 - Ax1) * (Ay1 - By1) - (Ay2 - Ay1) * (Ax1 - Bx1)) / d
    else:
        return
    if not(0 <= uA <= 1 and 0 <= uB <= 1):
        return
    x = Ax1 + uA * (Ax2 - Ax1)
    y = Ay1 + uA * (Ay2 - Ay1)

    return x, y

if __name__ == '__main__':
    (a, b), (c, d) = (4, 0), (6, 10)  # try (4, 0), (6, 4)
    (e, f), (g, h) = (0, 3), (10, 7)  # for non intersecting test
    pt = line_intersect(a, b, c, d, e, f, g, h)
    print(pt)


Find the last Sunday of each month

Write a program or a script that returns the last Sundays of each month of a given year. The year may be given through any simple input method in your language (command line, std in, etc).

Example of an expected output:

./last_sundays 2013
2013-01-27
2013-02-24
2013-03-31
2013-04-28
2013-05-26
2013-06-30
2013-07-28
2013-08-25
2013-09-29
2013-10-27
2013-11-24
2013-12-29

;Related tasks
* [[Day of the week]]
* [[Five weekends]]
* [[Last Friday of each month]]

Solution:
#include
#include

int main(int argc, char *argv[])
{
        int days[] = {31,29,31,30,31,30,31,31,30,31,30,31};
        int m, y, w;

        if (argc < 2 || (y = atoi(argv[1])) <= 1752) return 1;
        days[1] -= (y % 4) || (!(y % 100) && (y % 400));
        w = y * 365 + 97 * (y - 1) / 400 + 4;

        for(m = 0; m < 12; m++) {
                w = (w + days[m]) % 7;
                printf("%d-%02d-%d\n", y, m + 1,days[m] - w);
        }

        return 0;
}


Find the last Sunday of each month

Solution:
function lastSundayOfEachMonths(year) {
	var lastDay = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
	var sundays = [];
	var date, month;
	if (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {
		lastDay[2] = 29;
	}
	for (date = new Date(), month = 0; month < 12; month += 1) {
		date.setFullYear(year, month, lastDay[month]);
		date.setDate(date.getDate() - date.getDay());
		sundays.push(date.toISOString().substring(0, 10));
	}
	return sundays;
}

console.log(lastSundayOfEachMonths(2013).join('\n'));


Find the last Sunday of each month

Solution:
import sys
import calendar

year = 2013
if len(sys.argv) > 1:
    try:
        year = int(sys.argv[-1])
    except ValueError:
        pass

for month in range(1, 13):
    last_sunday = max(week[-1] for week in calendar.monthcalendar(year, month))
    print('{}-{}-{:2}'.format(year, calendar.month_abbr[month], last_sunday))


Find the missing permutation

ABCD
                    CABD
                    ACDB
                    DACB
                    BCDA
                    ACBD
                    ADCB
                    CDAB
                    DABC
                    BCAD
                    CADB
                    CDBA
                    CBAD
                    ABDC
                    ADBC
                    BDCA
                    DCBA
                    BACD
                    BADC
                    BDAC
                    CBDA
                    DBCA
                    DCAB

Listed above are   all-but-one   of the permutations of the symbols   '''A''',   '''B''',   '''C''',   and   '''D''',   ''except''   for one permutation that's   ''not''   listed.

;Task:
Find that missing permutation.

;Methods:
* Obvious method:
         enumerate all permutations of   '''A''',  '''B''',  '''C''',  and  '''D''',
         and then look for the missing permutation.

* alternate method:
         Hint:  if all permutations were shown above,  how many
         times would  '''A'''  appear in each position?
         What is the  ''parity''  of this number?

* another alternate method:
         Hint:  if you add up the letter values of each column,
         does a missing letter   '''A''',  '''B''',  '''C''',  and  '''D'''   from each
         column cause the total value for each column to be unique?

;Related task:
*   [[Permutations]])

Solution:
#include

#define N 4
const char *perms[] = {
	"ABCD", "CABD", "ACDB", "DACB", "BCDA", "ACBD", "ADCB", "CDAB",
	"DABC", "BCAD", "CADB", "CDBA", "CBAD", "ABDC", "ADBC", "BDCA",
	"DCBA", "BACD", "BADC", "BDAC", "CBDA", "DBCA", "DCAB",
};

int main()
{
	int i, j, n, cnt[N];
	char miss[N];

	for (n = i = 1; i < N; i++) n *= i; /* n = (N-1)!, # of occurrence */

	for (i = 0; i < N; i++) {
		for (j = 0; j < N; j++) cnt[j] = 0;

		/* count how many times each letter occur at position i */
		for (j = 0; j < sizeof(perms)/sizeof(const char*); j++)
			cnt[perms[j][i] - 'A']++;

		/* letter not occurring (N-1)! times is the missing one */
		for (j = 0; j < N && cnt[j] == n; j++);

		miss[i] = j + 'A';
	}
	printf("Missing: %.*s\n", N, miss);

	return 0;

}


Find the missing permutation

Solution:
(function (strList) {

    // [a] -> [[a]]
    function permutations(xs) {
        return xs.length ? (
            chain(xs, function (x) {
                return chain(permutations(deleted(x, xs)), function (ys) {
                    return [[x].concat(ys).join('')];
                })
            })) : [[]];
    }

    // Monadic bind/chain for lists
    // [a] -> (a -> b) -> [b]
    function chain(xs, f) {
        return [].concat.apply([], xs.map(f));
    }

    // a -> [a] -> [a]
    function deleted(x, xs) {
        return xs.length ? (
            x === xs[0] ? xs.slice(1) : [xs[0]].concat(
                deleted(x, xs.slice(1))
            )
        ) : [];
    }

    // Provided subset
    var lstSubSet = strList.split('\n');

    // Any missing permutations
    // (we can use fold/reduce, filter, or chain (concat map) here)
    return chain(permutations('ABCD'.split('')), function (x) {
        return lstSubSet.indexOf(x) === -1 ? [x] : [];
    });

})(
    'ABCD\nCABD\nACDB\nDACB\nBCDA\nACBD\nADCB\nCDAB\nDABC\nBCAD\nCADB\n\
CDBA\nCBAD\nABDC\nADBC\nBDCA\nDCBA\nBACD\nBADC\nBDAC\nCBDA\nDBCA\nDCAB'
);


Find the missing permutation

Solution: ===Python: Calculate difference when compared to all permutations===


Find the missing permutation

Solution:
def missing_permutation(arr):
  "Find the missing permutation in an array of N! - 1 permutations."

  # We won't validate every precondition, but we do have some basic
  # guards.
  if len(arr) == 0: raise Exception("Need more data")
  if len(arr) == 1:
      return [arr[0][1] + arr[0][0]]

  # Now we know that for each position in the string, elements should appear
  # an even number of times (N-1 >= 2).  We can use a set to detect the element appearing
  # an odd number of times.  Detect odd occurrences by toggling admission/expulsion
  # to and from the set for each value encountered.  At the end of each pass one element
  # will remain in the set.
  missing_permutation = ''
  for pos in range(len(arr[0])):
      s = set()
      for permutation in arr:
          c = permutation[pos]
          if c in s:
            s.remove(c)
          else:
            s.add(c)
      missing_permutation += list(s)[0]
  return missing_permutation

given = '''ABCD CABD ACDB DACB BCDA ACBD ADCB CDAB DABC BCAD CADB CDBA
           CBAD ABDC ADBC BDCA DCBA BACD BADC BDAC CBDA DBCA DCAB'''.split()

print missing_permutation(given)


First-class functions/Use numbers analogously

In [[First-class functions]], a language is showing how its manipulation of functions is similar to its manipulation of other types.

This tasks aim is to compare and contrast a language's implementation of first class functions, with its normal handling of numbers.

Write a program to create an ordered collection of a mixture of literally typed and expressions producing a real number, together with another ordered collection of their multiplicative inverses. Try and use the following pseudo-code to generate the numbers for the ordered collections:
   x  = 2.0
   xi = 0.5
   y  = 4.0
   yi = 0.25
   z  = x + y
   zi = 1.0 / ( x + y )

Create a function ''multiplier'', that given two numbers as arguments returns a function that when called with one argument, returns the result of multiplying the two arguments to the call to multiplier that created it and the argument in the call:
  new_function = multiplier(n1,n2)
  # where new_function(m) returns the result of n1 * n2 * m

Applying the multiplier of a number and its inverse from the two ordered collections of numbers in pairs, show that the result in each case is one.
'''Compare and contrast the resultant program with the corresponding entry in [[First-class functions]].''' They should be close.

To paraphrase the task description: Do what was done before, but with numbers rather than functions

Solution:
const x = 2.0;
const xi = 0.5;
const y = 4.0;
const yi = 0.25;
const z = x + y;
const zi = 1.0 / (x + y);
const pairs = [[x, xi], [y, yi], [z, zi]];
const testVal = 0.5;

const multiplier = (a, b) => m => a * b * m;

const test = () => {
  return pairs.map(([a, b]) => {
    const f = multiplier(a, b);
    const result = f(testVal);
    return `${a} * ${b} * ${testVal} = ${result}`;
  });
}

test().join('\n');


Solution:
>>> # Some built in functions and their inverses
>>> from math import sin, cos, acos, asin
>>> # Add a user defined function and its inverse
>>> cube = lambda x: x * x * x
>>> croot = lambda x: x ** (1/3.0)
>>> # First class functions allow run-time creation of functions from functions
>>> # return function compose(f,g)(x) == f(g(x))
>>> compose = lambda f1, f2: ( lambda x: f1(f2(x)) )
>>> # first class functions should be able to be members of collection types
>>> funclist = [sin, cos, cube]
>>> funclisti = [asin, acos, croot]
>>> # Apply functions from lists as easily as integers
>>> [compose(inversef, f)(.5) for f, inversef in zip(funclist, funclisti)]
[0.5, 0.4999999999999999, 0.5]
>>>


First perfect square in base n with n unique digits

Find the first perfect square in a given base '''N''' that has at least '''N''' digits and
exactly '''N''' ''significant unique'' digits when expressed in base '''N'''.

E.G. In base '''10''', the first perfect square with at least '''10''' unique digits is '''1026753849''' ('''32043²''').

You may use analytical methods to reduce the search space, but the code must do a search. Do not use magic numbers or just feed the code the answer to verify it is correct.

;Task

* Find and display here, on this page, the first perfect square in base '''N''', with '''N''' significant unique digits when expressed in base '''N''', for each of base '''2''' through '''12'''. Display each number in the base '''N''' for which it was calculated.

* (optional) Do the same for bases '''13''' through '''16'''.

* (stretch goal) Continue on for bases '''17''' - '''??''' (Big Integer math)

;See also:

;* OEIS A260182: smallest square that is pandigital in base n.

;Related task

;* [[Casting out nines]]

Solution:
#include
#include

#define BUFF_SIZE 32

void toBaseN(char buffer[], long long num, int base) {
    char *ptr = buffer;
    char *tmp;

    // write it backwards
    while (num >= 1) {
        int rem = num % base;
        num /= base;

        *ptr++ = "0123456789ABCDEF"[rem];
    }
    *ptr-- = 0;

    // now reverse it to be written forwards
    for (tmp = buffer; tmp < ptr; tmp++, ptr--) {
        char c = *tmp;
        *tmp = *ptr;
        *ptr = c;
    }
}

int countUnique(char inBuf[]) {
    char buffer[BUFF_SIZE];
    int count = 0;
    int pos, nxt;

    strcpy_s(buffer, BUFF_SIZE, inBuf);

    for (pos = 0; buffer[pos] != 0; pos++) {
        if (buffer[pos] != 1) {
            count++;
            for (nxt = pos + 1; buffer[nxt] != 0; nxt++) {
                if (buffer[nxt] == buffer[pos]) {
                    buffer[nxt] = 1;
                }
            }
        }
    }

    return count;
}

void find(int base) {
    char nBuf[BUFF_SIZE];
    char sqBuf[BUFF_SIZE];
    long long n, s;

    for (n = 2; /*blank*/; n++) {
        s = n * n;
        toBaseN(sqBuf, s, base);
        if (strlen(sqBuf) >= base && countUnique(sqBuf) == base) {
            toBaseN(nBuf, n, base);
            toBaseN(sqBuf, s, base);
            //printf("Base %d : Num %lld Square %lld\n", base, n, s);
            printf("Base %d : Num %8s Square %16s\n", base, nBuf, sqBuf);
            break;
        }
    }
}

int main() {
    int i;

    for (i = 2; i <= 15; i++) {
        find(i);
    }

    return 0;
}


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

    // allDigitSquare :: Int -> Int
    const allDigitSquare = base => {
        const bools = replicate(base, false);
        return untilSucc(
            allDigitsUsedAtBase(base, bools),
            ceil(sqrt(parseInt(
                '10' + '0123456789abcdef'.slice(2, base),
                base
            )))
        );
    };

    // allDigitsUsedAtBase :: Int -> [Bool] -> Int -> Bool
    const allDigitsUsedAtBase = (base, bools) => n => {
        // Fusion of representing the square of integer N at a given base
        // with checking whether all digits of that base contribute to N^2.
        // Sets the bool at a digit position to True when used.
        // True if all digit positions have been used.
        const ds = bools.slice(0);
        let x = n * n;
        while (x) {
            ds[x % base] = true;
            x = floor(x / base);
        }
        return ds.every(x => x)
    };

    // showBaseSquare :: Int -> String
    const showBaseSquare = b => {
        const q = allDigitSquare(b);
        return justifyRight(2, ' ', str(b)) + ' -> ' +
            justifyRight(8, ' ', showIntAtBase(b, digit, q, '')) +
            ' -> ' + showIntAtBase(b, digit, q * q, '');
    };

    // TEST -----------------------------------------------
    const main = () => {
        // 1-12 only - by 15 the squares are truncated by
        // JS integer limits.

        // Returning values through console.log –
        // in separate events to avoid asynchronous disorder.
        print('Smallest perfect squares using all digits in bases 2-12:\n')
      (id > 0 ? chars.substr(id, 1) : " ")    print('Base      Root    Square')

        print(showBaseSquare(2));
        print(showBaseSquare(3));
        print(showBaseSquare(4));
        print(showBaseSquare(5));
        print(showBaseSquare(6));
        print(showBaseSquare(7));
        print(showBaseSquare(8));
        print(showBaseSquare(9));
        print(showBaseSquare(10));
        print(showBaseSquare(11));
        print(showBaseSquare(12));
    };

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

    const
        ceil = Math.ceil,
        floor = Math.floor,
        sqrt = Math.sqrt;

    // Tuple (,) :: a -> b -> (a, b)
    const Tuple = (a, b) => ({
        type: 'Tuple',
        '0': a,
        '1': b,
        length: 2
    });

    // digit :: Int -> Char
    const digit = n =>
        // Digit character for given integer.
        '0123456789abcdef' [n];

    // enumFromTo :: (Int, Int) -> [Int]
    const enumFromTo = (m, n) =>
        Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);

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

    // print :: a -> IO ()
    const print = x => console.log(x)

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

    // replicate :: Int -> a -> [a]
    const replicate = (n, x) =>
        Array.from({
            length: n
        }, () => x);

    // showIntAtBase :: Int -> (Int -> Char) -> Int -> String -> String
    const showIntAtBase = (base, toChr, n, rs) => {
        const go = ([n, d], r) => {
            const r_ = toChr(d) + r;
            return 0 !== n ? (
                go(Array.from(quotRem(n, base)), r_)
            ) : r_;
        };
        return 1 >= base ? (
            'error: showIntAtBase applied to unsupported base'
        ) : 0 > n ? (
            'error: showIntAtBase applied to negative number'
        ) : go(Array.from(quotRem(n, base)), rs);
    };

    // Abbreviation for quick testing - any 2nd arg interpreted as indent size

    // sj :: a -> String
    function sj() {
        const args = Array.from(arguments);
        return JSON.stringify.apply(
            null,
            1 < args.length && !isNaN(args[0]) ? [
                args[1], null, args[0]
            ] : [args[0], null, 2]
        );
    }

    // str :: a -> String
    const str = x => x.toString();

    // untilSucc :: (Int -> Bool) -> Int -> Int
    const untilSucc = (p, x) => {
        // The first in a chain of successive integers
        // for which p(x) returns true.
        let v = x;
        while (!p(v)) v = 1 + v;
        return v;
    };

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


Solution:
'''Perfect squares using every digit in a given base.'''

from itertools import count, dropwhile, repeat
from math import ceil, sqrt
from time import time

# allDigitSquare :: Int -> Int -> Int
def allDigitSquare(base, above):
    '''The lowest perfect square which
       requires all digits in the given base.
    '''
    bools = list(repeat(True, base))
    return next(
        dropwhile(
            missingDigitsAtBase(base, bools),
            count(
                max(
                    above,
                    ceil(sqrt(int(
                        '10' + '0123456789abcdef'[2:base],
                        base
                    )))
                )
            )
        )
    )

# missingDigitsAtBase :: Int -> [Bool] -> Int -> Bool
def missingDigitsAtBase(base, bools):
    '''Fusion of representing the square of integer N at a
       given base with checking whether all digits of
       that base contribute to N^2.
       Clears the bool at a digit position to False when used.
       True if any positions remain uncleared (unused).
    '''
    def go(x):
        xs = bools.copy()
        while x:
            xs[x % base] = False
            x //= base
        return any(xs)
    return lambda n: go(n * n)

# digit :: Int -> Char
def digit(n):
    '''Digit character for given integer.'''
    return '0123456789abcdef'[n]

# ------------------------- TEST -------------------------
# main :: IO ()
def main():
    '''Smallest perfect squares using all digits in bases 2-16'''

    start = time()

    print(main.__doc__ + ':\n\nBase      Root    Square')
    q = 0
    for b in enumFromTo(2)(16):
        q = allDigitSquare(b, q)
        print(
            str(b).rjust(2, ' ') + ' -> ' +
            showIntAtBase(b)(digit)(q)('').rjust(8, ' ') +
            ' -> ' +
            showIntAtBase(b)(digit)(q * q)('')
        )

    print(
        '\nc. ' + str(ceil(time() - start)) + ' seconds.'
    )

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

# enumFromTo :: (Int, Int) -> [Int]
def enumFromTo(m):
    '''Integer enumeration from m to n.'''
    return lambda n: list(range(m, 1 + n))

# showIntAtBase :: Int -> (Int -> String) -> Int ->
# String -> String
def showIntAtBase(base):
    '''String representation of an integer in a given base,
       using a supplied function for the string representation
       of digits.
    '''
    def wrap(toChr, n, rs):
        def go(nd, r):
            n, d = nd
            r_ = toChr(d) + r
            return go(divmod(n, base), r_) if 0 != n else r_
        return 'unsupported base' if 1 >= base else (
            'negative number' if 0 > n else (
                go(divmod(n, base), rs))
        )
    return lambda toChr: lambda n: lambda rs: (
        wrap(toChr, n, rs)
    )

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


First power of 2 that has leading decimal digits of 12

(This task is taken from a   ''Project Euler''   problem.)

(All numbers herein are expressed in base ten.)

'''27   =   128'''   and   '''7'''   is
the first power of   '''2'''   whose leading decimal digits are   '''12'''.

The next power of   '''2'''   whose leading decimal digits
are   '''12'''   is   '''80''',
'''280   =   1208925819614629174706176'''.

Define     '''  '' p''(''L,n'')'''      to be the ''' ''n''th'''-smallest
value of   ''' ''j'' '''   such that the base ten representation
of    '''2''j'''''    begins with the digits of   ''' ''L'' '''.

     So   ''p''(12, 1) =  7    and
          ''p''(12, 2) = 80

You are also given that:
          ''p''(123, 45)   =   12710

;Task:
::*   find:
:::::*     '''   ''p''(12,  1)        '''
:::::*     '''   ''p''(12,  2)        '''
:::::*     '''   ''p''(123, 45)       '''
:::::*     '''   ''p''(123, 12345)    '''
:::::*     '''   ''p''(123, 678910)   '''
::*   display the results here, on this page.

Solution:
#include
#include

int p(int l, int n) {
    int test = 0;
    double logv = log(2.0) / log(10.0);
    int factor = 1;
    int loop = l;
    while (loop > 10) {
        factor *= 10;
        loop /= 10;
    }
    while (n > 0) {
        int val;

        test++;
        val = (int)(factor * pow(10.0, fmod(test * logv, 1)));
        if (val == l) {
            n--;
        }
    }
    return test;
}

void runTest(int l, int n) {
    printf("p(%d, %d) = %d\n", l, n, p(l, n));
}

int main() {
    runTest(12, 1);
    runTest(12, 2);
    runTest(123, 45);
    runTest(123, 12345);
    runTest(123, 678910);

    return 0;
}


Solution:
from math import log, modf, floor

def p(l, n, pwr=2):
    l = int(abs(l))
    digitcount = floor(log(l, 10))
    log10pwr = log(pwr, 10)
    raised, found = -1, 0
    while found < n:
        raised += 1
        firstdigits = floor(10**(modf(log10pwr * raised)[0] + digitcount))
        if firstdigits == l:
            found += 1
    return raised

if __name__ == '__main__':
    for l, n in [(12, 1), (12, 2), (123, 45), (123, 12345), (123, 678910)]:
        print(f"p({l}, {n}) =", p(l, n))


Fivenum

Many big data or scientific programs use boxplots to show distributions of data.   In addition, sometimes saving large arrays for boxplots can be impractical and use extreme amounts of RAM.   It can be useful to save large arrays as arrays with five numbers to save memory.

For example, the   '''R'''   programming language implements Tukey's five-number summary as the '''[https://stat.ethz.ch/R-manual/R-devel/library/stats/html/fivenum.html fivenum]''' function.

;Task:
Given an array of numbers, compute the five-number summary.

;Note:
While these five numbers can be used to draw a boxplot,   statistical packages will typically need extra data.

Moreover, while there is a consensus about the "box" of the boxplot,   there are variations among statistical packages for the whiskers.

Solution:
#include
#include

double median(double *x, int start, int end_inclusive) {
    int size = end_inclusive - start + 1;
    if (size <= 0) {
        printf("Array slice cannot be empty\n");
        exit(1);
    }
    int m = start + size / 2;
    if (size % 2) return x[m];
    return (x[m - 1] + x[m]) / 2.0;
}

int compare (const void *a, const void *b) {
    double aa = *(double*)a;
    double bb = *(double*)b;
    if (aa > bb) return 1;
    if (aa < bb) return -1;
    return 0;
}

int fivenum(double *x, double *result, int x_len) {
    int i, m, lower_end;
    for (i = 0; i < x_len; i++) {
        if (x[i] != x[i]) {
           printf("Unable to deal with arrays containing NaN\n\n");
           return 1;
        }
    }
    qsort(x, x_len, sizeof(double), compare);
    result[0] = x[0];
    result[2] = median(x, 0, x_len - 1);
    result[4] = x[x_len - 1];
    m = x_len / 2;
    lower_end = (x_len % 2) ? m : m - 1;
    result[1] = median(x, 0, lower_end);
    result[3] = median(x, m, x_len - 1);
    return 0;
}

int show(double *result, int places) {
    int i;
    char f[7];
    sprintf(f, "%%.%dlf", places);
    printf("[");
    for (i = 0; i < 5; i++) {
        printf(f, result[i]);
        if (i < 4) printf(", ");
    }
    printf("]\n\n");
}

int main() {
    double result[5];

    double x1[11] = {15.0, 6.0, 42.0, 41.0, 7.0, 36.0, 49.0, 40.0, 39.0, 47.0, 43.0};
    if (!fivenum(x1, result, 11)) show(result, 1);

    double x2[6] = {36.0, 40.0, 7.0, 39.0, 41.0, 15.0};
    if (!fivenum(x2, result, 6)) show(result, 1);

    double x3[20] = {
         0.14082834,  0.09748790,  1.73131507,  0.87636009, -1.95059594,  0.73438555,
        -0.03035726,  1.46675970, -0.74621349, -0.72588772,  0.63905160,  0.61501527,
        -0.98983780, -1.00447874, -0.62759469,  0.66206163,  1.04312009, -0.10305385,
         0.75775634,  0.32566578
    };
    if (!fivenum(x3, result, 20)) show(result, 9);

    return 0;
}


Fivenum

Solution:
function median(arr) {
  let mid = Math.floor(arr.length / 2);
  return (arr.length % 2 == 0) ? (arr[mid-1] + arr[mid]) / 2 : arr[mid];
}

Array.prototype.fiveNums = function() {
  this.sort(function(a, b) { return a - b} );
  let mid = Math.floor(this.length / 2),
      loQ = (this.length % 2 == 0) ? this.slice(0, mid) : this.slice(0, mid+1),
      hiQ = this.slice(mid);
  return [ this[0],
           median(loQ),
           median(this),
           median(hiQ),
           this[this.length-1] ];
}

// testing
let test = [15, 6, 42, 41, 7, 36, 49, 40, 39, 47, 43];
console.log( test.fiveNums() );

test = [0, 0, 1, 2, 63, 61, 27, 13];
console.log( test.fiveNums() );

test = [ 0.14082834,  0.09748790,  1.73131507,  0.87636009, -1.95059594,
         0.73438555, -0.03035726,  1.46675970, -0.74621349, -0.72588772,
         0.63905160,  0.61501527, -0.98983780, -1.00447874, -0.62759469,
         0.66206163,  1.04312009, -0.10305385,  0.75775634,  0.32566578];
console.log( test.fiveNums() );


Fivenum

Solution:
from __future__ import division
import math
import sys

def fivenum(array):
    n = len(array)
    if n == 0:
        print("you entered an empty array.")
        sys.exit()
    x = sorted(array)

    n4 = math.floor((n+3.0)/2.0)/2.0
    d = [1, n4, (n+1)/2, n+1-n4, n]
    sum_array = []

    for e in range(5):
        floor = int(math.floor(d[e] - 1))
        ceil = int(math.ceil(d[e] - 1))
        sum_array.append(0.5 * (x[floor] + x[ceil]))

    return sum_array

x = [0.14082834, 0.09748790, 1.73131507, 0.87636009, -1.95059594, 0.73438555, -0.03035726, 1.46675970,
-0.74621349, -0.72588772, 0.63905160, 0.61501527, -0.98983780, -1.00447874, -0.62759469, 0.66206163,
1.04312009, -0.10305385, 0.75775634, 0.32566578]

y = fivenum(x)
print(y)


Fixed length records

Fixed length read/write

Before terminals, computers commonly used [https://en.wikipedia.org/wiki/Punched_card_reader punch card readers] or paper tape input.

A common format before these devices were superseded by terminal technology was based on the Hollerith code, [https://en.wikipedia.org/wiki/Hollerith_card Hollerith code].

These input devices handled 80 columns per card and had a limited character set, encoded by punching holes in one or more rows of the card for each column.

These devices assumed/demanded a fixed line width of 80 characters, newlines were not required (and could not even be encoded in some systems).

;Task:
Write a program to read 80 column fixed length records (no newline terminators (but newline characters allowed in the data)) and then write out the reverse of each line as fixed length 80 column records.

Samples here use printable characters, but that is not a given with fixed length data.  Filenames used are sample.txt, infile.dat, outfile.dat.

'''Note:''' There are no newlines, inputs and outputs are fixed at 80 columns, no more, no less, space padded.  Fixed length data is 8 bit complete.  NUL bytes of zero are allowed.

These fixed length formats are still in wide use on mainframes, with JCL and with COBOL (which commonly use [https://en.wikipedia.org/wiki/EBCDIC EBCDIC] encoding and not [https://en.wikipedia.org/wiki/ASCII ASCII]).  Most of the large players in day to day financial transactions know all about fixed length records and the expression ''logical record length''.

;Sample data:
To create the sample input file, use an editor that supports fixed length records or use a conversion utility.  For instance, most GNU/Linux versions of '''dd''' support blocking and unblocking records with a conversion byte size.

Line 1...1.........2.........3.........4.........5.........6.........7.........8
Line 2
Line 3
Line 4

Line 6
Line 7
     Indented line 8............................................................
Line 9                                                                 RT MARGIN
prompt$ dd if=sample.txt of=infile.dat cbs=80 conv=block will create a fixed length record file of 80 bytes given newline delimited text input.

prompt$ dd if=infile.dat cbs=80 conv=unblock will display a file with 80 byte logical record lengths to standard out as standard text with newlines.

;Bonus round:
Forth systems often include BLOCK words.  A block is 1024 bytes.  Source code is stored as 16 lines of 64 characters each (again, no newline character or sequence to mark the end of a line).

Write a program to convert a block file to text (using newlines). Trailing spaces should be excluded from the output.

Also demonstrate how to convert from a normal text file to block form. All lines either truncated or padded to 64 characters with no newline terminators. The last block filled to be exactly 1024 characters by adding blanks if needed. Assume a full range of 8 bit byte values for each character.

The COBOL example uses forth.txt and forth.blk filenames.

Solution:
infile = open('infile.dat', 'rb')
outfile = open('outfile.dat', 'wb')

while True:
    onerecord = infile.read(80)
    if len(onerecord) < 80:
        break
    onerecordreversed = bytes(reversed(onerecord))
    outfile.write(onerecordreversed)

infile.close()
outfile.close()


Flatten a list

;Task:
Write a function to flatten the nesting in an arbitrary list of values.

Your program should work on the equivalent of this list:
   [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
Where the correct result would be the list:
    [1, 2, 3, 4, 5, 6, 7, 8]

;Related task:
*   [[Tree traversal]]

Solution:
#include
#include
#include

typedef struct list_t list_t, *list;
struct list_t{
	int is_list, ival; /* ival is either the integer value or list length */
	list *lst;
};

list new_list()
{
	list x = malloc(sizeof(list_t));
	x->ival = 0;
	x->is_list = 1;
	x->lst = 0;
	return x;
}

void append(list parent, list child)
{
	parent->lst = realloc(parent->lst, sizeof(list) * (parent->ival + 1));
	parent->lst[parent->ival++] = child;
}

list from_string(char *s, char **e, list parent)
{
	list ret = 0;
	if (!parent) parent = new_list();

	while (*s != '\0') {
		if (*s == ']') {
			if (e) *e = s + 1;
			return parent;
		}
		if (*s == '[') {
			ret = new_list();
			ret->is_list = 1;
			ret->ival = 0;
			append(parent, ret);
			from_string(s + 1, &s, ret);
			continue;
		}
		if (*s >= '0' && *s <= '9') {
			ret = new_list();
			ret->is_list = 0;
			ret->ival = strtol(s, &s, 10);
			append(parent, ret);
			continue;
		}
		s++;
	}

	if (e) *e = s;
	return parent;
}

void show_list(list l)
{
	int i;
	if (!l) return;
	if (!l->is_list) {
		printf("%d", l->ival);
		return;
	}

	printf("[");
	for (i = 0; i < l->ival; i++) {
		show_list(l->lst[i]);
		if (i < l->ival - 1) printf(", ");
	}
	printf("]");
}

list flatten(list from, list to)
{
	int i;
	list t;

	if (!to) to = new_list();
	if (!from->is_list) {
		t = new_list();
		*t = *from;
		append(to, t);
	} else
		for (i = 0; i < from->ival; i++)
			flatten(from->lst[i], to);
	return to;
}

void delete_list(list l)
{
	int i;
	if (!l) return;
	if (l->is_list && l->ival) {
		for (i = 0; i < l->ival; i++)
			delete_list(l->lst[i]);
		free(l->lst);
	}

	free(l);
}

int main()
{
	list l = from_string("[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []", 0, 0);

	printf("Nested: ");
	show_list(l);
	printf("\n");

	list flat = flatten(l, 0);
	printf("Flattened: ");
	show_list(flat);

	/* delete_list(l); delete_list(flat); */
	return 0;
}


Flatten a list

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

    // flatten :: Tree a -> [a]
    function flatten(t) {
        return (t instanceof Array ? concatMap(flatten, t) : t);
    }

    // concatMap :: (a -> [b]) -> [a] -> [b]
    function concatMap(f, xs) {
        return [].concat.apply([], xs.map(f));
    }

    return flatten(
        [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
    );

})();


Flatten a list

Solution:
>>> def flatten(itr):
>>>    for x in itr:
>>>        try:
>>>            yield from flatten(x)
>>>        except:
>>>            yield x

>>> lst = [[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]

>>> list(flatten(lst))
[1, 2, 3, 4, 5, 6, 7, 8]

>>> tuple(flatten(lst))
(1, 2, 3, 4, 5, 6, 7, 8)

>>>for i in flatten(lst):
>>>    print(i)
1
2
3
4
5
6
7
8


Flatten a list

Solution:
'''Flatten a nested list'''

from itertools import (chain)

# ----------------------- FLATTEN ------------------------

# flatten :: NestedList a -> [a]
def flatten(x):
    '''A list of atomic values resulting from fully
       flattening an arbitrarily nested list.
    '''
    return concatMap(flatten)(x) if (
        isinstance(x, list)
    ) else [x]

# ------------------------- TEST -------------------------
def main():
    '''Test: flatten an arbitrarily nested list.
    '''
    print(
        fTable(__doc__ + ':')(showList)(showList)(
            flatten
        )([
            [[[]]],
            [[1, 2, 3]],
            [[1], [[2]], [[[3, 4]]]],
            [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]
        ])
    )

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

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

# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
    '''A concatenated list over which a function has been mapped.
       The list monad can be derived by using a function f which
       wraps its output in a list,
       (using an empty list to represent computational failure).
    '''
    def go(xs):
        return chain.from_iterable(map(f, xs))
    return go

# fTable :: String -> (a -> String) ->
#                     (b -> String) ->
#        (a -> b) -> [a] -> String
def fTable(s):
    '''Heading -> x display function ->
                 fx display function ->
          f -> value list -> tabular string.'''
    def go(xShow, fxShow, f, xs):
        w = max(map(compose(len)(xShow), 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
    )

# showList :: [a] -> String
def showList(xs):
    '''Stringification of a list.'''
    return '[' + ','.join(str(x) for x in xs) + ']'

if __name__ == '__main__':
    main()


Flipping bits game

[[Category:Games]]

;The game:
Given an   '''N×N'''   square array of zeroes or ones in an initial configuration,   and a target configuration of zeroes and ones.

The game is to transform one to the other in as few moves as possible by inverting whole numbered rows or whole lettered
columns at once   (as one move).

In an inversion.   any  '''1'''  becomes  '''0''',   and any  '''0'''  becomes  '''1'''  for that whole row or column.

;Task:
Create a program to score for the Flipping bits game.
# The game should create an original random target configuration and a starting configuration.
# Ensure that the starting position is ''never'' the target position.
# The target position must be guaranteed as reachable from the starting position.   (One possible way to do this is to generate the start position by legal flips from a random target position.   The flips will always be reversible back to the target from the given start position).
# The number of moves taken so far should be shown.

Show an example of a short game here, on this page, for a   '''3×3'''   array of bits.

Solution:
#include
#include

int i, j;

void fliprow(int **b, int sz, int n)
{
	for(i = 0; i < sz; i++)
		b[n+1][i] = !b[n+1][i];
}

void flipcol(int **b, int sz, int n)
{
	for(i = 1; i <= sz; i++)
		b[i][n] = !b[i][n];
}

void initt(int **t, int sz)
{
	for(i = 1; i <= sz; i++)
		for(j = 0; j < sz; j++)
			t[i][j] = rand()%2;
}

void initb(int **t, int **b, int sz)
{
	for(i = 1; i <= sz; i++)
		for(j = 0; j < sz; j++)
			b[i][j] = t[i][j];

	for(i = 1; i <= sz; i++)
		fliprow(b, sz, rand()%sz+1);
	for(i = 0; i < sz; i++)
		flipcol(b, sz, rand()%sz);
}

void printb(int **b, int sz)
{
	printf(" ");
	for(i = 0; i < sz; i++)
		printf(" %d", i);
	printf("\n");

	for(i = 1; i <= sz; i++)
	{
		printf("%d", i-1);
		for(j = 0; j < sz; j++)
			printf(" %d", b[i][j]);
		printf("\n");
	}

	printf("\n");
}

int eq(int **t, int **b, int sz)
{
	for(i = 1; i <= sz; i++)
		for(j = 0; j < sz; j++)
			if(b[i][j] != t[i][j])
				return 0;
	return 1;
}

void main()
{
	int sz = 3;
	int eql = 0;
	int mov = 0;
	int **t = malloc(sz*(sizeof(int)+1));
	for(i = 1; i <= sz; i++)
		t[i] = malloc(sz*sizeof(int));

	int **b = malloc(sz*(sizeof(int)+1));
	for(i = 1; i <= sz; i++)
		b[i] = malloc(sz*sizeof(int));
	char roc;
	int n;
	initt(t, sz);
	initb(t, b, sz);

	while(eq(t, b, sz))
		initb(t, b, sz);

	while(!eql)
	{
		printf("Target: \n");
		printb(t, sz);
		printf("Board: \n");
		printb(b, sz);
		printf("What to flip: ");
		scanf(" %c", &roc);
		scanf(" %d", &n);

		switch(roc)
		{
			case 'r':
				fliprow(b, sz, n);
				break;
			case 'c':
				flipcol(b, sz, n);
				break;
			default:
				perror("Please specify r or c and an number");
				break;
		}

		printf("Moves Taken: %d\n", ++mov);

		if(eq(t, b, sz))
		{
			printf("You win!\n");
			eql = 1;
		}
	}
}


Flipping bits game

Solution:
function numOfRows(board) { return board.length; }
function numOfCols(board) { return board[0].length; }
function boardToString(board) {
    // First the top-header
    var header = '   ';
    for (var c = 0; c < numOfCols(board); c++)
        header += c + ' ';

    // Then the side-header + board
    var sideboard = [];
    for (var r = 0; r < numOfRows(board); r++) {
        sideboard.push(r + ' [' + board[r].join(' ') + ']');
    }

    return header + '\n' + sideboard.join('\n');
}
function flipRow(board, row) {
    for (var c = 0; c < numOfCols(board); c++) {
        board[row][c] = 1 - board[row][c];
    }
}
function flipCol(board, col) {
    for (var r = 0; r < numOfRows(board); r++) {
        board[r][col] = 1 - board[r][col];
    }
}

function playFlippingBitsGame(rows, cols) {
    rows = rows | 3;
    cols = cols | 3;
    var targetBoard = [];
    var manipulatedBoard = [];
    // Randomly generate two identical boards.
    for (var r = 0; r < rows; r++) {
        targetBoard.push([]);
        manipulatedBoard.push([]);
        for (var c = 0; c < cols; c++) {
            targetBoard[r].push(Math.floor(Math.random() * 2));
            manipulatedBoard[r].push(targetBoard[r][c]);
        }
    }
    // Naive-scramble one of the boards.
    while (boardToString(targetBoard) == boardToString(manipulatedBoard)) {
        var scrambles = rows * cols;
        while (scrambles-- > 0) {
            if (0 == Math.floor(Math.random() * 2)) {
                flipRow(manipulatedBoard, Math.floor(Math.random() * rows));
            }
            else {
                flipCol(manipulatedBoard, Math.floor(Math.random() * cols));
            }
        }
    }
    // Get the user to solve.
    alert(
        'Try to match both boards.\n' +
        'Enter `r` or `c` to manipulate a row or col or enter `q` to quit.'
        );
    var input = '', letter, num, moves = 0;
    while (boardToString(targetBoard) != boardToString(manipulatedBoard) && input != 'q') {
        input = prompt(
            'Target:\n' + boardToString(targetBoard) +
            '\n\n\n' +
            'Board:\n' + boardToString(manipulatedBoard)
            );
        try {
            letter = input.charAt(0);
            num = parseInt(input.slice(1));
            if (letter == 'q')
				break;
            if (isNaN(num)
                || (letter != 'r' && letter != 'c')
                || (letter == 'r' && num >= rows)
                || (letter == 'c' && num >= cols)
                ) {
                throw new Error('');
            }
            if (letter == 'r') {
                flipRow(manipulatedBoard, num);
            }
            else {
                flipCol(manipulatedBoard, num);
            }
            moves++;
        }
        catch(e) {
            alert('Uh-oh, there seems to have been an input error');
        }
    }
    if (input == 'q') {
        alert('~~ Thanks for playing ~~');
    }
    else {
        alert('Completed in ' + moves + ' moves.');
    }
}


Flipping bits game

Solution:
"""
Given a %i by %i sqare array of zeroes or ones in an initial
configuration, and a target configuration of zeroes and ones
The task is to transform one to the other in as few moves as
possible by inverting whole numbered rows or whole lettered
columns at once.
In an inversion any 1 becomes 0 and any 0 becomes 1 for that
whole row or column.

"""

from random import randrange
from copy import deepcopy
from string import ascii_lowercase

try:    # 2to3 fix
    input = raw_input
except:
    pass

N = 3   # N x N Square arrray

board  = [[0]* N for i in range(N)]

def setbits(board, count=1):
    for i in range(count):
        board[randrange(N)][randrange(N)] ^= 1

def shuffle(board, count=1):
    for i in range(count):
        if randrange(0, 2):
            fliprow(randrange(N))
        else:
            flipcol(randrange(N))

def pr(board, comment=''):
    print(str(comment))
    print('     ' + ' '.join(ascii_lowercase[i] for i in range(N)))
    print('  ' + '\n  '.join(' '.join(['%2s' % j] + [str(i) for i in line])
                             for j, line in enumerate(board, 1)))

def init(board):
    setbits(board, count=randrange(N)+1)
    target = deepcopy(board)
    while board == target:
        shuffle(board, count=2 * N)
    prompt = '  X, T, or 1-%i / %s-%s to flip: ' % (N, ascii_lowercase[0],
                                                    ascii_lowercase[N-1])
    return target, prompt

def fliprow(i):
    board[i-1][:] = [x ^ 1 for x in board[i-1] ]

def flipcol(i):
    for row in board:
        row[i] ^= 1

if __name__ == '__main__':
    print(__doc__ % (N, N))
    target, prompt = init(board)
    pr(target, 'Target configuration is:')
    print('')
    turns = 0
    while board != target:
        turns += 1
        pr(board, '%i:' % turns)
        ans = input(prompt).strip()
        if (len(ans) == 1
            and ans in ascii_lowercase and ascii_lowercase.index(ans) < N):
            flipcol(ascii_lowercase.index(ans))
        elif ans and all(ch in '0123456789' for ch in ans) and 1 <= int(ans) <= N:
            fliprow(int(ans))
        elif ans == 'T':
            pr(target, 'Target configuration is:')
            turns -= 1
        elif ans == 'X':
            break
        else:
            print("  I don't understand %r... Try again. "
                  "(X to exit or T to show target)\n" % ans[:9])
            turns -= 1
    else:
        print('\nWell done!\nBye.')


Floyd's triangle

Floyd's triangle   lists the natural numbers in a right triangle aligned to the left where
* the first row is   '''1'''     (unity)
* successive rows start towards the left with the next number followed by successive naturals listing one more number than the line above.

The first few lines of a Floyd triangle looks like this:

 1
 2  3
 4  5  6
 7  8  9 10
11 12 13 14 15

;Task:
:# Write a program to generate and display here the first   n   lines of a Floyd triangle. (Use   n=5   and   n=14   rows).
:# Ensure that when displayed in a mono-space font, the numbers line up in vertical columns as shown and that only one space separates numbers of the last row.

Solution:
#include

void t(int n)
{
	int i, j, c, len;

	i = n * (n - 1) / 2;
	for (len = c = 1; c < i; c *= 10, len++);
	c -= i; // c is the col where width changes

#define SPEED_MATTERS 0
#if SPEED_MATTERS	// in case we really, really wanted to print huge triangles often
	char tmp[32], s[4096], *p;

	sprintf(tmp, "%*d", len, 0);

	inline void inc_numstr(void) {
		int k = len;

	redo:	if (!k--) return;

		if (tmp[k] == '9') {
			tmp[k] = '0';
			goto redo;
		}

		if (++tmp[k] == '!')
			tmp[k] = '1';
	}

	for (p = s, i = 1; i <= n; i++) {
		for (j = 1; j <= i; j++) {
			inc_numstr();
			__builtin_memcpy(p, tmp + 1 - (j >= c), len - (j < c));
			p += len - (j < c);

			*(p++) = (i - j)? ' ' : '\n';

			if (p - s + len >= 4096) {
				fwrite(s, 1, p - s, stdout);
				p = s;
			}
		}
	}

	fwrite(s, 1, p - s, stdout);
#else // NO_IT_DOESN'T
	int num;
	for (num = i = 1; i <= n; i++)
		for (j = 1; j <= i; j++)
			printf("%*d%c",	len - (j < c), num++, i - j ? ' ':'\n');
#endif
}

int main(void)
{
	t(5), t(14);

	// maybe not
	// t(10000);
	return 0;
}


Floyd's triangle

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

    // FLOYD's TRIANGLE -------------------------------------------------------

    // floyd :: Int -> [[Int]]
    function floyd(n) {
        return snd(mapAccumL(function (start, row) {
            return [start + row + 1, enumFromTo(start, start + row)];
        }, 1, enumFromTo(0, n - 1)));
    };

    // showFloyd :: [[Int]] -> String
    function showFloyd(xss) {
        var ws = map(compose([succ, length, show]), last(xss));
        return unlines(map(function (xs) {
            return concat(zipWith(function (w, x) {
                return justifyRight(w, ' ', show(x));
            }, ws, xs));
        }, xss));
    };

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

    // compose :: [(a -> a)] -> (a -> a)
    function compose(fs) {
        return function (x) {
            return fs.reduceRight(function (a, f) {
                return f(a);
            }, x);
        };
    };

    // concat :: [[a]] -> [a] | [String] -> String
    function concat(xs) {
        if (xs.length > 0) {
            var unit = typeof xs[0] === 'string' ? '' : [];
            return unit.concat.apply(unit, xs);
        } else return [];
    };

    // enumFromTo :: Int -> Int -> [Int]
    function enumFromTo(m, n) {
        return Array.from({
            length: Math.floor(n - m) + 1
        }, function (_, i) {
            return m + i;
        });
    };

    // justifyRight :: Int -> Char -> Text -> Text
    function justifyRight(n, cFiller, strText) {
        return n > strText.length ? (cFiller.repeat(n) + strText)
            .slice(-n) : strText;
    };

    // last :: [a] -> a
    function last(xs) {
        return xs.length ? xs.slice(-1)[0] : undefined;
    };

    // length :: [a] -> Int
    function length(xs) {
        return xs.length;
    };

    // map :: (a -> b) -> [a] -> [b]
    function map(f, xs) {
        return xs.map(f);
    };

    // 'The mapAccumL function behaves like a combination of map and foldl;
    // it applies a function to each element of a list, passing an accumulating
    // parameter from left to right, and returning a final value of this
    // accumulator together with the new list.' (See hoogle )

    // mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
    function mapAccumL(f, acc, xs) {
        return xs.reduce(function (a, x) {
            var pair = f(a[0], x);

            return [pair[0], a[1].concat([pair[1]])];
        }, [acc, []]);
    };

    // show ::
    // (a -> String) f,  Num n =>
    // a -> maybe f -> maybe n -> String
    var show = JSON.stringify;

    // snd :: (a, b) -> b
    function snd(tpl) {
        return Array.isArray(tpl) ? tpl[1] : undefined;
    };

    // succ :: Int -> Int
    function succ(x) {
        return x + 1;
    };

    // unlines :: [String] -> String
    function unlines(xs) {
        return xs.join('\n');
    };

    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    function zipWith(f, xs, ys) {
        var ny = ys.length;
        return (xs.length <= ny ? xs : xs.slice(0, ny))
            .map(function (x, i) {
                return f(x, ys[i]);
            });
    };

    // TEST ( n=5 and n=14 rows ) ---------------------------------------------

    return unlines(map(function (n) {
        return showFloyd(floyd(n)) + '\n';
    }, [5, 14]));
})();


Floyd's triangle

Solution:
>>> def floyd(rowcount=5):
	rows = [[1]]
	while len(rows) < rowcount:
		n = rows[-1][-1] + 1
		rows.append(list(range(n, n + len(rows[-1]) + 1)))
	return rows

>>> floyd()
[[1], [2, 3], [4, 5, 6], [7, 8, 9, 10], [11, 12, 13, 14, 15]]
>>> def pfloyd(rows=[[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]):
	colspace = [len(str(n)) for n in rows[-1]]
	for row in rows:
		print( ' '.join('%*i' % space_n for space_n in zip(colspace, row)))

>>> pfloyd()
1
2 3
4 5 6
7 8 9 10
>>> pfloyd(floyd(5))
 1
 2  3
 4  5  6
 7  8  9 10
11 12 13 14 15
>>> pfloyd(floyd(14))
 1
 2  3
 4  5  6
 7  8  9 10
11 12 13 14 15
16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 32 33 34 35 36
37 38 39 40 41 42 43 44  45
46 47 48 49 50 51 52 53  54  55
56 57 58 59 60 61 62 63  64  65  66
67 68 69 70 71 72 73 74  75  76  77  78
79 80 81 82 83 84 85 86  87  88  89  90  91
92 93 94 95 96 97 98 99 100 101 102 103 104 105
>>>


Floyd's triangle

Solution:
'''Floyd triangle in terms of iterate(f)(x)'''

from itertools import islice

# floyd :: Int -> [[Int]]
def floyd(n):
    '''n rows of a Floyd triangle.'''
    return take(n)(iterate(nextFloyd)([1]))

# nextFloyd :: [Int] -> [Int]
def nextFloyd(xs):
    '''A Floyd triangle row derived from
       the preceding row.'''
    n = succ(len(xs))
    return [1] if n < 2 else (
        enumFromTo(succ(n * pred(n) // 2))(
            n * succ(n) // 2
        )
    )

# showFloyd :: [[Int]] -> String
def showFloyd(xs):
    '''A stringification of Floyd triangle rows.'''
    return unlines(str(x) for x in xs)

# main :: IO ()
def main():
    '''Test'''
    print(showFloyd(
        floyd(5)
    ))

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

# enumFromTo :: (Int, Int) -> [Int]
def enumFromTo(m):
    '''Integer enumeration from m to n.'''
    return lambda n: list(range(m, 1 + n))

# iterate :: (a -> a) -> a -> Gen [a]
def iterate(f):
    '''An infinite list of repeated applications of f to x.'''
    def go(x):
        v = x
        while True:
            yield v
            v = f(v)
    return lambda x: go(x)

# pred ::  Enum a => a -> a
def pred(x):
    '''The predecessor of a value. For numeric types, (- 1).'''
    return x - 1 if isinstance(x, int) else (
        chr(ord(x) - 1)
    )

# succ :: Enum a => a -> a
def succ(x):
    '''The successor of a value. For numeric types, (1 +).'''
    return 1 + x if isinstance(x, int) else (
        chr(1 + ord(x))
    )

# take :: Int -> [a] -> [a]
# take :: Int -> String -> String
def take(n):
    '''The prefix of xs of length n,
       or xs itself if n > length xs.'''
    return lambda xs: (
        xs[0:n]
        if isinstance(xs, list)
        else list(islice(xs, n))
    )

# unlines :: [String] -> String
def unlines(xs):
    '''A single string derived by the intercalation
       of a list of strings with the newline character.'''
    return '\n'.join(xs)

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


Four bit adder

;Task:
"''Simulate''" a four-bit adder.

This design can be realized using four 1-bit full adders.
Each of these 1-bit full adders can be built with two gate. ;

Finally a half adder can be made using an   ''xor''   gate and an   ''and''   gate.

The   ''xor''   gate can be made using two   ''not''s,   two   ''and''s   and one   ''or''.

'''Not''',   '''or'''   and   '''and''',   the only allowed "gates" for the task, can be "imitated" by using the bitwise operators of your language.

If there is not a ''bit type'' in your language, to be sure that the   ''not''   does not "invert" all the other bits of the basic type   (e.g. a byte)   we are not interested in,   you can use an extra   ''nand''   (''and''   then   ''not'')   with the constant   '''1'''   on one input.

Instead of optimizing and reducing the number of gates used for the final 4-bit adder,   build it in the most straightforward way,   ''connecting'' the other "constructive blocks",   in turn made of "simpler" and "smaller" ones.

{|
|+Schematics of the "constructive blocks"
!(Xor gate with ANDs, ORs and NOTs)
!   (A half adder)
!          (A full adder)
!                (A 4-bit adder)
|-
|Xor gate done with ands, ors and nots
|A half adder
|A full adder
|A 4-bit adder
|}

Solutions should try to be as descriptive as possible, making it as easy as possible to identify "connections" between higher-order "blocks".

It is not mandatory to replicate the syntax of higher-order blocks in the atomic "gate" blocks, i.e. basic "gate" operations can be performed as usual bitwise operations, or they can be "wrapped" in a ''block'' in order to expose the same syntax of higher-order blocks, at implementers' choice.

To test the implementation, show the sum of two four-bit numbers (in binary).

Solution:
#include

typedef char pin_t;
#define IN const pin_t *
#define OUT pin_t *
#define PIN(X) pin_t _##X; pin_t *X = & _##X;
#define V(X) (*(X))

/* a NOT that does not soil the rest of the host of the single bit */
#define NOT(X) (~(X)&1)

/* a shortcut to "implement" a XOR using only NOT, AND and OR gates, as
   task requirements constrain */
#define XOR(X,Y) ((NOT(X)&(Y)) | ((X)&NOT(Y)))

void halfadder(IN a, IN b, OUT s, OUT c)
{
  V(s) = XOR(V(a), V(b));
  V(c) = V(a) & V(b);
}

void fulladder(IN a, IN b, IN ic, OUT s, OUT oc)
{
  PIN(ps); PIN(pc); PIN(tc);

  halfadder(/*INPUT*/a, b, /*OUTPUT*/ps, pc);
  halfadder(/*INPUT*/ps, ic, /*OUTPUT*/s, tc);
  V(oc) = V(tc) | V(pc);
}

void fourbitsadder(IN a0, IN a1, IN a2, IN a3,
		   IN b0, IN b1, IN b2, IN b3,
		   OUT o0, OUT o1, OUT o2, OUT o3,
		   OUT overflow)
{
  PIN(zero); V(zero) = 0;
  PIN(tc0); PIN(tc1); PIN(tc2);

  fulladder(/*INPUT*/a0, b0, zero, /*OUTPUT*/o0, tc0);
  fulladder(/*INPUT*/a1, b1, tc0,  /*OUTPUT*/o1, tc1);
  fulladder(/*INPUT*/a2, b2, tc1,  /*OUTPUT*/o2, tc2);
  fulladder(/*INPUT*/a3, b3, tc2,  /*OUTPUT*/o3, overflow);
}

int main()
{
  PIN(a0); PIN(a1); PIN(a2); PIN(a3);
  PIN(b0); PIN(b1); PIN(b2); PIN(b3);
  PIN(s0); PIN(s1); PIN(s2); PIN(s3);
  PIN(overflow);

  V(a3) = 0; V(b3) = 1;
  V(a2) = 0; V(b2) = 1;
  V(a1) = 1; V(b1) = 1;
  V(a0) = 0; V(b0) = 0;

  fourbitsadder(a0, a1, a2, a3, /* INPUT */
		b0, b1, b2, b3,
		s0, s1, s2, s3, /* OUTPUT */
		overflow);

  printf("%d%d%d%d + %d%d%d%d = %d%d%d%d, overflow = %d\n",
	 V(a3), V(a2), V(a1), V(a0),
	 V(b3), V(b2), V(b1), V(b0),
	 V(s3), V(s2), V(s1), V(s0),
	 V(overflow));

  return 0;
}


Four bit adder

Solution:
// basic building blocks allowed by the rules are ~, &, and |, we'll fake these
// in a way that makes what they do (at least when you use them) more obvious
// than the other available options do.

function not(a) {
    if (arePseudoBin(a))
        return a == 1 ? 0 : 1;
}

function and(a, b) {
    if (arePseudoBin(a, b))
        return a + b < 2 ? 0 : 1;
}

function nand(a, b) {
    if (arePseudoBin(a, b))
        return not(and(a, b));
}

function or(a, b) {
    if (arePseudoBin(a, b))
        return nand(nand(a,a), nand(b,b));
}

function xor(a, b) {
    if (arePseudoBin(a, b))
        return nand(nand(nand(a,b), a), nand(nand(a,b), b));
}

function halfAdder(a, b) {
    if (arePseudoBin(a, b))
        return { carry: and(a, b), sum: xor(a, b) };
}

function fullAdder(a, b, c) {
    if (arePseudoBin(a, b, c)) {
        var h0 = halfAdder(a, b),
            h1 = halfAdder(h0.sum, c);
        return {carry: or(h0.carry, h1.carry), sum: h1.sum };
    }
}

function fourBitAdder(a, b) {
    if (typeof a.length == 'undefined' || typeof b.length == 'undefined')
        throw new Error('bad values');
    // not sure if the rules allow this, but we need to pad the values
    // if they're too short and trim them if they're too long
    var inA = Array(4),
        inB = Array(4),
        out = Array(4),
        i = 4,
        pass;

    while (i--) {
        inA[i] = a[i] != 1 ? 0 : 1;
        inB[i] = b[i] != 1 ? 0 : 1;
    }

    // now we can start adding... I'd prefer to do this in a loop,
    // but that wouldn't be "connecting the other 'constructive blocks',
    // in turn made of 'simpler' and 'smaller' ones"

    pass = halfAdder(inA[3], inB[3]);
    out[3] = pass.sum;
    pass = fullAdder(inA[2], inB[2], pass.carry);
    out[2] = pass.sum;
    pass = fullAdder(inA[1], inB[1], pass.carry);
    out[1] = pass.sum;
    pass = fullAdder(inA[0], inB[0], pass.carry);
    out[0] = pass.sum;
    return out.join('');
}


Four bit adder

Solution:
def xor(a, b): return (a and not b) or (b and not a)

def ha(a, b): return xor(a, b), a and b     # sum, carry

def fa(a, b, ci):
    s0, c0 = ha(ci, a)
    s1, c1 = ha(s0, b)
    return s1, c0 or c1     # sum, carry

def fa4(a, b):
    width = 4
    ci = [None] * width
    co = [None] * width
    s  = [None] * width
    for i in range(width):
        s[i], co[i] = fa(a[i], b[i], co[i-1] if i else 0)
    return s, co[-1]

def int2bus(n, width=4):
    return [int(c) for c in "{0:0{1}b}".format(n, width)[::-1]]

def bus2int(b):
    return sum(1 << i for i, bit in enumerate(b) if bit)

def test_fa4():
    width = 4
    tot = [None] * (width + 1)
    for a in range(2**width):
        for b in range(2**width):
            tot[:width], tot[width] = fa4(int2bus(a), int2bus(b))
            assert a + b == bus2int(tot), "totals don't match: %i + %i != %s" % (a, b, tot)

if __name__ == '__main__':
   test_fa4()


Four is magic

;Task:
Write a subroutine, function, whatever it may be called in your language, that takes an integer number and returns an English text sequence starting with the English cardinal representation of that integer, the word 'is' and then the English cardinal representation of the count of characters that made up the first word, followed by a comma.

Continue the sequence by using the previous count word as the first word of the next phrase, append 'is' and the cardinal count of the letters in ''that'' word.

Continue until you reach four. Since four has four characters, finish by adding the words 'four is magic' and a period. All integers will eventually wind up at four.

For instance, suppose your are given the integer '''3'''. Convert '''3''' to '''Three''', add ''' is ''', then the cardinal character count of three, or '''five''', with a comma to separate if from the next phrase. Continue the sequence '''five is four,''' (five has four letters), and finally, '''four is magic.'''

      '''Three is five, five is four, four is magic.'''

For reference, here are outputs for 0 through 9.

      Zero is four, four is magic.
      One is three, three is five, five is four, four is magic.
      Two is three, three is five, five is four, four is magic.
      Three is five, five is four, four is magic.
      Four is magic.
      Five is four, four is magic.
      Six is three, three is five, five is four, four is magic.
      Seven is five, five is four, four is magic.
      Eight is five, five is four, four is magic.
      Nine is four, four is magic.

;Some task guidelines:
:* You may assume the input will only contain integer numbers.
:* Cardinal numbers between 20 and 100 may use either hyphens or spaces as word separators but they must use a word separator. ('''23''' is '''twenty three''' or '''twenty-three''' not '''twentythree'''.)
:* Cardinal number conversions should follow the  English short scale. (billion is 1e9, trillion is 1e12, etc.)
:* Cardinal numbers should not include commas. ('''20140''' is '''twenty thousand one hundred forty''' not '''twenty thousand, one hundred forty'''.)
:* When converted to a string, '''100''' should be '''one hundred''', not '''a hundred''' or '''hundred''', '''1000''' should be '''one thousand''', not '''a thousand''' or '''thousand'''.
:* When converted to a string, there should be no '''and''' in the cardinal string. '''130''' should be '''one hundred thirty''' not '''one hundred and thirty'''.
:* When counting characters, count ''all'' of the characters in the cardinal number including spaces and hyphens. '''One hundred fifty-one''' should be '''21''' not '''18'''.
:* The output should follow the format "N is K, K is M, M is ... four is magic." (unless the input is 4, in which case the output should simply be "four is magic.")
:* The output can either be the return value from the function, or be displayed from within the function.
:* You are encouraged, though not mandated to use proper sentence capitalization.
:* You may optionally support negative numbers. '''-7''' is '''negative seven'''.
:* Show the output here for a small representative sample of values, at least 5 but no more than 25. You are free to choose which which numbers to use for output demonstration.

You can choose to use a library, (module, external routine, whatever) to do the cardinal conversions as long as the code is easily and freely available to the public.

If you roll your own, make the routine accept at minimum any integer from 0 up to 999999. If you use a pre-made library, support at least up to unsigned 64 bit integers. (or the largest integer supported in your language if it is less.)

Four is magic is a popular code-golf task. '''This is not code golf.''' Write legible, idiomatic and well formatted code.

;Related tasks:
:*   [[Four is the number of_letters in the ...]]
:*   [[Look-and-say sequence]]
:*   [[Number names]]
:*   [[Self-describing numbers]]
:*   [[Summarize and say sequence]]
:*   [[Spelling of ordinal numbers]]
:*   [[De Bruijn sequences]]

Solution:
#include
#include
#include

typedef struct named_number_tag {
    const char* name;
    uint64_t number;
} named_number;

const named_number named_numbers[] = {
    { "hundred", 100 },
    { "thousand", 1000 },
    { "million", 1000000 },
    { "billion", 1000000000 },
    { "trillion", 1000000000000 },
    { "quadrillion", 1000000000000000ULL },
    { "quintillion", 1000000000000000000ULL }
};

const named_number* get_named_number(uint64_t n) {
    const size_t names_len = sizeof(named_numbers)/sizeof(named_number);
    for (size_t i = 0; i + 1 < names_len; ++i) {
        if (n < named_numbers[i + 1].number)
            return &named_numbers[i];
    }
    return &named_numbers[names_len - 1];
}

size_t append_number_name(GString* str, uint64_t n) {
    static const char* small[] = {
        "zero", "one", "two", "three", "four", "five", "six", "seven", "eight",
        "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen",
        "sixteen", "seventeen", "eighteen", "nineteen"
    };
    static const char* tens[] = {
        "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"
    };
    size_t len = str->len;
    if (n < 20) {
        g_string_append(str, small[n]);
    }
    else if (n < 100) {
        g_string_append(str, tens[n/10 - 2]);
        if (n % 10 != 0) {
            g_string_append_c(str, '-');
            g_string_append(str, small[n % 10]);
        }
    } else {
        const named_number* num = get_named_number(n);
        uint64_t p = num->number;
        append_number_name(str, n/p);
        g_string_append_c(str, ' ');
        g_string_append(str, num->name);
        if (n % p != 0) {
            g_string_append_c(str, ' ');
            append_number_name(str, n % p);
        }
    }
    return str->len - len;
}

GString* magic(uint64_t n) {
    GString* str = g_string_new(NULL);
    for (unsigned int i = 0; ; ++i) {
        size_t count = append_number_name(str, n);
        if (i == 0)
            str->str[0] = g_ascii_toupper(str->str[0]);
        if (n == 4) {
            g_string_append(str, " is magic.");
            break;
        }
        g_string_append(str, " is ");
        append_number_name(str, count);
        g_string_append(str, ", ");
        n = count;
    }
    return str;
}

void test_magic(uint64_t n) {
    GString* str = magic(n);
    printf("%s\n", str->str);
    g_string_free(str, TRUE);
}

int main() {
    test_magic(5);
    test_magic(13);
    test_magic(78);
    test_magic(797);
    test_magic(2739);
    test_magic(4000);
    test_magic(7893);
    test_magic(93497412);
    test_magic(2673497412U);
    test_magic(10344658531277200972ULL);
    return 0;
}


Four is magic

Solution:
const reverseOrderedNumberToTextMap = (function () {
    const rawNumberToTextMapping = { // Ported over from the Python solution.
        [1n]: "one",
        [2n]: "two",
        [3n]: "three",
        [4n]: "four",
        [5n]: "five",
        [6n]: "six",
        [7n]: "seven",
        [8n]: "eight",
        [9n]: "nine",
        [10n]: "ten",
        [11n]: "eleven",
        [12n]: "twelve",
        [13n]: "thirteen",
        [14n]: "fourteen",
        [15n]: "fifteen",
        [16n]: "sixteen",
        [17n]: "seventeen",
        [18n]: "eighteen",
        [19n]: "nineteen",
        [20n]: "twenty",
        [30n]: "thirty",
        [40n]: "forty",
        [50n]: "fifty",
        [60n]: "sixty",
        [70n]: "seventy",
        [80n]: "eighty",
        [90n]: "ninety",
        [100n]: "hundred",
        [1000n]: "thousand",
        [10n ** 6n]: "million",
        [10n ** 9n]: "billion",
        [10n ** 12n]: "trillion",
        [10n ** 15n]: "quadrillion",
        [10n ** 18n]: "quintillion",
        [10n ** 21n]: "sextillion",
        [10n ** 24n]: "septillion",
        [10n ** 27n]: "octillion",
        [10n ** 30n]: "nonillion",
        [10n ** 33n]: "decillion",
        [10n ** 36n]: "undecillion",
        [10n ** 39n]: "duodecillion",
        [10n ** 42n]: "tredecillion",
        [10n ** 45n]: "quattuordecillion",
        [10n ** 48n]: "quinquadecillion",
        [10n ** 51n]: "sedecillion",
        [10n ** 54n]: "septendecillion",
        [10n ** 57n]: "octodecillion",
        [10n ** 60n]: "novendecillion",
        [10n ** 63n]: "vigintillion",
        [10n ** 66n]: "unvigintillion",
        [10n ** 69n]: "duovigintillion",
        [10n ** 72n]: "tresvigintillion",
        [10n ** 75n]: "quattuorvigintillion",
        [10n ** 78n]: "quinquavigintillion",
        [10n ** 81n]: "sesvigintillion",
        [10n ** 84n]: "septemvigintillion",
        [10n ** 87n]: "octovigintillion",
        [10n ** 90n]: "novemvigintillion",
        [10n ** 93n]: "trigintillion",
        [10n ** 96n]: "untrigintillion",
        [10n ** 99n]: "duotrigintillion",
        [10n ** 102n]: "trestrigintillion",
        [10n ** 105n]: "quattuortrigintillion",
        [10n ** 108n]: "quinquatrigintillion",
        [10n ** 111n]: "sestrigintillion",
        [10n ** 114n]: "septentrigintillion",
        [10n ** 117n]: "octotrigintillion",
        [10n ** 120n]: "noventrigintillion",
        [10n ** 123n]: "quadragintillion",
        [10n ** 153n]: "quinquagintillion",
        [10n ** 183n]: "sexagintillion",
        [10n ** 213n]: "septuagintillion",
        [10n ** 243n]: "octogintillion",
        [10n ** 273n]: "nonagintillion",
        [10n ** 303n]: "centillion",
        [10n ** 306n]: "uncentillion",
        [10n ** 309n]: "duocentillion",
        [10n ** 312n]: "trescentillion",
        [10n ** 333n]: "decicentillion",
        [10n ** 336n]: "undecicentillion",
        [10n ** 363n]: "viginticentillion",
        [10n ** 366n]: "unviginticentillion",
        [10n ** 393n]: "trigintacentillion",
        [10n ** 423n]: "quadragintacentillion",
        [10n ** 453n]: "quinquagintacentillion",
        [10n ** 483n]: "sexagintacentillion",
        [10n ** 513n]: "septuagintacentillion",
        [10n ** 543n]: "octogintacentillion",
        [10n ** 573n]: "nonagintacentillion",
        [10n ** 603n]: "ducentillion",
        [10n ** 903n]: "trecentillion",
        [10n ** 1203n]: "quadringentillion",
        [10n ** 1503n]: "quingentillion",
        [10n ** 1803n]: "sescentillion",
        [10n ** 2103n]: "septingentillion",
        [10n ** 2403n]: "octingentillion",
        [10n ** 2703n]: "nongentillion",
        [10n ** 3003n]: "millinillion"
    };

    return new Map(Object.entries(rawNumberToTextMapping)
                         .sort((a, b) => BigInt(a[0]) > BigInt(b[0]) ? -1 : 1)
                         .map(numberAndText => [BigInt(numberAndText[0]), numberAndText[1]]));
})();

function getCardinalRepresentation(number)
{
    if (number == 0n)
    {
        return "zero";
    }

    function* generateCardinalRepresentationTokens(number)
    {
        if (number <= 0n)
        {
            yield "negative";
            number *= -1n;
        }

        for (const [currentEntryNumber, currentEntryText] of reverseOrderedNumberToTextMap.entries())
        {
            if (number >= currentEntryNumber)
            {
                if (currentEntryNumber >= 100n)
                {
                    yield* generateCardinalRepresentationTokens(number / currentEntryNumber);
                }

                yield currentEntryText;
                number -= currentEntryNumber;
            }
        }
    }

    return [...generateCardinalRepresentationTokens(number)].join(" ");
}

function* generateFourIsMagicParts(number)
{
    if (typeof number != "bigint")
    {
        number = BigInt(number);
    }

    if (number == 4n)
    {
        yield "four is magic";
    }
    else
    {
        const cardinalRepresentation = getCardinalRepresentation(number);
        yield `${cardinalRepresentation} is ${getCardinalRepresentation(BigInt(cardinalRepresentation.length))}`;
        yield* generateFourIsMagicParts(cardinalRepresentation.length);
    }

}

function capitalizeFirstLetter(str)
{
    return str.replace(/^([a-z])/, chr => chr.toUpperCase());
}

function fourIsMagic(number)
{
    return capitalizeFirstLetter(`${[...generateFourIsMagicParts(number)].join(", ")}.`);
}

[
    0,
    -150,
    210,
    10n ** 2703n + 1225n,
    4,
    -4,
    10n ** 3003n + 42n
].map(fourIsMagic).join("\n\n");