Check Machin-like formulas

Machin-like formulas   are useful for efficiently computing numerical approximations for \pi

;Task:
Verify the following Machin-like formulas are correct by calculating the value of '''tan'''   (''right hand side)'' for each equation using exact arithmetic and showing they equal '''1''':

: {\pi\over4} = \arctan{1\over2} + \arctan{1\over3}
: {\pi\over4} = 2 \arctan{1\over3} + \arctan{1\over7}
: {\pi\over4} = 4 \arctan{1\over5} - \arctan{1\over239}
: {\pi\over4} = 5 \arctan{1\over7} + 2 \arctan{3\over79}
: {\pi\over4} = 5 \arctan{29\over278} + 7 \arctan{3\over79}
: {\pi\over4} = \arctan{1\over2} + \arctan{1\over5} + \arctan{1\over8}
: {\pi\over4} = 4 \arctan{1\over5} - \arctan{1\over70} + \arctan{1\over99}
: {\pi\over4} = 5 \arctan{1\over7} + 4 \arctan{1\over53} + 2 \arctan{1\over4443}
: {\pi\over4} = 6 \arctan{1\over8} + 2 \arctan{1\over57} + \arctan{1\over239}
: {\pi\over4} = 8 \arctan{1\over10} - \arctan{1\over239} - 4 \arctan{1\over515}
: {\pi\over4} = 12 \arctan{1\over18} + 8 \arctan{1\over57} - 5 \arctan{1\over239}
: {\pi\over4} = 16 \arctan{1\over21} + 3 \arctan{1\over239} + 4 \arctan{3\over1042}
: {\pi\over4} = 22 \arctan{1\over28} + 2 \arctan{1\over443} - 5 \arctan{1\over1393} - 10 \arctan{1\over11018}
: {\pi\over4} = 22 \arctan{1\over38} + 17 \arctan{7\over601} + 10 \arctan{7\over8149}
: {\pi\over4} = 44 \arctan{1\over57} + 7 \arctan{1\over239} - 12 \arctan{1\over682} + 24 \arctan{1\over12943}
: {\pi\over4} = 88 \arctan{1\over172} + 51 \arctan{1\over239} + 32 \arctan{1\over682} + 44 \arctan{1\over5357} + 68 \arctan{1\over12943}

and confirm that the following formula is ''incorrect'' by showing   '''tan'''   (''right hand side)''   is ''not''   '''1''':

: {\pi\over4} = 88 \arctan{1\over172} + 51 \arctan{1\over239} + 32 \arctan{1\over682} + 44 \arctan{1\over5357} + 68 \arctan{1\over12944}

These identities are useful in calculating the values:
: \tan(a + b) = {\tan(a) + \tan(b) \over 1 - \tan(a) \tan(b)}

: \tan\left(\arctan{a \over b}\right) = {a \over b}

: \tan(-a) = -\tan(a)

You can store the equations in any convenient data structure, but for extra credit parse them from human-readable text input.

Note: to formally prove the formula correct, it would have to be shown that ''{-3 pi \over 4} < right hand side < {5 pi \over 4}'' due to ''\tan()'' periodicity.

Solution:
import re
from fractions import Fraction
from pprint import pprint as pp

equationtext = '''\
  pi/4 = arctan(1/2) + arctan(1/3)
  pi/4 = 2*arctan(1/3) + arctan(1/7)
  pi/4 = 4*arctan(1/5) - arctan(1/239)
  pi/4 = 5*arctan(1/7) + 2*arctan(3/79)
  pi/4 = 5*arctan(29/278) + 7*arctan(3/79)
  pi/4 = arctan(1/2) + arctan(1/5) + arctan(1/8)
  pi/4 = 4*arctan(1/5) - arctan(1/70) + arctan(1/99)
  pi/4 = 5*arctan(1/7) + 4*arctan(1/53) + 2*arctan(1/4443)
  pi/4 = 6*arctan(1/8) + 2*arctan(1/57) + arctan(1/239)
  pi/4 = 8*arctan(1/10) - arctan(1/239) - 4*arctan(1/515)
  pi/4 = 12*arctan(1/18) + 8*arctan(1/57) - 5*arctan(1/239)
  pi/4 = 16*arctan(1/21) + 3*arctan(1/239) + 4*arctan(3/1042)
  pi/4 = 22*arctan(1/28) + 2*arctan(1/443) - 5*arctan(1/1393) - 10*arctan(1/11018)
  pi/4 = 22*arctan(1/38) + 17*arctan(7/601) + 10*arctan(7/8149)
  pi/4 = 44*arctan(1/57) + 7*arctan(1/239) - 12*arctan(1/682) + 24*arctan(1/12943)
  pi/4 = 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12943)
  pi/4 = 88*arctan(1/172) + 51*arctan(1/239) + 32*arctan(1/682) + 44*arctan(1/5357) + 68*arctan(1/12944)
'''

def parse_eqn(equationtext=equationtext):
    eqn_re = re.compile(r"""(?mx)
    (?P ^ \s* pi/4 \s* = \s*)?             # LHS of equation
    (?:                                         # RHS
        \s* (?P [+-])? \s*
        (?: (?P \d+) \s* \*)?
        \s* arctan\( (?P \d+) / (?P \d+)
    )""")

    found = eqn_re.findall(equationtext)
    machins, part = [], []
    for lhs, sign, mult, numer, denom in eqn_re.findall(equationtext):
        if lhs and part:
            machins.append(part)
            part = []
        part.append( ( (-1 if sign == '-' else 1) * ( int(mult) if mult else 1),
                       Fraction(int(numer), (int(denom) if denom else 1)) ) )
    machins.append(part)
    return machins

def tans(xs):
    xslen = len(xs)
    if xslen == 1:
        return tanEval(*xs[0])
    aa, bb = xs[:xslen//2], xs[xslen//2:]
    a, b = tans(aa), tans(bb)
    return (a + b) / (1 - a * b)

def tanEval(coef, f):
    if coef == 1:
        return f
    if coef < 0:
        return -tanEval(-coef, f)
    ca = coef // 2
    cb = coef - ca
    a, b = tanEval(ca, f), tanEval(cb, f)
    return (a + b) / (1 - a * b)

if __name__ == '__main__':
    machins = parse_eqn()
    #pp(machins, width=160)
    for machin, eqn in zip(machins, equationtext.split('\n')):
        ans = tans(machin)
        print('%5s: %s' % ( ('OK' if ans == 1 else 'ERROR'), eqn))


Check input device is a terminal

;Task:
Demonstrate how to check whether the input device is a terminal or not.

;Related task:
*   [[Check output device is a terminal]]

Solution:
#include 	//for isatty()
#include 	//for fileno()

int main(void)
{
	puts(isatty(fileno(stdin))
		? "stdin is tty"
		: "stdin is not tty");
	return 0;
}


Check input device is a terminal

Solution:
from sys import stdin
if stdin.isatty():
    print("Input comes from tty.")
else:
    print("Input doesn't come from tty.")


Check output device is a terminal

;Task:
Demonstrate how to check whether the output device is a terminal or not.

;Related task:
*   [[Check input device is a terminal]]

Solution:
#include    // for isatty()
#include     // for fileno()

int main()
{
    puts(isatty(fileno(stdout))
          ? "stdout is tty"
          : "stdout is not tty");
    return 0;
}


Check output device is a terminal

Solution:
from sys import stdout
if stdout.isatty():
    print 'The output device is a teletype. Or something like a teletype.'
else:
    print 'The output device isn\'t like a teletype.'


Cheryl's birthday

Albert and Bernard just became friends with Cheryl, and they want to know when her birthday is.

Cheryl gave them a list of ten possible dates:
      May 15,     May 16,     May 19
      June 17,    June 18
      July 14,    July 16
      August 14,  August 15,  August 17

Cheryl then tells Albert the   ''month''   of birth,   and Bernard the   ''day''   (of the month)   of birth.
  1)  Albert:   I don't know when Cheryl's birthday is, but I know that Bernard does not know too.
  2)  Bernard:  At first I don't know when Cheryl's birthday is, but I know now.
  3)  Albert:   Then I also know when Cheryl's birthday is.

;Task
Write a computer program to deduce, by successive elimination, Cheryl's birthday.

;Related task:
* [[Sum and Product Puzzle]]

;References
* [https://en.wikipedia.org/wiki/Cheryl%27s_Birthday Wikipedia article] of the same name.
* [https://en.wikipedia.org/wiki/Tuple_relational_calculus, Tuple Relational Calculus]

Solution:
#include
#include

char *months[] = {
    "ERR", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

struct Date {
    int month, day;
    bool active;
} dates[] = {
    {5,15,true}, {5,16,true}, {5,19,true},
    {6,17,true}, {6,18,true},
    {7,14,true}, {7,16,true},
    {8,14,true}, {8,15,true}, {8,17,true}
};
#define UPPER_BOUND (sizeof(dates) / sizeof(struct Date))

void printRemaining() {
    int i, c;
    for (i = 0, c = 0; i < UPPER_BOUND; i++) {
        if (dates[i].active) {
            c++;
        }
    }
    printf("%d remaining.\n", c);
}

void printAnswer() {
    int i;
    for (i = 0; i < UPPER_BOUND; i++) {
        if (dates[i].active) {
            printf("%s, %d\n", months[dates[i].month], dates[i].day);
        }
    }
}

void firstPass() {
    // the month cannot have a unique day
    int i, j, c;
    for (i = 0; i < UPPER_BOUND; i++) {
        c = 0;

        for (j = 0; j < UPPER_BOUND; j++) {
            if (dates[j].day == dates[i].day) {
                c++;
            }
        }

        if (c == 1) {
            for (j = 0; j < UPPER_BOUND; j++) {
                if (!dates[j].active) continue;
                if (dates[j].month == dates[i].month) {
                    dates[j].active = false;
                }
            }
        }
    }
}

void secondPass() {
    // the day must now be unique
    int i, j, c;
    for (i = 0; i < UPPER_BOUND; i++) {
        if (!dates[i].active) continue;
        c = 0;

        for (j = 0; j < UPPER_BOUND; j++) {
            if (!dates[j].active) continue;
            if (dates[j].day == dates[i].day) {
                c++;
            }
        }

        if (c > 1) {
            for (j = 0; j < UPPER_BOUND; j++) {
                if (!dates[j].active) continue;
                if (dates[j].day == dates[i].day) {
                    dates[j].active = false;
                }
            }
        }
    }
}

void thirdPass() {
    // the month must now be unique
    int i, j, c;
    for (i = 0; i < UPPER_BOUND; i++) {
        if (!dates[i].active) continue;
        c = 0;

        for (j = 0; j < UPPER_BOUND; j++) {
            if (!dates[j].active) continue;
            if (dates[j].month == dates[i].month) {
                c++;
            }
        }

        if (c > 1) {
            for (j = 0; j < UPPER_BOUND; j++) {
                if (!dates[j].active) continue;
                if (dates[j].month == dates[i].month) {
                    dates[j].active = false;
                }
            }
        }
    }
}

int main() {
    printRemaining();
    // the month cannot have a unique day
    firstPass();

    printRemaining();
    // the day must now be unique
    secondPass();

    printRemaining();
    // the month must now be unique
    thirdPass();

    printAnswer();
    return 0;
}


Cheryl's birthday

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

    // main :: IO ()
    const main = () => {
        const
            month = fst,
            day = snd;
        showLog(
            map(x => Array.from(x), (

                // The month with only one remaining day,

                // (A's month contains only one remaining day)
                // (3 :: A "Then I also know")
                uniquePairing(month)(

                    // among the days with unique months,

                    // (B's day is paired with only one remaining month)
                    // (2 :: B "I know now")
                    uniquePairing(day)(

                        // excluding months with unique days,

                        // (A's month is not among those with unique days)
                        // (1 :: A "I know that Bernard does not know")
                        monthsWithUniqueDays(false)(

                            // from the given month-day pairs:

                            // (0 :: Cheryl's list)
                            map(x => tupleFromList(words(strip(x))),
                                splitOn(/,\s+/,
                                    `May 15, May 16, May 19,
                                        June 17, June 18, July 14, July 16,
                                        Aug 14, Aug 15, Aug 17`
                                )
                            )
                        )
                    )
                )
            ))
        );
    };

    // monthsWithUniqueDays :: Bool -> [(Month, Day)] -> [(Month, Day)]
    const monthsWithUniqueDays = blnInclude => xs => {
        const months = map(fst, uniquePairing(snd)(xs));
        return filter(
            md => (blnInclude ? id : not)(
                elem(fst(md), months)
            ),
            xs
        );
    };

    // uniquePairing :: ((a, a) -> a) ->
    //      -> [(Month, Day)] -> [(Month, Day)]
    const uniquePairing = f => xs =>
        bindPairs(xs,
            md => {
                const
                    dct = f(md),
                    matches = filter(
                        k => 1 === length(dct[k]),
                        Object.keys(dct)
                    );
                return filter(tpl => elem(f(tpl), matches), xs);
            }
        );

    // bindPairs :: [(Month, Day)] -> (Dict, Dict) -> [(Month, Day)]
    const bindPairs = (xs, f) => f(
        Tuple(
            dictFromPairs(fst)(snd)(xs),
            dictFromPairs(snd)(fst)(xs)
        )
    );

    // dictFromPairs :: ((a, a) -> a) -> ((a, a) -> a) -> [(a, a)] -> Dict
    const dictFromPairs = f => g => xs =>
        foldl((a, tpl) => Object.assign(
            a, {
                [f(tpl)]: (a[f(tpl)] || []).concat(g(tpl).toString())
            }
        ), {}, xs);

    // GENERIC ABSTRACTIONS -------------------------------

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

    // elem :: Eq a => a -> [a] -> Bool
    const elem = (x, xs) => xs.includes(x);

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

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

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

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

    // intersect :: (Eq a) => [a] -> [a] -> [a]
    const intersect = (xs, ys) =>
        xs.filter(x => -1 !== ys.indexOf(x));

    // Returns Infinity over objects without finite length
    // this enables zip and zipWith to choose the shorter
    // argument when one is non-finite, like cycle, repeat etc

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

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

    // not :: Bool -> Bool
    const not = b => !b;

    // showLog :: a -> IO ()
    const showLog = (...args) =>
        console.log(
            args
            .map(JSON.stringify)
            .join(' -> ')
        );

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

    // splitOn :: String -> String -> [String]
    const splitOn = (pat, src) =>
        src.split(pat);

    // strip :: String -> String
    const strip = s => s.trim();

    // tupleFromList :: [a] -> (a, a ...)
    const tupleFromList = xs =>
        TupleN.apply(null, xs);

    // TupleN :: a -> b ...  -> (a, b ... )
    function TupleN() {
        const
            args = Array.from(arguments),
            lng = args.length;
        return lng > 1 ? Object.assign(
            args.reduce((a, x, i) => Object.assign(a, {
                [i]: x
            }), {
                type: 'Tuple' + (2 < lng ? lng.toString() : ''),
                length: lng
            })
        ) : args[0];
    };

    // words :: String -> [String]
    const words = s => s.split(/\s+/);

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


Cheryl's birthday

Solution:
'''Cheryl's Birthday'''

from itertools import groupby
from re import split

# main :: IO ()
def main():
    '''Derivation of the date.'''

    month, day = 0, 1
    print(
        # (3 :: A "Then I also know")
        # (A's month contains only one remaining day)
        uniquePairing(month)(
            # (2 :: B "I know now")
            # (B's day is paired with only one remaining month)
            uniquePairing(day)(
                # (1 :: A "I know that Bernard does not know")
                # (A's month is not among those with unique days)
                monthsWithUniqueDays(False)([
                    # 0 :: Cheryl's list:
                    tuple(x.split()) for x in
                    split(
                        ', ',
                        'May 15, May 16, May 19, ' +
                        'June 17, June 18, ' +
                        'July 14, July 16, ' +
                        'Aug 14, Aug 15, Aug 17'
                    )
                ])
            )
        )
    )

# ------------------- QUERY FUNCTIONS --------------------

# monthsWithUniqueDays :: Bool -> [(Month, Day)] -> [(Month, Day)]
def monthsWithUniqueDays(blnInclude):
    '''The subset of months with (or without) unique days.
    '''
    def go(xs):
        month, day = 0, 1
        months = [fst(x) for x in uniquePairing(day)(xs)]
        return [
            md for md in xs
            if blnInclude or not (md[month] in months)
        ]
    return go

# uniquePairing :: DatePart -> [(Month, Day)] -> [(Month, Day)]
def uniquePairing(i):
    '''Subset of months (or days) with a unique intersection.
    '''
    def go(xs):
        def inner(md):
            dct = md[i]
            uniques = [
                k for k in dct.keys()
                if 1 == len(dct[k])
            ]
            return [tpl for tpl in xs if tpl[i] in uniques]
        return inner
    return ap(bindPairs)(go)

# bindPairs :: [(Month, Day)] ->
# ((Dict String [String], Dict String [String])
# -> [(Month, Day)]) -> [(Month, Day)]
def bindPairs(xs):
    '''List monad injection operator for lists
       of (Month, Day) pairs.
    '''
    return lambda f: f(
        (
            dictFromPairs(xs),
            dictFromPairs(
                [(b, a) for (a, b) in xs]
            )
        )
    )

# dictFromPairs :: [(Month, Day)] -> Dict Text [Text]
def dictFromPairs(xs):
    '''A dictionary derived from a list of
       month day pairs.
    '''
    return {
        k: [snd(x) for x in m] for k, m in groupby(
            sorted(xs, key=fst), key=fst
        )
    }

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

# ap :: (a -> b -> c) -> (a -> b) -> a -> c
def ap(f):
    '''Applicative instance for functions.
    '''
    def go(g):
        def fxgx(x):
            return f(x)(
                g(x)
            )
        return fxgx
    return go

# fst :: (a, b) -> a
def fst(tpl):
    '''First component of a pair.
    '''
    return tpl[0]

# snd :: (a, b) -> b
def snd(tpl):
    '''Second component of a pair.
    '''
    return tpl[1]

if __name__ == '__main__':
    main()


Chinese remainder theorem

Suppose   n_1,   n_2,   \ldots,   n_k   are positive [[integer]]s that are pairwise co-prime.

Then, for any given sequence of integers   a_1,   a_2,   \dots,   a_k,   there exists an integer   x   solving the following system of simultaneous congruences:

::: \begin{align}
  x &\equiv a_1 \pmod{n_1} \\
  x &\equiv a_2 \pmod{n_2} \\
    &{}\  \  \vdots \\
  x &\equiv a_k \pmod{n_k}
\end{align}

Furthermore, all solutions   x   of this system are congruent modulo the product,    N=n_1n_2\ldots n_k.

;Task:
Write a program to solve a system of linear congruences by applying the   Chinese Remainder Theorem.

If the system of equations cannot be solved, your program must somehow indicate this.

(It may throw an exception or return a special false value.)

Since there are infinitely many solutions, the program should return the unique solution   s   where   0 \leq s \leq n_1n_2\ldots n_k.

''Show the functionality of this program'' by printing the result such that the   n's   are   [3,5,7]   and the   a's   are   [2,3,2].

'''Algorithm''':   The following algorithm only applies if the   n_i's   are pairwise co-prime.

Suppose, as above, that a solution is required for the system of congruences:

::: x \equiv a_i \pmod{n_i} \quad\mathrm{for}\; i = 1, \ldots, k

Again, to begin, the product   N = n_1n_2 \ldots n_k   is defined.

Then a solution   x   can be found as follows:

For each   i,   the integers   n_i   and   N/n_i   are co-prime.

Using the   Extended Euclidean algorithm,   we can find integers   r_i   and   s_i   such that   r_i n_i + s_i N/n_i = 1.

Then, one solution to the system of simultaneous congruences is:

::: x = \sum_{i=1}^k a_i s_i N/n_i

and the minimal solution,

::: x \pmod{N}.

Solution:
#include

// returns x where (a * x) % b == 1
int mul_inv(int a, int b)
{
	int b0 = b, t, q;
	int x0 = 0, x1 = 1;
	if (b == 1) return 1;
	while (a > 1) {
		q = a / b;
		t = b, b = a % b, a = t;
		t = x0, x0 = x1 - q * x0, x1 = t;
	}
	if (x1 < 0) x1 += b0;
	return x1;
}

int chinese_remainder(int *n, int *a, int len)
{
	int p, i, prod = 1, sum = 0;

	for (i = 0; i < len; i++) prod *= n[i];

	for (i = 0; i < len; i++) {
		p = prod / n[i];
		sum += a[i] * mul_inv(p, n[i]) * p;
	}

	return sum % prod;
}

int main(void)
{
	int n[] = { 3, 5, 7 };
	int a[] = { 2, 3, 2 };

	printf("%d\n", chinese_remainder(n, a, sizeof(n)/sizeof(n[0])));
	return 0;
}


Chinese remainder theorem

Solution:
function crt(num, rem) {
  let sum = 0;
  const prod = num.reduce((a, c) => a * c, 1);

  for (let i = 0; i < num.length; i++) {
    const [ni, ri] = [num[i], rem[i]];
    const p = Math.floor(prod / ni);
    sum += ri * p * mulInv(p, ni);
  }
  return sum % prod;
}

function mulInv(a, b) {
  const b0 = b;
  let [x0, x1] = [0, 1];

  if (b === 1) {
    return 1;
  }
  while (a > 1) {
    const q = Math.floor(a / b);
    [a, b] = [b, a % b];
    [x0, x1] = [x1 - q * x0, x0];
  }
  if (x1 < 0) {
    x1 += b0;
  }
  return x1;
}

console.log(crt([3,5,7], [2,3,2]))


Chinese remainder theorem

Solution:
# Python 2.7
def chinese_remainder(n, a):
    sum = 0
    prod = reduce(lambda a, b: a*b, n)

    for n_i, a_i in zip(n, a):
        p = prod / n_i
        sum += a_i * mul_inv(p, n_i) * p
    return sum % prod

def mul_inv(a, b):
    b0 = b
    x0, x1 = 0, 1
    if b == 1: return 1
    while a > 1:
        q = a / b
        a, b = b, a%b
        x0, x1 = x1 - q * x0, x0
    if x1 < 0: x1 += b0
    return x1

if __name__ == '__main__':
    n = [3, 5, 7]
    a = [2, 3, 2]
    print chinese_remainder(n, a)


Chinese zodiac

Traditionally, the Chinese have counted years using two lists of labels, one of length 10 (the "celestial stems") and one of length 12 (the "terrestrial branches"). The labels do not really have any meaning outside their positions in the two lists; they're simply a traditional enumeration device, used much as Westerners use letters and numbers. They were historically used for months and days as well as years, and the stems are still sometimes used for school grades.

Years cycle through both lists concurrently, so that both stem and branch advance each year; if we used Roman letters for the stems and numbers for the branches, consecutive years would be labeled A1, B2, C3, etc. Since the two lists are different lengths, they cycle back to their beginning at different points: after J10 we get A11, and then after B12 we get C1. The result is a repeating 60-year pattern within which each pair of names occurs only once.

Mapping the branches to twelve traditional animal deities results in the well-known "Chinese zodiac", assigning each year to a given animal. For example, Sunday, January 22, 2023 CE (in the common Gregorian calendar) began the lunisolar Year of the Rabbit.

The celestial stems do not have a one-to-one mapping like that of the branches to animals; however, the five pairs of consecutive stems are each associated with one of the five traditional Chinese elements (Wood, Fire, Earth, Metal, and Water). Further, one of the two years within each element is assigned to yin, the other to yang.

Thus, the Chinese year beginning in 2023 CE is also the yin year of Water. Since 12 is an even number, the association between animals and yin/yang doesn't change; consecutive Years of the Rabbit will cycle through the five elements, but will always be yin.

;Task: Create a subroutine or program that will return or output the animal, yin/yang association, and element for the lunisolar year that begins in a given CE year.

You may optionally provide more information in the form of the year's numerical position within the 60-year cycle and/or its actual Chinese stem-branch name (in Han characters or Pinyin transliteration).

;Requisite information:
* The animal cycle runs in this order: Rat, Ox, Tiger, Rabbit, Dragon, Snake, Horse, Goat, Monkey, Rooster, Dog, Pig.
* The element cycle runs in this order: Wood, Fire, Earth, Metal, Water.
* Each element gets two consecutive years; a yang followed by a yin.
* The current 60-year cycle began in 1984; any multiple of 60 years from that point may be used to reckon from.

Thus, year 1 of a cycle is the year of the Wood Rat (yang), year 2 the Wood Ox (yin), and year 3 the Fire Tiger (yang). The year 2023 - which, as already noted, is the year of the Water Rabbit (yin) - is the 40th year of the current cycle.

;Information for optional task:
* The ten celestial stems are '''甲''' ''jiă'', '''乙''' ''yĭ'', '''丙''' ''bĭng'', '''丁''' ''dīng'', '''戊''' ''wù'', '''己''' ''jĭ'', '''庚''' ''gēng'', '''辛''' ''xīn'', '''壬''' ''rén'', and '''癸''' ''gŭi''. With the ASCII version of Pinyin tones, the names are written "jia3", "yi3", "bing3", "ding1", "wu4", "ji3", "geng1", "xin1", "ren2", and "gui3".
* The twelve terrestrial branches are '''子''' ''zĭ'', '''丑''' ''chŏu'', '''寅''' ''yín'', '''卯''' ''măo'', '''辰''' ''chén'', '''巳''' ''sì'', '''午''' ''wŭ'', '''未''' ''wèi'', '''申''' ''shēn'', '''酉''' ''yŏu'', '''戌''' ''xū'', '''亥''' ''hài''. In ASCII Pinyin, those are "zi3", "chou3", "yin2", "mao3", "chen2", "si4", "wu3", "wei4", "shen1", "you3", "xu1", and "hai4".

Therefore 1984 was '''甲子''' (''jiă-zĭ'', or jia3-zi3).  2023 is '''癸卯''' (''gŭi-măo'' or gui3-mao3).

Solution:
#include
#include

const char* animals[] = { "Rat","Ox","Tiger","Rabbit","Dragon","Snake","Horse","Goat","Monkey","Rooster","Dog","Pig" };
const char* elements[] = { "Wood","Fire","Earth","Metal","Water" };

const char* getElement(int year) {
    int element = (int)floor((year - 4) % 10 / 2);
    return elements[element];
}

const char* getAnimal(int year) {
    return animals[(year - 4) % 12];
}

const char* getYY(int year) {
    if (year % 2 == 0) {
        return "yang";
    } else {
        return "yin";
    }
}

int main() {
    int years[] = { 1935, 1938, 1968, 1972, 1976, 2017 };
    int i;

    //the zodiac cycle didnt start until 4 CE, so years <4 shouldnt be valid
    for (i = 0; i < 6; ++i) {
        int year = years[i];
        printf("%d is the year of the %s %s (%s).\n", year, getElement(year), getAnimal(year), getYY(year));
    }

    return 0;
}


Chinese zodiac

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

    // ---------- TRADITIONAL CALENDAR STRINGS -----------

    // ats :: Array Int (String, String)
    const ats = () =>
        // 天干 tiangan – 10 heavenly stems
        zip(
            chars("甲乙丙丁戊己庚辛壬癸")
        )(
            words("jiă yĭ bĭng dīng wù jĭ gēng xīn rén gŭi")
        );

    // ads :: Array Int (String, String)
    const ads = () =>
        // 地支 dizhi – 12 terrestrial branches
        zip(
            chars("子丑寅卯辰巳午未申酉戌亥")
        )(
            words(
                "zĭ chŏu yín măo chén sì " + (
                    "wŭ wèi shēn yŏu xū hài"
                )
            )
        );

    // aws :: Array Int (String, String, String)
    const aws = () =>
        // 五行 wuxing – 5 elements
        zip3(
            chars("木火土金水")
        )(
            words("mù huǒ tǔ jīn shuǐ")
        )(
            words("wood fire earth metal water")
        );

    // axs :: Array Int (String, String, String)
    const axs = () =>
        // 十二生肖 shengxiao – 12 symbolic animals
        zip3(
            chars("鼠牛虎兔龍蛇馬羊猴鸡狗豬")
        )(
            words(
                "shǔ niú hǔ tù lóng shé " + (
                    "mǎ yáng hóu jī gǒu zhū"
                )
            )
        )(
            words(
                "rat ox tiger rabbit dragon snake " + (
                    "horse goat monkey rooster dog pig"
                )
            )
        );

    // ays :: Array Int (String, String)
    const ays = () =>
        // 阴阳 yinyang
        zip(
            chars("阳阴")
        )(
            words("yáng yīn")
        );

    // --------------- TRADITIONAL CYCLES ----------------
    const zodiac = y => {
        const
            iYear = y - 4,
            iStem = iYear % 10,
            iBranch = iYear % 12,
            [hStem, pStem] = ats()[iStem],
            [hBranch, pBranch] = ads()[iBranch],
            [hElem, pElem, eElem] = aws()[quot(iStem)(2)],
            [hAnimal, pAnimal, eAnimal] = axs()[iBranch],
            [hYinyang, pYinyang] = ays()[iYear % 2];

        return [
            [
                show(y), hStem + hBranch, hElem,
                hAnimal, hYinyang
            ],
            ["", pStem + pBranch, pElem, pAnimal, pYinyang],
            [
                "", `${show((iYear % 60) + 1)}/60`,
                eElem, eAnimal, ""
            ]
        ];
    };

    // ---------------------- TEST -----------------------
    const main = () => [
            1935, 1938, 1968, 1972, 1976, 1984,
            new Date().getFullYear()
        ]
        .map(showYear)
        .join("\n\n");

    // ------------------- FORMATTING --------------------
    // fieldWidths :: [[Int]]
    const fieldWidths = [
        [6, 10, 7, 8, 3],
        [6, 11, 8, 8, 4],
        [6, 11, 8, 8, 4]
    ];

    // showYear :: Int -> String
    const showYear = y =>
        zipWith(zip)(fieldWidths)(zodiac(y))
        .map(
            row => row.map(
                ([n, s]) => s.padEnd(n, " ")
            )
            .join("")
        )
        .join("\n");

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

    // chars :: String -> [Char]
    const chars = s => [...s];

    // quot :: Integral a => a -> a -> a
    const quot = n =>
        m => Math.trunc(n / m);

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

    // words :: String -> [String]
    const words = s =>
        // List of space-delimited sub-strings.
        s.split(/\s+/u);

    // zip :: [a] -> [b] -> [(a, b)]
    const zip = xs =>
        // The paired members of xs and ys, up to
        // the length of the shorter of the two lists.
        ys => Array.from({
            length: Math.min(xs.length, ys.length)
        }, (_, i) => [xs[i], ys[i]]);

    // zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]
    const zip3 = xs =>
        ys => zs => xs.slice(
            0,
            Math.min(...[xs, ys, zs].map(x => x.length))
        )
        .map((x, i) => [x, ys[i], zs[i]]);

    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f =>
        // A list constructed by zipping with a
        // custom function, rather than with the
        // default tuple constructor.
        xs => ys => xs.map(
            (x, i) => f(x)(ys[i])
        ).slice(
            0, Math.min(xs.length, ys.length)
        );

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


Chinese zodiac

Solution:
# coding: utf-8

from __future__ import print_function
from datetime import datetime

pinyin = {
  '甲': 'jiă',
  '乙': 'yĭ',
  '丙': 'bĭng',
  '丁': 'dīng',
  '戊': 'wù',
  '己': 'jĭ',
  '庚': 'gēng',
  '辛': 'xīn',
  '壬': 'rén',
  '癸': 'gŭi',

  '子': 'zĭ',
  '丑': 'chŏu',
  '寅': 'yín',
  '卯': 'măo',
  '辰': 'chén',
  '巳': 'sì',
  '午': 'wŭ',
  '未': 'wèi',
  '申': 'shēn',
  '酉': 'yŏu',
  '戌': 'xū',
  '亥': 'hài'
}

animals = ['Rat', 'Ox', 'Tiger', 'Rabbit', 'Dragon', 'Snake',
           'Horse', 'Goat', 'Monkey', 'Rooster', 'Dog', 'Pig']
elements = ['Wood', 'Fire', 'Earth', 'Metal', 'Water']

celestial = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']
terrestrial = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥']
aspects = ['yang', 'yin']

def calculate(year):
    BASE = 4
    year = int(year)
    cycle_year = year - BASE
    stem_number = cycle_year % 10
    stem_han = celestial[stem_number]
    stem_pinyin = pinyin[stem_han]
    element_number = stem_number // 2
    element = elements[element_number]
    branch_number = cycle_year % 12
    branch_han = terrestrial[branch_number]
    branch_pinyin = pinyin[branch_han]
    animal = animals[branch_number]
    aspect_number = cycle_year % 2
    aspect = aspects[aspect_number]
    index = cycle_year % 60 + 1
    print("{}: {}{} ({}-{}, {} {}; {} - year {} of the cycle)"
          .format(year, stem_han, branch_han,
                  stem_pinyin, branch_pinyin, element, animal, aspect, index))

current_year = datetime.now().year
years = [1935, 1938, 1968, 1972, 1976, current_year]
for year in years:
    calculate(year)


Chinese zodiac

Solution:
'''Chinese zodiac'''

from functools import (reduce)
from datetime import datetime

# TRADITIONAL STRINGS -------------------------------------

# zodiacNames :: Dict
def zodiacNames():
    '''天干 tiangan – 10 heavenly stems
       地支 dizhi – 12 terrestrial branches
       五行 wuxing – 5 elements
       生肖 shengxiao – 12 symbolic animals
       阴阳 yinyang - dark and light
    '''
    return dict(
        zip(
            ['tian', 'di', 'wu', 'sx', 'yy'],
            map(
                lambda tpl: list(
                    zip(* [tpl[0]] + list(
                        map(
                            lambda x: x.split(),
                            tpl[1:])
                    ))
                ),
                [
                    # 天干 tiangan – 10 heavenly stems
                    ('甲乙丙丁戊己庚辛壬癸',
                     'jiă yĭ bĭng dīng wù jĭ gēng xīn rén gŭi'),

                    # 地支 dizhi – 12 terrestrial branches
                    ('子丑寅卯辰巳午未申酉戌亥',
                     'zĭ chŏu yín măo chén sì wŭ wèi shēn yŏu xū hài'),

                    # 五行 wuxing – 5 elements
                    ('木火土金水',
                     'mù huǒ tǔ jīn shuǐ',
                     'wood fire earth metal water'),

                    # 十二生肖 shengxiao – 12 symbolic animals
                    ('鼠牛虎兔龍蛇馬羊猴鸡狗豬',
                     'shǔ niú hǔ tù lóng shé mǎ yáng hóu jī gǒu zhū',
                     'rat ox tiger rabbit dragon snake horse goat ' +
                     'monkey rooster dog pig'
                     ),

                    # 阴阳 yinyang
                    ('阳阴', 'yáng yīn')
                ]
            )))

# zodiacYear :: Dict -> [[String]]
def zodiacYear(dct):
    '''A string of strings containing the
       Chinese zodiac tokens for a given year.
    '''
    def tokens(y):
        iYear = y - 4
        iStem = iYear % 10
        iBranch = iYear % 12
        (hStem, pStem) = dct['tian'][iStem]
        (hBranch, pBranch) = dct['di'][iBranch]
        yy = iYear % 2
        return [
            [str(y), '', ''],
            [
                hStem + hBranch,
                pStem + pBranch,
                str((iYear % 60) + 1) + '/60'
            ],
            list(dct['wu'][iStem // 2]),
            list(dct['sx'][iBranch]),
            list(dct['yy'][int(yy)]) + ['dark' if yy else 'light']
        ]
    return lambda year: tokens(year)

# TEST ----------------------------------------------------
# main :: IO ()
def main():
    '''Writing out wiki tables displaying Chinese zodiac
       details for a given list of years.
    '''
    print('\n'.join(
        list(map(
            zodiacTable(zodiacNames()),
            [
                1935, 1938, 1949,
                1968, 1972, 1976,
                datetime.now().year
            ]
        ))
    ))

# WIKI TABLES  --------------------------------------------

# zodiacTable :: Dict -> Int -> String
def zodiacTable(tokens):
    '''A wiki table displaying Chinese zodiac
       details for a a given year.
    '''
    return lambda y: wikiTable({
        'class': 'wikitable',
        'colwidth': '70px'
    })(transpose(zodiacYear(tokens)(y)))

# wikiTable :: Dict -> [[a]] -> String
def wikiTable(opts):
    '''List of lists rendered as a wiki table string.'''
    def colWidth():
        return 'width:' + opts['colwidth'] + '; ' if (
            'colwidth' in opts
        ) else ''

    def cellStyle():
        return opts['cell'] if 'cell' in opts else ''

    return lambda rows: '{| ' + reduce(
        lambda a, k: (
            a + k + '="' + opts[k] + '" ' if k in opts else a
        ),
        ['class', 'style'],
        ''
    ) + '\n' + '\n|-\n'.join(
        '\n'.join(
            ('|' if (0 != i and ('cell' not in opts)) else (
                '|style="' + colWidth() + cellStyle() + '"|'
            )) + (
                str(x) or ' '
            ) for x in row
        ) for i, row in enumerate(rows)
    ) + '\n|}\n\n'

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

# transpose :: Matrix a -> Matrix a
def transpose(m):
    '''The rows and columns of the argument transposed.
       (The matrix containers and rows can be lists or tuples).'''
    if m:
        inner = type(m[0])
        z = zip(*m)
        return (type(m))(
            map(inner, z) if tuple != inner else z
        )
    else:
        return m

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


Church numerals

;Task:
In the Church encoding of natural numbers, the number N is encoded by a function that applies its first argument N times to its second argument.

* '''Church zero''' always returns the identity function, regardless of its first argument. In other words, the first argument is not applied to the second argument at all.
* '''Church one''' applies its first argument f just once to its second argument x, yielding '''f(x)'''
* '''Church two''' applies its first argument f twice to its second argument x, yielding '''f(f(x))'''
* and each successive Church numeral applies its first argument one additional time to its second argument, '''f(f(f(x)))''', '''f(f(f(f(x))))''' ...  The Church numeral 4, for example, returns a quadruple composition of the function supplied as its first argument.

Arithmetic operations on natural numbers can be similarly represented as functions on Church numerals.

In your language define:

* Church Zero,
* a Church successor function (a function on a Church numeral which returns the next Church numeral in the series),
* functions for Addition, Multiplication and Exponentiation over Church numerals,
* a function to convert integers to corresponding Church numerals,
* and a function to convert Church numerals to corresponding integers.

You should:

* Derive Church numerals three and four in terms of Church zero and a Church successor function.
* use Church numeral arithmetic to obtain the the sum and the product of Church 3 and Church 4,
* similarly obtain 4^3 and 3^4 in terms of Church numerals, using a Church numeral exponentiation function,
* convert each result back to an integer, and return it or print it to the console.

Solution:
'''Church numerals'''

from itertools import repeat
from functools import reduce

# ----- CHURCH ENCODINGS OF NUMERALS AND OPERATIONS ------

def churchZero():
    '''The identity function.
       No applications of any supplied f
       to its argument.
    '''
    return lambda f: identity

def churchSucc(cn):
    '''The successor of a given
       Church numeral. One additional
       application of f. Equivalent to
       the arithmetic addition of one.
    '''
    return lambda f: compose(f)(cn(f))

def churchAdd(m):
    '''The arithmetic sum of two Church numerals.'''
    return lambda n: lambda f: compose(m(f))(n(f))

def churchMult(m):
    '''The arithmetic product of two Church numerals.'''
    return lambda n: compose(m)(n)

def churchExp(m):
    '''Exponentiation of Church numerals. m^n'''
    return lambda n: n(m)

def churchFromInt(n):
    '''The Church numeral equivalent of
       a given integer.
    '''
    return lambda f: (
        foldl
        (compose)
        (identity)
        (replicate(n)(f))
    )

# OR, alternatively:
def churchFromInt_(n):
    '''The Church numeral equivalent of a given
       integer, by explicit recursion.
    '''
    if 0 == n:
        return churchZero()
    else:
        return churchSucc(churchFromInt(n - 1))

def intFromChurch(cn):
    '''The integer equivalent of a
       given Church numeral.
    '''
    return cn(succ)(0)

# ------------------------- TEST -------------------------
# main :: IO ()
def main():
    'Tests'

    cThree = churchFromInt(3)
    cFour = churchFromInt(4)

    print(list(map(intFromChurch, [
        churchAdd(cThree)(cFour),
        churchMult(cThree)(cFour),
        churchExp(cFour)(cThree),
        churchExp(cThree)(cFour),
    ])))

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

# compose (flip (.)) :: (a -> b) -> (b -> c) -> a -> c
def compose(f):
    '''A left to right composition of two
       functions f and g'''
    return lambda g: lambda x: g(f(x))

# foldl :: (a -> b -> a) -> a -> [b] -> a
def foldl(f):
    '''Left to right reduction of a list,
       using the binary operator f, and
       starting with an initial value a.
    '''
    def go(acc, xs):
        return reduce(lambda a, x: f(a)(x), xs, acc)
    return lambda acc: lambda xs: go(acc, xs)

# identity :: a -> a
def identity(x):
    '''The identity function.'''
    return x

# replicate :: Int -> a -> [a]
def replicate(n):
    '''A list of length n in which every
       element has the value x.
    '''
    return lambda x: repeat(x, n)

# 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))
    )

if __name__ == '__main__':
    main()


Circles of given radius through two points

2 circles with a given radius through 2 points in 2D space.

Given two points on a plane and a radius, usually two circles of given radius can be drawn through the points.
;Exceptions:
# r==0.0 should be treated as never describing circles (except in the case where the points are coincident).
# If the points are coincident then an infinite number of circles with the point on their circumference can be drawn, unless r==0.0 as well which then collapses the circles to a point.
# If the points form a diameter then return two identical circles ''or'' return a single circle, according to which is the most natural mechanism for the implementation language.
# If the points are too far apart then no circles can be drawn.

;Task detail:
* Write a function/subroutine/method/... that takes two points and a radius and returns the two circles through those points, ''or some indication of special cases where two, possibly equal, circles cannot be returned''.
* Show here the output for the following inputs:

      p1                p2           r
0.1234, 0.9876    0.8765, 0.2345    2.0
0.0000, 2.0000    0.0000, 0.0000    1.0
0.1234, 0.9876    0.1234, 0.9876    2.0
0.1234, 0.9876    0.8765, 0.2345    0.5
0.1234, 0.9876    0.1234, 0.9876    0.0

;Related task:
*   [[Total circles area]].

;See also:
*   [http://mathforum.org/library/drmath/view/53027.html Finding the Center of a Circle from 2 Points and Radius] from Math forum @ Drexel

Solution:
#include
#include

typedef struct{
	double x,y;
	}point;

double distance(point p1,point p2)
{
	return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}

void findCircles(point p1,point p2,double radius)
{
	double separation = distance(p1,p2),mirrorDistance;

	if(separation == 0.0)
	{
		radius == 0.0 ? printf("\nNo circles can be drawn through (%.4f,%.4f)",p1.x,p1.y):
							 printf("\nInfinitely many circles can be drawn through (%.4f,%.4f)",p1.x,p1.y);
	}

	else if(separation == 2*radius)
	{
		printf("\nGiven points are opposite ends of a diameter of the circle with center (%.4f,%.4f) and radius %.4f",(p1.x+p2.x)/2,(p1.y+p2.y)/2,radius);
	}

	else if(separation > 2*radius)
	{
		printf("\nGiven points are farther away from each other than a diameter of a circle with radius %.4f",radius);
	}

	else
	{
		mirrorDistance =sqrt(pow(radius,2) - pow(separation/2,2));

		printf("\nTwo circles are possible.");
		printf("\nCircle C1 with center (%.4f,%.4f), radius %.4f and Circle C2 with center (%.4f,%.4f), radius %.4f",(p1.x+p2.x)/2 + mirrorDistance*(p1.y-p2.y)/separation,(p1.y+p2.y)/2 + mirrorDistance*(p2.x-p1.x)/separation,radius,(p1.x+p2.x)/2 - mirrorDistance*(p1.y-p2.y)/separation,(p1.y+p2.y)/2 - mirrorDistance*(p2.x-p1.x)/separation,radius);
	}
}

int main()
{
    int i;

    point cases[] =
    {	{0.1234, 0.9876},    {0.8765, 0.2345},
	{0.0000, 2.0000},    {0.0000, 0.0000},
	{0.1234, 0.9876},    {0.1234, 0.9876},
	{0.1234, 0.9876},    {0.8765, 0.2345},
	{0.1234, 0.9876},    {0.1234, 0.9876}
    };

    double radii[] = {2.0,1.0,2.0,0.5,0.0};

    for(i=0;i<5;i++)
    {
	printf("\nCase %d)",i+1);
	findCircles(cases[2*i],cases[2*i+1],radii[i]);
    }

    return 0;
}


Solution:
const hDist = (p1, p2) => Math.hypot(...p1.map((e, i) => e - p2[i])) / 2;
const pAng = (p1, p2) => Math.atan(p1.map((e, i) => e - p2[i]).reduce((p, c) => c / p, 1));
const solveF = (p, r) => t => [r*Math.cos(t) + p[0], r*Math.sin(t) + p[1]];
const diamPoints = (p1, p2) => p1.map((e, i) => e + (p2[i] - e) / 2);

const findC = (...args) => {
  const [p1, p2, s] = args;
  const solve = solveF(p1, s);
  const halfDist = hDist(p1, p2);

  let msg = `p1: ${p1}, p2: ${p2}, r:${s} Result: `;
  switch (Math.sign(s - halfDist)) {
    case 0:
      msg += s ? `Points on diameter. Circle at: ${diamPoints(p1, p2)}` :
        'Radius Zero';
      break;
    case 1:
      if (!halfDist) {
        msg += 'Coincident point. Infinite solutions';
      }
      else {
        let theta = pAng(p1, p2);
        let theta2 = Math.acos(halfDist / s);
        [1, -1].map(e => solve(theta + e * theta2)).forEach(
          e => msg += `Circle at ${e} `);
      }
      break;
    case -1:
      msg += 'No intersection. Points further apart than circle diameter';
      break;
  }
  return msg;
};

[
  [[0.1234, 0.9876], [0.8765, 0.2345], 2.0],
  [[0.0000, 2.0000], [0.0000, 0.0000], 1.0],
  [[0.1234, 0.9876], [0.1234, 0.9876], 2.0],
  [[0.1234, 0.9876], [0.8765, 0.2345], 0.5],
  [[0.1234, 0.9876], [0.1234, 0.9876], 0.0]
].forEach((t,i) => console.log(`Test: ${i}: ${findC(...t)}`));


Solution:
from collections import namedtuple
from math import sqrt

Pt = namedtuple('Pt', 'x, y')
Circle = Cir = namedtuple('Circle', 'x, y, r')

def circles_from_p1p2r(p1, p2, r):
    'Following explanation at http://mathforum.org/library/drmath/view/53027.html'
    if r == 0.0:
        raise ValueError('radius of zero')
    (x1, y1), (x2, y2) = p1, p2
    if p1 == p2:
        raise ValueError('coincident points gives infinite number of Circles')
    # delta x, delta y between points
    dx, dy = x2 - x1, y2 - y1
    # dist between points
    q = sqrt(dx**2 + dy**2)
    if q > 2.0*r:
        raise ValueError('separation of points > diameter')
    # halfway point
    x3, y3 = (x1+x2)/2, (y1+y2)/2
    # distance along the mirror line
    d = sqrt(r**2-(q/2)**2)
    # One answer
    c1 = Cir(x = x3 - d*dy/q,
             y = y3 + d*dx/q,
             r = abs(r))
    # The other answer
    c2 = Cir(x = x3 + d*dy/q,
             y = y3 - d*dx/q,
             r = abs(r))
    return c1, c2

if __name__ == '__main__':
    for p1, p2, r in [(Pt(0.1234, 0.9876), Pt(0.8765, 0.2345), 2.0),
                      (Pt(0.0000, 2.0000), Pt(0.0000, 0.0000), 1.0),
                      (Pt(0.1234, 0.9876), Pt(0.1234, 0.9876), 2.0),
                      (Pt(0.1234, 0.9876), Pt(0.8765, 0.2345), 0.5),
                      (Pt(0.1234, 0.9876), Pt(0.1234, 0.9876), 0.0)]:
        print('Through points:\n  %r,\n  %r\n  and radius %f\nYou can construct the following circles:'
              % (p1, p2, r))
        try:
            print('  %r\n  %r\n' % circles_from_p1p2r(p1, p2, r))
        except ValueError as v:
            print('  ERROR: %s\n' % (v.args[0],))


Cistercian numerals

Cistercian numerals were used across Europe by [https://en.wikipedia.org/wiki/Cistercians Cistercian] monks during the Late Medieval Period as an alternative to Roman numerals. They were used to represent base 10 integers from '''0''' to '''9999'''.

;How they work
All Cistercian numerals begin with a vertical line segment, which by itself represents the number '''0'''. Then, glyphs representing the digits '''1''' through '''9''' are optionally added to the four quadrants surrounding the vertical line segment. These glyphs are drawn with vertical and horizontal symmetry about the initial line segment. Each quadrant corresponds to a digit place in the number:

:* The '''upper-right''' quadrant represents the '''ones''' place.
:* The '''upper-left''' quadrant represents the '''tens''' place.
:* The '''lower-right''' quadrant represents the '''hundreds''' place.
:* The '''lower-left''' quadrant represents the '''thousands''' place.

Please consult the following image for examples of Cistercian numerals showing each glyph: [https://upload.wikimedia.org/wikipedia/commons/6/67/Cistercian_digits_%28vertical%29.svg]

;Task

:* Write a function/procedure/routine to display any given Cistercian numeral. This could be done by drawing to the display, creating an image, or even as text (as long as it is a reasonable facsimile).

:* Use the routine to show the following Cistercian numerals:

::* 0
::* 1
::* 20
::* 300
::* 4000
::* 5555
::* 6789
::* And a number of your choice!

;Notes
Due to the inability to upload images to Rosetta Code as of this task's creation, showing output here on this page is not required. However, it is welcomed — especially for text output.

;See also

:* '''[https://www.youtube.com/watch?v=9p55Qgt7Ciw Numberphile - The Forgotten Number System]'''
:* '''[https://www.dcode.fr/cistercian-numbers dcode.fr - Online Cistercian numeral converter]'''

Solution:
#include

#define GRID_SIZE 15
char canvas[GRID_SIZE][GRID_SIZE];

void initN() {
    int i, j;
    for (i = 0; i < GRID_SIZE; i++) {
        for (j = 0; j < GRID_SIZE; j++) {
            canvas[i][j] = ' ';
        }
        canvas[i][5] = 'x';
    }
}

void horizontal(size_t c1, size_t c2, size_t r) {
    size_t c;
    for (c = c1; c <= c2; c++) {
        canvas[r][c] = 'x';
    }
}

void vertical(size_t r1, size_t r2, size_t c) {
    size_t r;
    for (r = r1; r <= r2; r++) {
        canvas[r][c] = 'x';
    }
}

void diagd(size_t c1, size_t c2, size_t r) {
    size_t c;
    for (c = c1; c <= c2; c++) {
        canvas[r + c - c1][c] = 'x';
    }
}

void diagu(size_t c1, size_t c2, size_t r) {
    size_t c;
    for (c = c1; c <= c2; c++) {
        canvas[r - c + c1][c] = 'x';
    }
}

void drawOnes(int v) {
    switch (v) {
    case 1:
        horizontal(6, 10, 0);
        break;
    case 2:
        horizontal(6, 10, 4);
        break;
    case 3:
        diagd(6, 10, 0);
        break;
    case 4:
        diagu(6, 10, 4);
        break;
    case 5:
        drawOnes(1);
        drawOnes(4);
        break;
    case 6:
        vertical(0, 4, 10);
        break;
    case 7:
        drawOnes(1);
        drawOnes(6);
        break;
    case 8:
        drawOnes(2);
        drawOnes(6);
        break;
    case 9:
        drawOnes(1);
        drawOnes(8);
        break;
    default:
        break;
    }
}

void drawTens(int v) {
    switch (v) {
    case 1:
        horizontal(0, 4, 0);
        break;
    case 2:
        horizontal(0, 4, 4);
        break;
    case 3:
        diagu(0, 4, 4);
        break;
    case 4:
        diagd(0, 4, 0);
        break;
    case 5:
        drawTens(1);
        drawTens(4);
        break;
    case 6:
        vertical(0, 4, 0);
        break;
    case 7:
        drawTens(1);
        drawTens(6);
        break;
    case 8:
        drawTens(2);
        drawTens(6);
        break;
    case 9:
        drawTens(1);
        drawTens(8);
        break;
    default:
        break;
    }
}

void drawHundreds(int hundreds) {
    switch (hundreds) {
    case 1:
        horizontal(6, 10, 14);
        break;
    case 2:
        horizontal(6, 10, 10);
        break;
    case 3:
        diagu(6, 10, 14);
        break;
    case 4:
        diagd(6, 10, 10);
        break;
    case 5:
        drawHundreds(1);
        drawHundreds(4);
        break;
    case 6:
        vertical(10, 14, 10);
        break;
    case 7:
        drawHundreds(1);
        drawHundreds(6);
        break;
    case 8:
        drawHundreds(2);
        drawHundreds(6);
        break;
    case 9:
        drawHundreds(1);
        drawHundreds(8);
        break;
    default:
        break;
    }
}

void drawThousands(int thousands) {
    switch (thousands) {
    case 1:
        horizontal(0, 4, 14);
        break;
    case 2:
        horizontal(0, 4, 10);
        break;
    case 3:
        diagd(0, 4, 10);
        break;
    case 4:
        diagu(0, 4, 14);
        break;
    case 5:
        drawThousands(1);
        drawThousands(4);
        break;
    case 6:
        vertical(10, 14, 0);
        break;
    case 7:
        drawThousands(1);
        drawThousands(6);
        break;
    case 8:
        drawThousands(2);
        drawThousands(6);
        break;
    case 9:
        drawThousands(1);
        drawThousands(8);
        break;
    default:
        break;
    }
}

void draw(int v) {
    int thousands = v / 1000;
    v %= 1000;

    int hundreds = v / 100;
    v %= 100;

    int tens = v / 10;
    int ones = v % 10;

    if (thousands > 0) {
        drawThousands(thousands);
    }
    if (hundreds > 0) {
        drawHundreds(hundreds);
    }
    if (tens > 0) {
        drawTens(tens);
    }
    if (ones > 0) {
        drawOnes(ones);
    }
}

void write(FILE *out) {
    int i;
    for (i = 0; i < GRID_SIZE; i++) {
        fprintf(out, "%-.*s", GRID_SIZE, canvas[i]);
        putc('\n', out);
    }
}

void test(int n) {
    printf("%d:\n", n);
    initN();
    draw(n);
    write(stdout);
    printf("\n\n");
}

int main() {
    test(0);
    test(1);
    test(20);
    test(300);
    test(4000);
    test(5555);
    test(6789);
    test(9999);

    return 0;
}


Cistercian numerals

Solution:
// html
document.write(`

0
1
20
300
4000
5555
6789
Random

`);

// to show given examples
// can be deleted for normal use
function set(num) {
  document.getElementById('num').value = num;
  showCist();
}

const SW = 10; // stroke width
let canvas = document.getElementById('cist'),
    cx = canvas.getContext('2d');

function showCist() {
  // reset canvas
  cx.clearRect(0, 0, canvas.width, canvas.height);
  cx.lineWidth = SW;
  cx.beginPath();
  cx.moveTo(100, 0+.5*SW);
  cx.lineTo(100, 300-.5*SW);
  cx.stroke();

  let num = document.getElementById('num').value;
  while (num.length < 4) num = '0' + num;  // fills leading zeros to $num

  /***********************\
  |        POINTS:        |
  | ********************* |
  |                       |
  |     a --- b --- c     |
  |     |     |     |     |
  |     d --- e --- f     |
  |     |     |     |     |
  |     g --- h --- i     |
  |     |     |     |     |
  |     j --- k --- l     |
  |                       |
  \***********************/
  let
  a = [0+SW,   0+SW],   b = [100,   0+SW],   c = [200-SW,   0+SW],
  d = [0+SW,    100],   e = [100,    100],   f = [200-SW,    100],
  g = [0+SW,    200],   h = [100,    200],   i = [200-SW,    200],
  j = [0+SW, 300-SW],   k = [100, 300-SW],   l = [200-SW, 300-SW];

  function draw() {
    let x = 1;
    cx.beginPath();
    cx.moveTo(arguments[0][0], arguments[0][1]);
    while (x < arguments.length) {
      cx.lineTo(arguments[x][0], arguments[x][1]);
      x++;
    }
    cx.stroke();
  }

  // 1000s
  switch (num[0]) {
    case '1': draw(j, k);       break;       case '2': draw(g, h);    break;
    case '3': draw(g, k);       break;       case '4': draw(j, h);    break;
    case '5': draw(k, j, h);    break;       case '6': draw(g, j);    break;
    case '7': draw(g, j, k);    break;       case '8': draw(j, g, h); break;
    case '9': draw(h, g, j, k); break;
  }
  // 100s
  switch (num[1]) {
    case '1': draw(k, l);       break;       case '2': draw(h, i);    break;
    case '3': draw(k, i);       break;       case '4': draw(h, l);    break;
    case '5': draw(h, l, k);    break;       case '6': draw(i, l);    break;
    case '7': draw(k, l, i);    break;       case '8': draw(h, i, l); break;
    case '9': draw(h, i, l, k); break;
  }
  // 10s
  switch (num[2]) {
    case '1': draw(a, b);       break;       case '2': draw(d, e);    break;
    case '3': draw(d, b);       break;       case '4': draw(a, e);    break;
    case '5': draw(b, a, e);    break;       case '6': draw(a, d);    break;
    case '7': draw(d, a, b);    break;       case '8': draw(a, d, e); break;
    case '9': draw(b, a, d, e); break;
  }
  // 1s
  switch (num[3]) {
    case '1': draw(b, c);       break;       case '2': draw(e, f);    break;
    case '3': draw(b, f);       break;       case '4': draw(e, c);    break;
    case '5': draw(b, c, e);    break;       case '6': draw(c, f);    break;
    case '7': draw(b, c, f);    break;       case '8': draw(e, f, c); break;
    case '9': draw(b, c, f, e); break;
  }
}


Cistercian numerals

Solution:
# -*- coding: utf-8 -*-
"""
Some UTF-8 chars used:

‾	8254	203E	‾	OVERLINE
┃	9475	2503	 	BOX DRAWINGS HEAVY VERTICAL
╱	9585	2571	 	BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
╲	9586	2572	 	BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
◸	9720	25F8	 	UPPER LEFT TRIANGLE
◹	9721	25F9	 	UPPER RIGHT TRIANGLE
◺	9722	25FA	 	LOWER LEFT TRIANGLE
◻	9723	25FB	 	WHITE MEDIUM SQUARE
◿	9727	25FF	 	LOWER RIGHT TRIANGLE

"""

#%% digit sections

def _init():
    "digit sections for forming numbers"
    digi_bits = """
#0  1   2  3  4  5  6   7   8   9
#
 .  ‾   _  ╲  ╱  ◸  .|  ‾|  _|  ◻
#
 .  ‾   _  ╱  ╲  ◹  |.  |‾  |_  ◻
#
 .  _  ‾   ╱  ╲  ◺  .|  _|  ‾|  ◻
#
 .  _  ‾   ╲  ╱  ◿  |.  |_  |‾  ◻

""".strip()

    lines = [[d.replace('.', ' ') for d in ln.strip().split()]
             for ln in digi_bits.strip().split('\n')
             if '#' not in ln]
    formats = '<2 >2 <2 >2'.split()
    digits = [[f"{dig:{f}}" for dig in line]
              for f, line in zip(formats, lines)]

    return digits

_digits = _init()

#%% int to 3-line strings
def _to_digits(n):
    assert 0 <= n < 10_000 and int(n) == n

    return [int(digit) for digit in f"{int(n):04}"][::-1]

def num_to_lines(n):
    global _digits
    d = _to_digits(n)
    lines = [
        ''.join((_digits[1][d[1]], '┃',  _digits[0][d[0]])),
        ''.join((_digits[0][   0], '┃',  _digits[0][   0])),
        ''.join((_digits[3][d[3]], '┃',  _digits[2][d[2]])),
        ]

    return lines

def cjoin(c1, c2, spaces='   '):
    return [spaces.join(by_row) for by_row in zip(c1, c2)]

#%% main
if __name__ == '__main__':
    #n = 6666
    #print(f"Arabic {n} to Cistercian:\n")
    #print('\n'.join(num_to_lines(n)))

    for pow10 in range(4):
        step = 10 ** pow10
        print(f'\nArabic {step}-to-{9*step} by {step} in Cistercian:\n')
        lines = num_to_lines(step)
        for n in range(step*2, step*10, step):
            lines = cjoin(lines, num_to_lines(n))
        print('\n'.join(lines))

    numbers = [0, 5555, 6789, 6666]
    print(f'\nArabic {str(numbers)[1:-1]} in Cistercian:\n')
    lines = num_to_lines(numbers[0])
    for n in numbers[1:]:
        lines = cjoin(lines, num_to_lines(n))
    print('\n'.join(lines))


Closures/Value capture

;Task:
Create a list of ten functions, in the simplest manner possible   (anonymous functions are encouraged),   such that the function at index   '' i ''    (you may choose to start    '' i ''    from either    '''0'''    or    '''1'''),     when run, should return the square of the index,   that is,    '' i '' 2.

Display the result of running any but the last function, to demonstrate that the function indeed remembers its value.

;Goal:
Demonstrate how to create a series of independent closures based on the same template but maintain separate copies of the variable closed over.

In imperative languages, one would generally use a loop with a mutable counter variable.

For each function to maintain the correct number, it has to capture the ''value'' of the variable at the time it was created, rather than just a reference to the variable, which would have a different value by the time the function was run.

See also: [[Multiple distinct objects]]

Solution:
#include
#include
#include
#include

typedef int (*f_int)();

#define TAG 0xdeadbeef
int _tmpl() {
	volatile int x = TAG;
	return x * x;
}

#define PROT (PROT_EXEC | PROT_WRITE)
#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS)
f_int dupf(int v)
{
	size_t len = (void*)dupf - (void*)_tmpl;
	f_int ret = mmap(NULL, len, PROT, FLAGS, 0, 0);
	char *p;
	if(ret == MAP_FAILED) {
		perror("mmap");
		exit(-1);
	}
	memcpy(ret, _tmpl, len);
	for (p = (char*)ret; p < (char*)ret + len - sizeof(int); p++)
		if (*(int *)p == TAG) *(int *)p = v;
	return ret;
}

int main()
{
	f_int funcs[10];
	int i;
	for (i = 0; i < 10; i++) funcs[i] = dupf(i);

	for (i = 0; i < 9; i++)
		printf("func[%d]: %d\n", i, funcs[i]());

	return 0;
}


Closures/Value capture

Solution:
var funcs = [];
for (var i = 0; i < 10; i++) {
    funcs.push( (function(i) {
                     return function() { return i * i; }
                })(i) );
}
window.alert(funcs[3]()); // alerts "9"


Closures/Value capture

Solution:
<syntaxhighlight lang="javascript"><script type="application/javascript;version=1.7">
var funcs = [];
for (var i = 0; i < 10; i++) {
    let (i = i) {
        funcs.push( function() { return i * i; } );
    }
}
window.alert(funcs[3]()); // alerts "9"
</script></syntaxhighlight>


Closures/Value capture

Solution:
"use strict";
let funcs = [];
for (let i = 0; i < 10; ++i) {
    funcs.push((i => () => i*i)(i));
}
console.log(funcs[3]());


Closures/Value capture

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

    // Int -> Int -> [Int]
    function range(m, n) {
        return Array.apply(null, Array(n - m + 1))
            .map(function (x, i) {
                return m + i;
            });
    }

    var lstFns = range(0, 10)
        .map(function (i) {
            return function () {
                return i * i;
            };
        })

    return lstFns[3]();

})();


Closures/Value capture

Solution:
funcs = []
for i in range(10):
    funcs.append((lambda i: lambda: i * i)(i))
print funcs[3]() # prints 9


Colorful numbers

A '''colorful number''' is a non-negative base 10 integer where the product of every sub group of consecutive digits is unique.

;E.G.

24753 is a colorful number. 2, 4, 7, 5, 3, (2×4)8, (4×7)28, (7×5)35, (5×3)15, (2×4×7)56, (4×7×5)140, (7×5×3)105, (2×4×7×5)280, (4×7×5×3)420, (2×4×7×5×3)840

Every product is unique.

2346 is '''not''' a colorful number. 2, 3, 4, '''6''', (2×3)'''6''', (3×4)12, (4×6)24, (2×3×4)48, (3×4×6)72, (2×3×4×6)144

The product '''6''' is repeated.

Single digit numbers '''are''' considered to be colorful. A colorful number larger than 9 cannot contain a repeated digit, the digit 0 or the digit 1. As a consequence, there is a firm upper limit for colorful numbers; no colorful number can have more than 8 digits.

;Task

* Write a routine (subroutine, function, procedure, whatever it may be called in your language) to test if a number is a colorful number or not.
* Use that routine to find all of the colorful numbers less than 100.
* Use that routine to find the largest possible colorful number.

;Stretch

* Find and display the count of colorful numbers in each order of magnitude.
* Find and show the total count of '''all''' colorful numbers.

''Colorful numbers have no real number theory application. They are more a recreational math puzzle than a useful tool.''

Solution:
#include
#include
#include
#include

bool colorful(int n) {
    // A colorful number cannot be greater than 98765432.
    if (n < 0 || n > 98765432)
        return false;
    int digit_count[10] = {};
    int digits[8] = {};
    int num_digits = 0;
    for (int m = n; m > 0; m /= 10) {
        int d = m % 10;
        if (n > 9 && (d == 0 || d == 1))
            return false;
        if (++digit_count[d] > 1)
            return false;
        digits[num_digits++] = d;
    }
    // Maximum number of products is (8 x 9) / 2.
    int products[36] = {};
    for (int i = 0, product_count = 0; i < num_digits; ++i) {
        for (int j = i, p = 1; j < num_digits; ++j) {
            p *= digits[j];
            for (int k = 0; k < product_count; ++k) {
                if (products[k] == p)
                    return false;
            }
            products[product_count++] = p;
        }
    }
    return true;
}

static int count[8];
static bool used[10];
static int largest = 0;

void count_colorful(int taken, int n, int digits) {
    if (taken == 0) {
        for (int d = 0; d < 10; ++d) {
            used[d] = true;
            count_colorful(d < 2 ? 9 : 1, d, 1);
            used[d] = false;
        }
    } else {
        if (colorful(n)) {
            ++count[digits - 1];
            if (n > largest)
                largest = n;
        }
        if (taken < 9) {
            for (int d = 2; d < 10; ++d) {
                if (!used[d]) {
                    used[d] = true;
                    count_colorful(taken + 1, n * 10 + d, digits + 1);
                    used[d] = false;
                }
            }
        }
    }
}

int main() {
    setlocale(LC_ALL, "");

    clock_t start = clock();

    printf("Colorful numbers less than 100:\n");
    for (int n = 0, count = 0; n < 100; ++n) {
        if (colorful(n))
            printf("%2d%c", n, ++count % 10 == 0 ? '\n' : ' ');
    }

    count_colorful(0, 0, 0);
    printf("\n\nLargest colorful number: %'d\n", largest);

    printf("\nCount of colorful numbers by number of digits:\n");
    int total = 0;
    for (int d = 0; d < 8; ++d) {
        printf("%d   %'d\n", d + 1, count[d]);
        total += count[d];
    }
    printf("\nTotal: %'d\n", total);

    clock_t end = clock();
    printf("\nElapsed time: %f seconds\n",
           (end - start + 0.0) / CLOCKS_PER_SEC);
    return 0;
}


Colorful numbers

Solution:
from math import prod

largest = [0]

def iscolorful(n):
    if 0 <= n < 10:
        return True
    dig = [int(c) for c in str(n)]
    if 1 in dig or 0 in dig or len(dig) > len(set(dig)):
        return False
    products = list(set(dig))
    for i in range(len(dig)):
        for j in range(i+2, len(dig)+1):
            p = prod(dig[i:j])
            if p in products:
                return False
            products.append(p)

    largest[0] = max(n, largest[0])
    return True

print('Colorful numbers for 1:25, 26:50, 51:75, and 76:100:')
for i in range(1, 101, 25):
    for j in range(25):
        if iscolorful(i + j):
            print(f'{i + j: 5,}', end='')
    print()

csum = 0
for i in range(8):
    j = 0 if i == 0 else 10**i
    k = 10**(i+1) - 1
    n = sum(iscolorful(x) for x in range(j, k+1))
    csum += n
    print(f'The count of colorful numbers between {j} and {k} is {n}.')

print(f'The largest possible colorful number is {largest[0]}.')
print(f'The total number of colorful numbers is {csum}.')


Colour bars/Display

;Task:
Display a series of vertical color bars across the width of the display.

The color bars should either use:
:::*   the system palette,   or
:::*   the sequence of colors:
::::::*   black
::::::*   red
::::::*   green
::::::*   blue
::::::*   magenta
::::::*   cyan
::::::*   yellow
::::::*   white

Solution:
#include

#define COLOURS 8

int main()
{
	int colour=0,i,j,MAXROW,MAXCOL;
	struct text_info tInfo;
	gettextinfo(&tInfo);
	MAXROW = tInfo.screenheight;
	MAXCOL = tInfo.screenwidth;
	textbackground(BLACK);     //8 colour constants are defined
	clrscr();

	for(colour=0;colour

===Graphics Mode===
The required functions and structures are in graphics.h, conio.h is included for getch().

#include
#include

int main()
{
	int d=DETECT,m,maxX,maxY,maxColours,i;
	initgraph(&d,&m,"c:/turboc3/bgi");
	maxX = getmaxx();
	maxY = getmaxy();
	maxColours = getmaxcolor();

	for(i=0;i


Colour bars/Display

Solution:
#!/usr/bin/env python
#vertical coloured stripes in window in Python 2.7.1

from livewires import *

horiz=640; vert=480
begin_graphics(width=horiz,height=vert,title="v_stripes",background=Colour.black)
NameColors=["black","red","green","dark_blue","purple","blue","yellow","white"]
stepik=horiz/len(NameColors)

for index,each in enumerate(NameColors):
	ExcStrng="set_colour(Colour."+each+")"
	exec ExcStrng
	box(index*stepik,0,(index+1)*stepik,vert,filled=1)

while keys_pressed() != ['x']: # press x key to terminate program
	pass

end_graphics()


Colour pinstripe/Printer

The task is to create 1 point wide colour vertical pinstripes with a sufficient number of pinstripes to span the entire width of the colour graphics printer. The pinstripes should alternate between each individual cartridge ink and ink pair and black and white pinstripes should be included. A typical pinstripe sequence woud be black, red, green, blue, magenta, cyan, yellow, white.

After the first inch of printing, we switch to a wider 2 pixel wide vertical pinstripe pattern. and to 3 point wide vertical for the next inch, and then 4 point wide, etc. This trend continues for the entire length of the page (or for 12 inches of run length in the case of a printer using continuous roll stationery). After printing the test pattern the page is ejected (or the test pattern is rolled clear of the printer enclosure, in the case of continuous roll printers).

Note that it is an acceptable solution to use the smallest marks that the language provides, rather than working at native printer resolution, where this is not achievable from within the language.

Optionally, on systems where the printer resolution cannot be determined, it is permissible to prompt the user for printer resolution, and to calculate point size based on user input, enabling fractional point sizes to be used.

Solution:
from turtle import *
from PIL import Image
import time
import subprocess

"""

Only works on Windows. Assumes that you have Ghostscript
installed and in your path.

https://www.ghostscript.com/download/gsdnld.html

Hard coded to 100 pixels per inch.

"""

colors = ["black", "red", "green", "blue", "magenta", "cyan", "yellow", "white"]

screen = getscreen()

# width and height in pixels
# aspect ratio for 11 by 8.5 paper

inch_width = 11.0
inch_height = 8.5

pixels_per_inch = 100

pix_width = int(inch_width*pixels_per_inch)
pix_height = int(inch_height*pixels_per_inch)

screen.setup (width=pix_width, height=pix_height, startx=0, starty=0)

screen.screensize(pix_width,pix_height)

# center is 0,0

# get coordinates of the edges

left_edge = -screen.window_width()//2

right_edge = screen.window_width()//2

bottom_edge = -screen.window_height()//2

top_edge = screen.window_height()//2

# draw quickly

screen.delay(0)
screen.tracer(5)

for inch in range(int(inch_width)-1):
    line_width = inch + 1
    pensize(line_width)
    colornum = 0

    min_x = left_edge + (inch * pixels_per_inch)
    max_x = left_edge + ((inch+1) * pixels_per_inch)

    for y in range(bottom_edge,top_edge,line_width):
        penup()
        pencolor(colors[colornum])
        colornum = (colornum + 1) % len(colors)
        setposition(min_x,y)
        pendown()
        setposition(max_x,y)

screen.getcanvas().postscript(file="striped.eps")

# convert to jpeg
# won't work without Ghostscript.

im = Image.open("striped.eps")
im.save("striped.jpg")

# Got idea from http://rosettacode.org/wiki/Colour_pinstripe/Printer#Go

subprocess.run(["mspaint", "/pt", "striped.jpg"])


Comma quibbling

Comma quibbling is a task originally set by Eric Lippert in his [http://blogs.msdn.com/b/ericlippert/archive/2009/04/15/comma-quibbling.aspx blog].

;Task:

Write a function to generate a string output which is the concatenation of input words from a list/sequence where:
# An input of no words produces the output string of just the two brace characters "{}".
# An input of just one word, e.g. ["ABC"], produces the output string of the word inside the two braces, e.g. "{ABC}".
# An input of two words, e.g. ["ABC", "DEF"], produces the output string of the two words inside the two braces with the words separated by the string " and ", e.g. "{ABC and DEF}".
# An input of three or more words, e.g. ["ABC", "DEF", "G", "H"], produces the output string of all but the last word separated by ", " with the last word separated by " and " and all within braces; e.g. "{ABC, DEF, G and H}".

Test your function with the following series of inputs showing your output here on this page:
* []                       # (No input words).
* ["ABC"]
* ["ABC", "DEF"]
* ["ABC", "DEF", "G", "H"]

Note: Assume words are non-empty strings of uppercase characters for this task.

Solution:
#include
#include
#include

char *quib(const char **strs, size_t size)
{

    size_t len = 3 + ((size > 1) ? (2 * size + 1) : 0);
    size_t i;

    for (i = 0; i < size; i++)
        len += strlen(strs[i]);

    char *s = malloc(len * sizeof(*s));
    if (!s)
    {
        perror("Can't allocate memory!\n");
        exit(EXIT_FAILURE);
    }

    strcpy(s, "{");
    switch (size) {
        case 0:  break;
        case 1:  strcat(s, strs[0]);
                 break;
        default: for (i = 0; i < size - 1; i++)
                 {
                     strcat(s, strs[i]);
                     if (i < size - 2)
                         strcat(s, ", ");
                     else
                         strcat(s, " and ");
                 }
                 strcat(s, strs[i]);
                 break;
    }
    strcat(s, "}");
    return s;
}

int main(void)
{
    const char *test[] = {"ABC", "DEF", "G", "H"};
    char *s;

    for (size_t i = 0; i < 5; i++)
    {
        s = quib(test, i);
        printf("%s\n", s);
        free(s);
    }
    return EXIT_SUCCESS;
}


Comma quibbling

Solution:
function quibble(words) {
  return "{" +
    words.slice(0, words.length-1).join(",") +
   (words.length > 1 ? " and " : "") +
   (words[words.length-1] || '') +
  "}";
}

[[], ["ABC"], ["ABC", "DEF"], ["ABC", "DEF", "G", "H"]].forEach(
  function(s) {
    console.log(quibble(s));
  }
);


Comma quibbling

Solution:
>>> def strcat(sequence):
    return '{%s}' % ', '.join(sequence)[::-1].replace(',', 'dna ', 1)[::-1]

>>> for seq in ([], ["ABC"], ["ABC", "DEF"], ["ABC", "DEF", "G", "H"]):
    print('Input: %-24r -> Output: %r' % (seq, strcat(seq)))

Input: []                       -> Output: '{}'
Input: ['ABC']                  -> Output: '{ABC}'
Input: ['ABC', 'DEF']           -> Output: '{ABC and DEF}'
Input: ['ABC', 'DEF', 'G', 'H'] -> Output: '{ABC, DEF, G and H}'
>>>


Command-line arguments

See also [[Program name]].

For parsing command line arguments intelligently, see [[Parsing command-line arguments]].

Example command line:

 myprogram -c "alpha beta" -h "gamma"

Solution:
#include
#include

int main(int argc, char* argv[])
{
  int i;
  (void) printf("This program is named %s.\n", argv[0]);
  for (i = 1; i < argc; ++i)
    (void) printf("the argument #%d is %s\n", i, argv[i]);
  return EXIT_SUCCESS;
}


Command-line arguments

Solution:
process.argv.forEach((val, index) => {
  console.log(`${index}: ${val}`);
});


Command-line arguments

Solution:
var objArgs = WScript.Arguments;
for (var i = 0; i < objArgs.length; i++)
   WScript.Echo(objArgs.Item(i));


Command-line arguments

Solution:
import System;
var argv:String[] = Environment.GetCommandLineArgs();
for (var i in argv)
  print(argv[i]);


Command-line arguments

Solution:
for (var i = 0; i < arguments.length; i++)
    print(arguments[i]);


Command-line arguments

Solution:
import sys
program_name = sys.argv[0]
arguments = sys.argv[1:]
count = len(arguments)


Compare a list of strings

;Task:
Given a   list   of arbitrarily many strings, show how to:

*   test if they are all lexically '''equal'''
*   test if every string is lexically '''less than''' the one after it  ''(i.e. whether the list is in strict ascending order)''

Each of those two tests should result in a single true or false value, which could be used as the condition of an    if    statement or similar.

If the input list has less than two elements, the tests should always return true.

There is ''no'' need to provide a complete program and output.

Assume that the strings are already stored in an array/list/sequence/tuple variable (whatever is most idiomatic) with the name   strings,   and just show the expressions for performing those two tests on it (plus of course any includes and custom functions etc. that it needs),   with as little distractions as possible.

Try to write your solution in a way that does not modify the original list,   but if it does then please add a note to make that clear to readers.

If you need further guidance/clarification,   see [[#Perl]] and [[#Python]] for solutions that use implicit short-circuiting loops,   and [[#Raku]] for a solution that gets away with simply using a built-in language feature.

Solution:
#include
#include

static bool
strings_are_equal(const char **strings, size_t nstrings)
{
    for (size_t i = 1; i < nstrings; i++)
        if (strcmp(strings[0], strings[i]) != 0)
            return false;
    return true;
}

static bool
strings_are_in_ascending_order(const char **strings, size_t nstrings)
{
    for (size_t i = 1; i < nstrings; i++)
        if (strcmp(strings[i - 1], strings[i]) >= 0)
            return false;
    return true;
}


Compare a list of strings

Solution:
function allEqual(a) {
  var out = true, i = 0;
  while (++i

===ES6===
====Functional====

Using a generic zipWith, and functionally composed predicates:
(() => {
    'use strict';

    // allEqual :: [String] -> Bool
    let allEqual = xs => and(zipWith(equal, xs, xs.slice(1))),

        // azSorted :: [String] -> Bool
        azSorted = xs => and(zipWith(azBefore, xs, xs.slice(1))),

        // equal :: a -> a -> Bool
        equal = (a, b) => a === b,

        // azBefore :: String -> String -> Bool
        azBefore = (a, b) => a.toLowerCase() <= b.toLowerCase();

    // GENERIC

    // and :: [Bool] -> Bool
    let and = xs => xs.reduceRight((a, x) => a && x, true),

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

    // TEST

    let lists = [
        ['isiZulu', 'isiXhosa', 'isiNdebele', 'Xitsonga',
            'Tshivenda', 'Setswana', 'Sesotho sa Leboa', 'Sesotho',
            'English', 'Afrikaans'
        ],
        ['Afrikaans', 'English', 'isiNdebele', 'isiXhosa',
            'isiZulu', 'Sesotho', 'Sesotho sa Leboa', 'Setswana',
            'Tshivenda', 'Xitsonga',
        ],
        ['alpha', 'alpha', 'alpha', 'alpha', 'alpha', 'alpha',
            'alpha', 'alpha', 'alpha', 'alpha', 'alpha', 'alpha'
        ]
    ];

    return {
        allEqual: lists.map(allEqual),
        azSorted: lists.map(azSorted)
    };

})();


Compare a list of strings

Solution:
from operator import (eq, lt)

xs = ["alpha", "beta", "gamma", "delta", "epsilon", "zeta",
      "eta", "theta", "iota", "kappa", "lambda", "mu"]

ys = ["alpha", "beta", "gamma", "delta", "epsilon", "zeta",
      "eta", "theta", "iota", "kappa", "lambda", "mu"]

az = sorted(xs)

print (
    all(map(eq, xs, ys)),

    all(map(lt, xs, xs[1:])),

    all(map(lt, az, az[1:]))
)


Compile-time calculation

Some programming languages allow calculation of values at compile time.

;Task:
Calculate    10!    (ten factorial)   at compile time.

Print the result when the program is run.

Discuss what limitations apply to compile-time calculations in your language.

Solution:
#include
#include

#define ORDER_PP_DEF_8fac ORDER_PP_FN( \
8fn(8X, 8seq_fold(8times, 1, 8seq_iota(1, 8inc(8X)))) )

int main(void) {
	printf("10! = %d\n", ORDER_PP( 8to_lit( 8fac(10) ) ) );
	return 0;
}


Compiler/AST interpreter

An AST interpreter interprets an [https://en.wikipedia.org/wiki/Abstract_syntax_tree Abstract Syntax Tree (AST)]
produced by a Syntax Analyzer.

Take the AST output from the Syntax analyzer task, and interpret it as appropriate.
Refer to the Syntax analyzer task for details of the AST.

;Loading the AST from the syntax analyzer is as simple as (pseudo code):

def load_ast()
    line = readline()
    # Each line has at least one token
    line_list = tokenize the line, respecting double quotes

    text = line_list[0] # first token is always the node type

    if text == ";"   # a terminal node
        return NULL

    node_type = text # could convert to internal form if desired

    # A line with two tokens is a leaf node
    # Leaf nodes are: Identifier, Integer, String
    # The 2nd token is the value
    if len(line_list) > 1
        return make_leaf(node_type, line_list[1])

    left = load_ast()
    right = load_ast()
    return make_node(node_type, left, right)

; The interpreter algorithm is relatively simple:

interp(x)
    if x == NULL return NULL
    elif x.node_type == Integer return x.value converted to an integer
    elif x.node_type == Ident   return the current value of variable x.value
    elif x.node_type == String  return x.value
    elif x.node_type == Assign
                    globals[x.left.value] = interp(x.right)
                    return NULL
    elif x.node_type is a binary operator return interp(x.left) operator interp(x.right)
    elif x.node_type is a unary operator, return return operator interp(x.left)
    elif x.node_type ==  If
                    if (interp(x.left)) then interp(x.right.left)
                    else interp(x.right.right)
                    return NULL
    elif x.node_type == While
                    while (interp(x.left)) do interp(x.right)
                    return NULL
    elif x.node_type == Prtc
                    print interp(x.left) as a character, no newline
                    return NULL
    elif x.node_type == Prti
                    print interp(x.left) as an integer, no newline
                    return NULL
    elif x.node_type == Prts
                    print interp(x.left) as a string, respecting newlines ("\n")
                    return NULL
    elif x.node_type == Sequence
                    interp(x.left)
                    interp(x.right)
                    return NULL
    else
        error("unknown node type")

Notes:

Because of the simple nature of our tiny language, Semantic analysis is not needed.

Your interpreter should use C like division semantics, for both division and modulus.  For division of positive operands, only the non-fractional portion of the result should be returned.  In other words, the result should be truncated towards 0.

This means, for instance, that 3 / 2 should result in 1.

For division when one of the operands is negative, the result should be truncated towards 0.

This means, for instance, that 3 / -2 should result in -1.

; Test program

{| class="wikitable"
|-
! prime.t
! lex <prime.t  	| parse | interp
|-
| style="vertical-align:top" |
/*
 Simple prime number generator
 */
count = 1;
n = 1;
limit = 100;
while (n < limit) {
    k=3;
    p=1;
    n=n+2;
    while ((k*k<=n) && (p)) {
        p=n/k*k!=n;
        k=k+2;
    }
    if (p) {
        print(n, " is prime\n");
        count = count + 1;
    }
}
print("Total primes found: ", count, "\n");

| style="vertical-align:top" |

3 is prime
5 is prime
7 is prime
11 is prime
13 is prime
17 is prime
19 is prime
23 is prime
29 is prime
31 is prime
37 is prime
41 is prime
43 is prime
47 is prime
53 is prime
59 is prime
61 is prime
67 is prime
71 is prime
73 is prime
79 is prime
83 is prime
89 is prime
97 is prime
101 is prime
Total primes found: 26

|}

; Additional examples

Your solution should pass all the test cases above and the additional tests found '''Here'''.

The C and Python versions can be considered reference implementations.

;Related Tasks

* Lexical Analyzer task
* Syntax Analyzer task
* Code Generator task
* Virtual Machine Interpreter task

__TOC__

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

#define da_dim(name, type)  type *name = NULL;          \
                            int _qy_ ## name ## _p = 0;  \
                            int _qy_ ## name ## _max = 0
#define da_rewind(name)     _qy_ ## name ## _p = 0
#define da_redim(name)      do {if (_qy_ ## name ## _p >= _qy_ ## name ## _max) \
                                name = realloc(name, (_qy_ ## name ## _max += 32) * sizeof(name[0]));} while (0)
#define da_append(name, x)  do {da_redim(name); name[_qy_ ## name ## _p++] = x;} while (0)
#define da_len(name)        _qy_ ## name ## _p
#define da_add(name)        do {da_redim(name); _qy_ ## name ## _p++;} while (0)

typedef enum {
    nd_Ident, nd_String, nd_Integer, nd_Sequence, nd_If, nd_Prtc, nd_Prts, nd_Prti, nd_While,
    nd_Assign, nd_Negate, nd_Not, nd_Mul, nd_Div, nd_Mod, nd_Add, nd_Sub, nd_Lss, nd_Leq,
    nd_Gtr, nd_Geq, nd_Eql, nd_Neq, nd_And, nd_Or
} NodeType;

typedef struct Tree Tree;
struct Tree {
    NodeType node_type;
    Tree *left;
    Tree *right;
    int value;
};

// dependency: Ordered by NodeType, must remain in same order as NodeType enum

struct {
    char       *enum_text;
    NodeType   node_type;
} atr[] = {
    {"Identifier"  , nd_Ident,  },  {"String"      , nd_String,  },
    {"Integer"     , nd_Integer,},  {"Sequence"    , nd_Sequence,},
    {"If"          , nd_If,     },  {"Prtc"        , nd_Prtc,    },
    {"Prts"        , nd_Prts,   },  {"Prti"        , nd_Prti,    },
    {"While"       , nd_While,  },  {"Assign"      , nd_Assign,  },
    {"Negate"      , nd_Negate, },  {"Not"         , nd_Not,     },
    {"Multiply"    , nd_Mul,    },  {"Divide"      , nd_Div,     },
    {"Mod"         , nd_Mod,    },  {"Add"         , nd_Add,     },
    {"Subtract"    , nd_Sub,    },  {"Less"        , nd_Lss,     },
    {"LessEqual"   , nd_Leq,    },  {"Greater"     , nd_Gtr,     },
    {"GreaterEqual", nd_Geq,    },  {"Equal"       , nd_Eql,     },
    {"NotEqual"    , nd_Neq,    },  {"And"         , nd_And,     },
    {"Or"          , nd_Or,     },
};

FILE *source_fp;
da_dim(string_pool, const char *);
da_dim(global_names, const char *);
da_dim(global_values, int);

void error(const char *fmt, ... ) {
    va_list ap;
    char buf[1000];

    va_start(ap, fmt);
    vsprintf(buf, fmt, ap);
    printf("error: %s\n", buf);
    exit(1);
}

Tree *make_node(NodeType node_type, Tree *left, Tree *right) {
    Tree *t = calloc(sizeof(Tree), 1);
    t->node_type = node_type;
    t->left = left;
    t->right = right;
    return t;
}

Tree *make_leaf(NodeType node_type, int value) {
    Tree *t = calloc(sizeof(Tree), 1);
    t->node_type = node_type;
    t->value = value;
    return t;
}

int interp(Tree *x) {           /* interpret the parse tree */
    if (!x) return 0;
    switch(x->node_type) {
        case nd_Integer:  return x->value;
        case nd_Ident:    return global_values[x->value];
        case nd_String:   return x->value;

        case nd_Assign:   return global_values[x->left->value] = interp(x->right);
        case nd_Add:      return interp(x->left) +  interp(x->right);
        case nd_Sub:      return interp(x->left) -  interp(x->right);
        case nd_Mul:      return interp(x->left) *  interp(x->right);
        case nd_Div:      return interp(x->left) /  interp(x->right);
        case nd_Mod:      return interp(x->left) %  interp(x->right);
        case nd_Lss:      return interp(x->left) <  interp(x->right);
        case nd_Gtr:      return interp(x->left) >  interp(x->right);
        case nd_Leq:      return interp(x->left) <= interp(x->right);
        case nd_Eql:      return interp(x->left) == interp(x->right);
        case nd_Neq:      return interp(x->left) != interp(x->right);
        case nd_And:      return interp(x->left) && interp(x->right);
        case nd_Or:       return interp(x->left) || interp(x->right);
        case nd_Negate:   return -interp(x->left);
        case nd_Not:      return !interp(x->left);

        case nd_If:       if (interp(x->left))
                            interp(x->right->left);
                          else
                            interp(x->right->right);
                          return 0;

        case nd_While:    while (interp(x->left))
                            interp(x->right);
                          return 0;

        case nd_Prtc:     printf("%c", interp(x->left));
                          return 0;
        case nd_Prti:     printf("%d", interp(x->left));
                          return 0;
        case nd_Prts:     printf("%s", string_pool[interp(x->left)]);
                          return 0;

        case nd_Sequence: interp(x->left);
                          interp(x->right);
                          return 0;

        default:          error("interp: unknown tree type %d\n", x->node_type);
    }
    return 0;
}

void init_in(const char fn[]) {
    if (fn[0] == '\0')
        source_fp = stdin;
    else {
        source_fp = fopen(fn, "r");
        if (source_fp == NULL)
            error("Can't open %s\n", fn);
    }
}

NodeType get_enum_value(const char name[]) {
    for (size_t i = 0; i < sizeof(atr) / sizeof(atr[0]); i++) {
        if (strcmp(atr[i].enum_text, name) == 0) {
            return atr[i].node_type;
        }
    }
    error("Unknown token %s\n", name);
    return -1;
}

char *read_line(int *len) {
    static char *text = NULL;
    static int textmax = 0;

    for (*len = 0; ; (*len)++) {
        int ch = fgetc(source_fp);
        if (ch == EOF || ch == '\n') {
            if (*len == 0)
                return NULL;
            break;
        }
        if (*len + 1 >= textmax) {
            textmax = (textmax == 0 ? 128 : textmax * 2);
            text = realloc(text, textmax);
        }
        text[*len] = ch;
    }
    text[*len] = '\0';
    return text;
}

char *rtrim(char *text, int *len) {         // remove trailing spaces
    for (; *len > 0 && isspace(text[*len - 1]); --(*len))
        ;

    text[*len] = '\0';
    return text;
}

int fetch_string_offset(char *st) {
    int len = strlen(st);
    st[len - 1] = '\0';
    ++st;
    char *p, *q;
    p = q = st;

    while ((*p++ = *q++) != '\0') {
        if (q[-1] == '\\') {
            if (q[0] == 'n') {
                p[-1] = '\n';
                ++q;
            } else if (q[0] == '\\') {
                ++q;
            }
        }
    }

    for (int i = 0; i < da_len(string_pool); ++i) {
        if (strcmp(st, string_pool[i]) == 0) {
            return i;
        }
    }
    da_add(string_pool);
    int n = da_len(string_pool) - 1;
    string_pool[n] = strdup(st);
    return da_len(string_pool) - 1;
}

int fetch_var_offset(const char *name) {
    for (int i = 0; i < da_len(global_names); ++i) {
        if (strcmp(name, global_names[i]) == 0)
            return i;
    }
    da_add(global_names);
    int n = da_len(global_names) - 1;
    global_names[n] = strdup(name);
    da_append(global_values, 0);
    return n;
}

Tree *load_ast() {
    int len;
    char *yytext = read_line(&len);
    yytext = rtrim(yytext, &len);

    // get first token
    char *tok = strtok(yytext, " ");

    if (tok[0] == ';') {
        return NULL;
    }
    NodeType node_type = get_enum_value(tok);

    // if there is extra data, get it
    char *p = tok + strlen(tok);
    if (p != &yytext[len]) {
        int n;
        for (++p; isspace(*p); ++p)
            ;
        switch (node_type) {
            case nd_Ident:      n = fetch_var_offset(p);    break;
            case nd_Integer:    n = strtol(p, NULL, 0);     break;
            case nd_String:     n = fetch_string_offset(p); break;
            default:            error("Unknown node type: %s\n", p);
        }
        return make_leaf(node_type, n);
    }

    Tree *left  = load_ast();
    Tree *right = load_ast();
    return make_node(node_type, left, right);
}

int main(int argc, char *argv[]) {
    init_in(argc > 1 ? argv[1] : "");

    Tree *x = load_ast();
    interp(x);

    return 0;
}


Compiler/AST interpreter

Solution:
from __future__ import print_function
import sys, shlex, operator

nd_Ident, nd_String, nd_Integer, nd_Sequence, nd_If, nd_Prtc, nd_Prts, nd_Prti, nd_While, \
nd_Assign, nd_Negate, nd_Not, nd_Mul, nd_Div, nd_Mod, nd_Add, nd_Sub, nd_Lss, nd_Leq,     \
nd_Gtr, nd_Geq, nd_Eql, nd_Neq, nd_And, nd_Or = range(25)

all_syms = {
    "Identifier"  : nd_Ident,    "String"      : nd_String,
    "Integer"     : nd_Integer,  "Sequence"    : nd_Sequence,
    "If"          : nd_If,       "Prtc"        : nd_Prtc,
    "Prts"        : nd_Prts,     "Prti"        : nd_Prti,
    "While"       : nd_While,    "Assign"      : nd_Assign,
    "Negate"      : nd_Negate,   "Not"         : nd_Not,
    "Multiply"    : nd_Mul,      "Divide"      : nd_Div,
    "Mod"         : nd_Mod,      "Add"         : nd_Add,
    "Subtract"    : nd_Sub,      "Less"        : nd_Lss,
    "LessEqual"   : nd_Leq,      "Greater"     : nd_Gtr,
    "GreaterEqual": nd_Geq,      "Equal"       : nd_Eql,
    "NotEqual"    : nd_Neq,      "And"         : nd_And,
    "Or"          : nd_Or}

input_file  = None
globals     = {}

#*** show error and exit
def error(msg):
    print("%s" % (msg))
    exit(1)

class Node:
    def __init__(self, node_type, left = None, right = None, value = None):
        self.node_type  = node_type
        self.left  = left
        self.right = right
        self.value = value

#***
def make_node(oper, left, right = None):
    return Node(oper, left, right)

#***
def make_leaf(oper, n):
    return Node(oper, value = n)

#***
def fetch_var(var_name):
    n = globals.get(var_name, None)
    if n == None:
        globals[var_name] = n = 0
    return n

#***
def interp(x):
    global globals

    if x == None: return None
    elif x.node_type == nd_Integer: return int(x.value)
    elif x.node_type == nd_Ident:   return fetch_var(x.value)
    elif x.node_type == nd_String:  return x.value

    elif x.node_type == nd_Assign:
                    globals[x.left.value] = interp(x.right)
                    return None
    elif x.node_type == nd_Add:     return interp(x.left) +   interp(x.right)
    elif x.node_type == nd_Sub:     return interp(x.left) -   interp(x.right)
    elif x.node_type == nd_Mul:     return interp(x.left) *   interp(x.right)
    # use C like division semantics
    # another way: abs(x) / abs(y) * cmp(x, 0) * cmp(y, 0)
    elif x.node_type == nd_Div:     return int(float(interp(x.left)) / interp(x.right))
    elif x.node_type == nd_Mod:     return int(float(interp(x.left)) % interp(x.right))
    elif x.node_type == nd_Lss:     return interp(x.left) <   interp(x.right)
    elif x.node_type == nd_Gtr:     return interp(x.left) >   interp(x.right)
    elif x.node_type == nd_Leq:     return interp(x.left) <=  interp(x.right)
    elif x.node_type == nd_Geq:     return interp(x.left) >=  interp(x.right)
    elif x.node_type == nd_Eql:     return interp(x.left) ==  interp(x.right)
    elif x.node_type == nd_Neq:     return interp(x.left) !=  interp(x.right)
    elif x.node_type == nd_And:     return interp(x.left) and interp(x.right)
    elif x.node_type == nd_Or:      return interp(x.left) or  interp(x.right)
    elif x.node_type == nd_Negate:  return -interp(x.left)
    elif x.node_type == nd_Not:     return not interp(x.left)

    elif x.node_type ==  nd_If:
                    if (interp(x.left)):
                        interp(x.right.left)
                    else:
                        interp(x.right.right)
                    return None

    elif x.node_type == nd_While:
                    while (interp(x.left)):
                        interp(x.right)
                    return None

    elif x.node_type == nd_Prtc:
                    print("%c" % (interp(x.left)), end='')
                    return None

    elif x.node_type == nd_Prti:
                    print("%d" % (interp(x.left)), end='')
                    return None

    elif x.node_type == nd_Prts:
                    print(interp(x.left), end='')
                    return None

    elif x.node_type == nd_Sequence:
                    interp(x.left)
                    interp(x.right)
                    return None
    else:
        error("error in code generator - found %d, expecting operator" % (x.node_type))

def str_trans(srce):
    dest = ""
    i = 0
    srce = srce[1:-1]
    while i < len(srce):
        if srce[i] == '\\' and i + 1 < len(srce):
            if srce[i + 1] == 'n':
                dest += '\n'
                i += 2
            elif srce[i + 1] == '\\':
                dest += '\\'
                i += 2
        else:
            dest += srce[i]
            i += 1

    return dest

def load_ast():
    line = input_file.readline()
    line_list = shlex.split(line, False, False)

    text = line_list[0]

    value = None
    if len(line_list) > 1:
        value = line_list[1]
        if value.isdigit():
            value = int(value)

    if text == ";":
        return None
    node_type = all_syms[text]
    if value != None:
        if node_type == nd_String:
            value = str_trans(value)

        return make_leaf(node_type, value)
    left = load_ast()
    right = load_ast()
    return make_node(node_type, left, right)

#*** main driver
input_file = sys.stdin
if len(sys.argv) > 1:
    try:
        input_file = open(sys.argv[1], "r", 4096)
    except IOError as e:
        error(0, 0, "Can't open %s" % sys.argv[1])

n = load_ast()
interp(n)