Greatest subsequential sum

Solution:
'''Greatest subsequential sum'''

from functools import (reduce)

# maxSubseq :: [Int] -> [Int] -> (Int, [Int])
def maxSubseq(xs):
    '''Subsequence of xs with the maximum sum'''
    def go(ab, x):
        (m1, m2) = ab[0]
        hi = max((0, []), (m1 + x, m2 + [x]))
        return (hi, max(ab[1], hi))
    return reduce(go, xs, ((0, []), (0, [])))[1]

# TEST -----------------------------------------------------------
print(
    maxSubseq(
        [-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1]
    )
)


Greedy algorithm for Egyptian fractions

An   Egyptian fraction   is the sum of distinct unit fractions such as:

::::   \tfrac{1}{2} + \tfrac{1}{3} + \tfrac{1}{16} \,(= \tfrac{43}{48})

Each fraction in the expression has a numerator equal to   '''1'''   (unity)   and a denominator that is a positive integer,   and all the denominators are distinct   (i.e., no repetitions).

Fibonacci's   Greedy algorithm for Egyptian fractions   expands the fraction     \tfrac{x}{y}     to be represented by repeatedly performing the replacement

::::   \frac{x}{y} = \frac{1}{\lceil y/x\rceil} + \frac{(-y)\!\!\!\!\mod x}{y\lceil y/x\rceil}

(simplifying the 2nd term in this replacement as necessary, and where     \lceil x \rceil     is the   ''ceiling''   function).

For this task,   Proper and improper fractions   must be able to be expressed.

Proper  fractions   are of the form    \tfrac{a}{b}    where    a    and    b    are positive integers, such that    a < b,     and

improper fractions are of the form    \tfrac{a}{b}    where    a    and    b    are positive integers, such that    ''a'' ≥ ''b''.

(See the REXX programming example to view one method of expressing the whole number part of an improper fraction.)

For improper fractions, the integer part of any improper fraction should be first isolated and shown preceding the Egyptian unit fractions, and be surrounded by square brackets [''n''].

;Task requirements:
*   show the Egyptian fractions for:  \tfrac{43}{48}  and  \tfrac{5}{121}  and  \tfrac{2014}{59}
*   for all proper fractions,    \tfrac{a}{b}    where    a    and    b    are positive one-or two-digit (decimal) integers, find and show an Egyptian fraction that has:
::*   the largest number of terms,
::*   the largest denominator.
*   for all one-, two-, and three-digit integers,   find and show (as above).     {extra credit}

;Also see:
*   Wolfram MathWorld™ entry: [http://mathworld.wolfram.com/EgyptianFraction.html Egyptian fraction]

Solution:
#include
#include
#include

typedef int64_t integer;

struct Pair {
    integer md;
    int tc;
};

integer mod(integer x, integer y) {
    return ((x % y) + y) % y;
}

integer gcd(integer a, integer b) {
    if (0 == a) return b;
    if (0 == b) return a;
    if (a == b) return a;
    if (a > b) return gcd(a - b, b);
    return gcd(a, b - a);
}

void write0(bool show, char *str) {
    if (show) {
        printf(str);
    }
}

void write1(bool show, char *format, integer a) {
    if (show) {
        printf(format, a);
    }
}

void write2(bool show, char *format, integer a, integer b) {
    if (show) {
        printf(format, a, b);
    }
}

struct Pair egyptian(integer x, integer y, bool show) {
    struct Pair ret;
    integer acc = 0;
    bool first = true;

    ret.tc = 0;
    ret.md = 0;

    write2(show, "Egyptian fraction for %lld/%lld: ", x, y);
    while (x > 0) {
        integer z = (y + x - 1) / x;
        if (z == 1) {
            acc++;
        } else {
            if (acc > 0) {
                write1(show, "%lld + ", acc);
                first = false;
                acc = 0;
                ret.tc++;
            } else if (first) {
                first = false;
            } else {
                write0(show, " + ");
            }
            if (z > ret.md) {
                ret.md = z;
            }
            write1(show, "1/%lld", z);
            ret.tc++;
        }
        x = mod(-y, x);
        y = y * z;
    }
    if (acc > 0) {
        write1(show, "%lld", acc);
        ret.tc++;
    }
    write0(show, "\n");

    return ret;
}

int main() {
    struct Pair p;
    integer nm = 0, dm = 0, dmn = 0, dmd = 0, den = 0;;
    int tm, i, j;

    egyptian(43, 48, true);
    egyptian(5, 121, true); // final term cannot be represented correctly
    egyptian(2014, 59, true);

    tm = 0;
    for (i = 1; i < 100; i++) {
        for (j = 1; j < 100; j++) {
            p = egyptian(i, j, false);
            if (p.tc > tm) {
                tm = p.tc;
                nm = i;
                dm = j;
            }
            if (p.md > den) {
                den = p.md;
                dmn = i;
                dmd = j;
            }
        }
    }
    printf("Term max is %lld/%lld with %d terms.\n", nm, dm, tm); // term max is correct
    printf("Denominator max is %lld/%lld\n", dmn, dmd);           // denominator max is not correct
    egyptian(dmn, dmd, true);                                     // enough digits cannot be represented without bigint

    return 0;
}


Greedy algorithm for Egyptian fractions

Solution:
from fractions import Fraction
from math import ceil

class Fr(Fraction):
    def __repr__(self):
        return '%s/%s' % (self.numerator, self.denominator)

def ef(fr):
    ans = []
    if fr >= 1:
        if fr.denominator == 1:
            return [[int(fr)], Fr(0, 1)]
        intfr = int(fr)
        ans, fr = [[intfr]], fr - intfr
    x, y = fr.numerator, fr.denominator
    while x != 1:
        ans.append(Fr(1, ceil(1/fr)))
        fr = Fr(-y % x, y* ceil(1/fr))
        x, y = fr.numerator, fr.denominator
    ans.append(fr)
    return ans

if __name__ == '__main__':
    for fr in [Fr(43, 48), Fr(5, 121), Fr(2014, 59)]:
        print('%r ─► %s' % (fr, ' '.join(str(x) for x in ef(fr))))
    lenmax = denommax = (0, None)
    for fr in set(Fr(a, b) for a in range(1,100) for b in range(1, 100)):
        e = ef(fr)
        #assert sum((f[0] if type(f) is list else f) for f in e) == fr, 'Whoops!'
        elen, edenom = len(e), e[-1].denominator
        if elen > lenmax[0]:
            lenmax = (elen, fr, e)
        if edenom > denommax[0]:
            denommax = (edenom, fr, e)
    print('Term max is %r with %i terms' % (lenmax[1], lenmax[0]))
    dstr = str(denommax[0])
    print('Denominator max is %r with %i digits %s...%s' %
          (denommax[1], len(dstr), dstr[:5], dstr[-5:]))


Greyscale bars/Display

The task is to display a series of vertical greyscale bars (contrast bars) with a sufficient number of bars to span the entire width of the display.

For the top quarter of the display, the left hand bar should be black, and we then incrementally step through six shades of grey until we have a white bar on the right hand side of the display. (This gives a total of 8 bars)

For the second quarter down, we start with white and step down through 14 shades of gray, getting darker until we have black on the right hand side of the display. (This gives a total of 16 bars).

Halfway down the display, we start with black, and produce 32 bars, ending in white, and for the last quarter, we start with white and step through 62 shades of grey, before finally arriving at black in the bottom right hand corner, producing a total of 64 bars for the bottom quarter.

Solution:
#include
/* do some greyscale plotting */
void gsplot (cairo_t *cr,int x,int y,double s) {
    cairo_set_source_rgb (cr,s,s,s);
    cairo_move_to (cr,x+0.5,y);
    cairo_rel_line_to (cr,0,1);
    cairo_stroke (cr);
}
/* make a shaded widget */
gboolean expose_event (GtkWidget *widget,GdkEventExpose *event,gpointer data) {
    int r,c,x=0;
    cairo_t *cr;
    cr = gdk_cairo_create (widget->window);
    cairo_scale (cr,5,50);
    cairo_set_line_width (cr,1);
    for (r=0;r<4;r++) {
        c = (r&1)*64-(r%2);
        do gsplot (cr,x++%64,r,c/(1<<(3-r))/(8*(1<


Greyscale bars/Display

Solution:
#!/usr/bin/env python
#four gray scaled stripes 8:16:32:64 in Python 2.7.1

from livewires import *

horiz=640; vert=480; pruh=vert/4; dpp=255.0
begin_graphics(width=horiz,height=vert,title="Gray stripes",background=Colour.black)

def ty_pruhy(each):
	hiy=each[0]*pruh; loy=hiy-pruh
	krok=horiz/each[1]; piecol=255.0/(each[1]-1)
	for x in xrange(0,each[1]):
		barva=Colour(piecol*x/dpp,piecol*x/dpp,piecol*x/dpp ); set_colour(barva)
		if each[2]:
			box(x*krok,hiy,x*krok+krok,loy,filled=1)
		else:
			box(horiz-x*krok,hiy,horiz-((x+1)*krok),loy,filled=1)

# main
source=[[4,8,True],[3,16,False],[2,32,True],[1,64,False]]
for each in source:
	ty_pruhy(each)

while keys_pressed() != [' ']: # press spacebar to close window
	pass


Hailstone sequence

The Hailstone sequence of numbers can be generated from a starting positive integer,   n   by:
*   If   n   is     '''1'''     then the sequence ends.
*   If   n   is   '''even''' then the next   n   of the sequence    = n/2
*   If   n   is   '''odd'''    then the next   n   of the sequence    = (3 * n) + 1

The (unproven) Collatz conjecture is that the hailstone sequence for any starting number always terminates.

This sequence was named by Lothar Collatz in 1937   (or possibly in 1939),   and is also known as (the):
:::*   hailstone sequence,   hailstone numbers
:::*   3x + 2 mapping,   3n + 1 problem
:::*   Collatz sequence
:::*   Hasse's algorithm
:::*   Kakutani's problem
:::*   Syracuse algorithm,   Syracuse problem
:::*   Thwaites conjecture
:::*   Ulam's problem

The hailstone sequence is also known as   ''hailstone numbers''   (because the values are usually subject to multiple descents and ascents like hailstones in a cloud).

;Task:
# Create a routine to generate the hailstone sequence for a number.
# Use the routine to show that the hailstone sequence for the number 27 has 112 elements starting with 27, 82, 41, 124 and ending with 8, 4, 2, 1
# Show the number less than 100,000 which has the longest hailstone sequence together with that sequence's length.    (But don't show the actual sequence!)

;See also:
*   [http://xkcd.com/710 xkcd] (humourous).
*   [https://terrytao.files.wordpress.com/2020/02/collatz.pdf The Notorious Collatz conjecture] Terence Tao, UCLA (Presentation, pdf).
*   [https://www.youtube.com/watch?v=094y1Z2wpJg The Simplest Math Problem No One Can Solve] Veritasium (video, sponsored).

Solution:
#include
#include

int hailstone(int n, int *arry)
{
    int hs = 1;

    while (n!=1) {
        hs++;
        if (arry) *arry++ = n;
        n = (n&1) ? (3*n+1) : (n/2);
    }
    if (arry) *arry++ = n;
    return hs;
}

int main()
{
    int j, hmax = 0;
    int jatmax, n;
    int *arry;

    for (j=1; j<100000; j++) {
       n = hailstone(j, NULL);
       if (hmax < n) {
           hmax = n;
           jatmax = j;
       }
    }
    n = hailstone(27, NULL);
    arry = malloc(n*sizeof(int));
    n = hailstone(27, arry);

    printf("[ %d, %d, %d, %d, ...., %d, %d, %d, %d] len=%d\n",
        arry[0],arry[1],arry[2],arry[3],
        arry[n-4], arry[n-3], arry[n-2], arry[n-1], n);
    printf("Max %d at j= %d\n", hmax, jatmax);
    free(arry);

    return 0;
}


Hailstone sequence

Solution:
function hailstone (n) {
    var seq = [n];
    while (n > 1) {
        n = n % 2 ? 3 * n + 1 : n / 2;
        seq.push(n);
    }
    return seq;
}

// task 2: verify the sequence for n = 27
var h = hailstone(27), hLen = h.length;
print("sequence 27 is (" + h.slice(0, 4).join(", ") + " ... "
    + h.slice(hLen - 4, hLen).join(", ") + "). length: " + hLen);

// task 3: find the longest sequence for n < 100000
for (var n, max = 0, i = 100000; --i;) {
    var seq = hailstone(i), sLen = seq.length;
    if (sLen > max) {
        n = i;
        max = sLen;
    }
}
print("longest sequence: " + max + " numbers for starting point " + n);


Hailstone sequence

Solution:
def hailstone(n):
    seq = [n]
    while n > 1:
        n = 3 * n + 1 if n & 1 else n // 2
        seq.append(n)
    return seq

if __name__ == '__main__':
    h = hailstone(27)
    assert (len(h) == 112
            and h[:4] == [27, 82, 41, 124]
            and h[-4:] == [8, 4, 2, 1])
    max_length, n = max((len(hailstone(i)), i) for i in range(1, 100_000))
    print(f"Maximum length {max_length} was found for hailstone({n}) "
          f"for numbers <100,000")


Harmonic series

In mathematics, the '''n-th''' harmonic number is the sum of the reciprocals of the first '''n''' natural numbers:

'''H''n'' = 1 + 1/2 + 1/3 + ... + 1/n'''

The series of harmonic numbers thus obtained is often loosely referred to as the harmonic series.

Harmonic numbers are closely related to the Euler–Mascheroni constant.

The harmonic series is divergent, albeit quite slowly, and grows toward infinity.

;Task
* Write a function (routine, procedure, whatever it may be called in your language) to generate harmonic numbers.
* Use that procedure to show the values of the first 20 harmonic numbers.
* Find and show the position in the series of the first value greater than the integers 1 through 5

;Stretch
* Find and show the position in the series of the first value greater than the integers 6 through 10

;Related
* [[Egyptian fractions]]

Solution:
from  fractions import Fraction

def harmonic_series():
    n, h = Fraction(1), Fraction(1)
    while True:
        yield h
        h += 1 / (n + 1)
        n += 1

if __name__ == '__main__':
    from itertools import islice
    for n, d in (h.as_integer_ratio() for h in islice(harmonic_series(), 20)):
        print(n, '/', d)


Harshad or Niven series

The [http://mathworld.wolfram.com/HarshadNumber.html Harshad] or Niven numbers are positive integers ≥ 1 that are divisible by the sum of their digits.

For example,   '''42'''   is a Harshad number as   '''42'''   is divisible by   ('''4''' + '''2''')   without remainder.

Assume that the series is defined as the numbers in increasing order.

;Task:
The task is to create a function/method/procedure to generate successive members of the Harshad sequence.

Use it to:
::*   list the first '''20''' members of the sequence,   and
::*   list the first Harshad number greater than '''1000'''.

Show your output here.

;Related task
:*   [https://rosettacode.org/wiki/Increasing_gaps_between_consecutive_Niven_numbers Increasing gaps between consecutive Niven numbers]

;See also
*    OEIS: A005349

Solution:
#include

static int digsum(int n)
{
    int sum = 0;
    do { sum += n % 10; } while (n /= 10);
    return sum;
}

int main(void)
{
    int n, done, found;

    for (n = 1, done = found = 0; !done; ++n) {
        if (n % digsum(n) == 0) {
            if (found++ < 20) printf("%d ", n);
            if (n > 1000) done = printf("\n%d\n", n);
        }
    }

    return 0;
}


Harshad or Niven series

Solution:
function isHarshad(n) {
    var s = 0;
    var n_str = new String(n);
    for (var i = 0; i < n_str.length; ++i) {
        s += parseInt(n_str.charAt(i));
    }
    return n % s === 0;
}

var count = 0;
var harshads = [];

for (var n = 1; count < 20; ++n) {
    if (isHarshad(n)) {
        count++;
        harshads.push(n);
    }
}

console.log(harshads.join(" "));

var h = 1000;
while (!isHarshad(++h));
console.log(h);


Harshad or Niven series

Solution:
>>> import itertools
>>> def harshad():
	for n in itertools.count(1):
		if n % sum(int(ch) for ch in str(n)) == 0:
			yield n

>>> list(itertools.islice(harshad(), 0, 20))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 18, 20, 21, 24, 27, 30, 36, 40, 42]
>>> for n in harshad():
	if n > 1000:
		print(n)
		break

1002
>>>


Harshad or Niven series

Solution:
'''Harshad or Niven series'''

from itertools import count, dropwhile, islice

# harshads :: () -> [Int]
def harshads():
    '''Harshad series'''
    return (
        x for x in count(1)
        if 0 == x % digitSum(x)
    )

# digitSum :: Int -> Int
def digitSum(n):
    '''Sum of the decimal digits of n.'''
    def go(x):
        return None if 0 == x else divmod(x, 10)
    return sum(unfoldl(go)(n))

# ------------------------- TEST -------------------------
# main :: IO ()
def main():
    '''First 20, and first above 1000.'''

    def firstTwenty(xs):
        return take(20)(xs)

    def firstAbove1000(xs):
        return take(1)(
            dropwhile(lambda x: 1000 >= x, xs)
        )

    print(
        fTable(__doc__ + ':\n')(
            lambda x: x.__name__
        )(showList)(lambda f: f(harshads()))([
            firstTwenty,
            firstAbove1000
        ])
    )

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

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

# unfoldl :: (b -> Maybe (b, a)) -> b -> [a]
def unfoldl(f):
    '''A lazy (generator) list unfolded from a seed value
       by repeated application of f until no residue remains.
       Dual to fold/reduce.
       f returns either None or just (residue, value).
       For a strict output list, wrap the result with list()
    '''
    def go(v):
        residueValue = f(v)
        while residueValue:
            yield residueValue[1]
            residueValue = f(residueValue[0])
    return go

# ----------------------- DISPLAY ------------------------

# fTable :: String -> (a -> String) ->
# (b -> String) -> (a -> b) -> [a] -> String
def fTable(s):
    '''Heading -> x display function ->
       fx display function -> f -> xs -> tabular string.
    '''
    def gox(xShow):
        def gofx(fxShow):
            def gof(f):
                def goxs(xs):
                    ys = [xShow(x) for x in xs]
                    w = max(map(len, ys))

                    def arrowed(x, y):
                        return y.rjust(w, ' ') + ' -> ' + (
                            fxShow(f(x))
                        )
                    return s + '\n' + '\n'.join(
                        map(arrowed, xs, ys)
                    )
                return goxs
            return gof
        return gofx
    return gox

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

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


Hash join

An hash join algorithm.

Implement the "hash join" algorithm, and demonstrate that it passes the test-case listed below.

You should represent the tables as data structures that feel natural in your programming language.

The "hash join" algorithm consists of two steps:

# '''Hash phase:''' Create a multimap from one of the two tables, mapping from each join column value to all the rows that contain it.
#* The multimap must support hash-based lookup which scales better than a simple linear search, because that's the whole point of this algorithm.
#* Ideally we should create the multimap for the ''smaller'' table, thus minimizing its creation time and memory size.
# '''Join phase:''' Scan the other table, and find matching rows by looking in the multimap created before.

In pseudo-code, the algorithm could be expressed as follows:

 '''let''' ''A'' = the first input table (or ideally, the larger one)
 '''let''' ''B'' = the second input table (or ideally, the smaller one)
 '''let''' ''jA'' = the join column ID of table ''A''
 '''let''' ''jB'' = the join column ID of table ''B''
 '''let''' ''MB'' = a multimap for mapping from single values to multiple rows of table ''B'' (starts out empty)
 '''let''' ''C'' = the output table (starts out empty)

 '''for each''' row ''b'' '''in''' table ''B''''':'''
    '''place''' ''b'' '''in''' multimap ''MB'' under key ''b''(''jB'')

 '''for each''' row ''a'' '''in''' table ''A''''':'''
    '''for each''' row ''b'' '''in''' multimap ''MB'' under key ''a''(''jA'')''':'''
       '''let''' ''c'' = the concatenation of row ''a'' and row ''b''
       '''place''' row ''c'' in table ''C''

{| class="wikitable"
|-
! Input
! Output
|-
|

{| style="border:none; border-collapse:collapse;"
|-
| style="border:none" | ''A'' =
| style="border:none" |

{| class="wikitable"
|-
! Age !! Name
|-
| 27 || Jonah
|-
| 18 || Alan
|-
| 28 || Glory
|-
| 18 || Popeye
|-
| 28 || Alan
|}

| style="border:none; padding-left:1.5em;" rowspan="2" |
| style="border:none" | ''B'' =
| style="border:none" |

{| class="wikitable"
|-
! Character !! Nemesis
|-
| Jonah || Whales
|-
| Jonah || Spiders
|-
| Alan || Ghosts
|-
| Alan || Zombies
|-
| Glory || Buffy
|}

|-
| style="border:none" | ''jA'' =
| style="border:none" | Name (i.e. column 1)

| style="border:none" | ''jB'' =
| style="border:none" | Character (i.e. column 0)
|}

|

{| class="wikitable" style="margin-left:1em"
|-
! A.Age !! A.Name !! B.Character !! B.Nemesis
|-
| 27 || Jonah || Jonah || Whales
|-
| 27 || Jonah || Jonah || Spiders
|-
| 18 || Alan || Alan || Ghosts
|-
| 18 || Alan || Alan || Zombies
|-
| 28 || Glory || Glory || Buffy
|-
| 28 || Alan || Alan || Ghosts
|-
| 28 || Alan || Alan || Zombies
|}

|}

The order of the rows in the output table is not significant.
If you're using numerically indexed arrays to represent table rows (rather than referring to columns by name), you could represent the output rows in the form [[27, "Jonah"], ["Jonah", "Whales"]].

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

    // hashJoin :: [Dict] -> [Dict] -> String -> [Dict]
    let hashJoin = (tblA, tblB, strJoin) => {

        let [jA, jB] = strJoin.split('='),
            M = tblB.reduce((a, x) => {
                let id = x[jB];
                return (
                    a[id] ? a[id].push(x) : a[id] = [x],
                    a
                );
            }, {});

        return tblA.reduce((a, x) => {
            let match = M[x[jA]];
            return match ? (
                a.concat(match.map(row => dictConcat(x, row)))
            ) : a;
        }, []);
    },

    // dictConcat :: Dict -> Dict -> Dict
    dictConcat = (dctA, dctB) => {
        let ok = Object.keys;
        return ok(dctB).reduce(
            (a, k) => (a['B_' + k] = dctB[k]) && a,
            ok(dctA).reduce(
                (a, k) => (a['A_' + k] = dctA[k]) && a, {}
            )
        );
    };

    // TEST
    let lstA = [
        { age: 27, name: 'Jonah' },
        { age: 18, name: 'Alan' },
        { age: 28, name: 'Glory' },
        { age: 18, name: 'Popeye' },
        { age: 28, name: 'Alan' }
    ],
    lstB = [
        { character: 'Jonah', nemesis: 'Whales' },
        { character: 'Jonah', nemesis: 'Spiders' },
        { character: 'Alan', nemesis: 'Ghosts' },
        { character:'Alan', nemesis: 'Zombies' },
        { character: 'Glory', nemesis: 'Buffy' },
        { character: 'Bob', nemesis: 'foo' }
    ];

    return hashJoin(lstA, lstB, 'name=character');

})();


Hash join

Solution:
from collections import defaultdict

def hashJoin(table1, index1, table2, index2):
    h = defaultdict(list)
    # hash phase
    for s in table1:
        h[s[index1]].append(s)
    # join phase
    return [(s, r) for r in table2 for s in h[r[index2]]]

table1 = [(27, "Jonah"),
          (18, "Alan"),
          (28, "Glory"),
          (18, "Popeye"),
          (28, "Alan")]
table2 = [("Jonah", "Whales"),
          ("Jonah", "Spiders"),
          ("Alan", "Ghosts"),
          ("Alan", "Zombies"),
          ("Glory", "Buffy")]

for row in hashJoin(table1, 1, table2, 0):
    print(row)


Haversine formula

The '''haversine formula''' is an equation important in navigation, giving great-circle distances between two points on a sphere from their longitudes and latitudes.

It is a special case of a more general formula  in spherical trigonometry, the '''law of haversines''', relating the sides and angles of spherical "triangles".

;Task:
Implement a great-circle distance function, or use a library function,
to show the great-circle distance between:
* Nashville International Airport (BNA)   in Nashville, TN, USA,   which is:
    '''N''' 36°7.2',   '''W''' 86°40.2'     (36.12,   -86.67)           -and-
* Los Angeles International Airport (LAX)  in Los Angeles, CA, USA,   which is:
    '''N''' 33°56.4',  '''W''' 118°24.0'    (33.94,  -118.40)

User Kaimbridge clarified on the Talk page:

 -- 6371.0 km is the authalic radius based on/extracted from surface area;
 -- 6372.8 km is an approximation of the radius of the average circumference
    (i.e., the average great-elliptic or great-circle radius), where the
     boundaries are the meridian (6367.45 km) and the equator (6378.14 km).

Using either of these values results, of course, in differing distances:

 6371.0 km -> 2886.44444283798329974715782394574671655 km;
 6372.8 km -> 2887.25995060711033944886005029688505340 km;
 (results extended for accuracy check:  Given that the radii are only
  approximations anyways, .01' ≈ 1.0621333 km and .001" ≈ .00177 km,
  practical precision required is certainly no greater than about
  .0000001——i.e., .1 mm!)

As distances are segments of great circles/circumferences, it is
recommended that the latter value (r = 6372.8 km) be used (which
most of the given solutions have already adopted, anyways).

Most of the examples below adopted Kaimbridge's recommended value of
6372.8 km for the earth radius.  However, the derivation of this
[http://math.wikia.com/wiki/Ellipsoidal_quadratic_mean_radius ellipsoidal quadratic mean radius]
is wrong (the averaging over azimuth is biased).  When applying these
examples in real applications, it is better to use the
[https://en.wikipedia.org/wiki/Earth_radius#Mean_radius mean earth radius],
6371 km.  This value is recommended by the International Union of
Geodesy and Geophysics and it minimizes the RMS relative error between the
great circle and geodesic distance.

Solution:
#include
#include
#include

#define R 6371
#define TO_RAD (3.1415926536 / 180)
double dist(double th1, double ph1, double th2, double ph2)
{
	double dx, dy, dz;
	ph1 -= ph2;
	ph1 *= TO_RAD, th1 *= TO_RAD, th2 *= TO_RAD;

	dz = sin(th1) - sin(th2);
	dx = cos(ph1) * cos(th1) - cos(th2);
	dy = sin(ph1) * cos(th1);
	return asin(sqrt(dx * dx + dy * dy + dz * dz) / 2) * 2 * R;
}

int main()
{
	double d = dist(36.12, -86.67, 33.94, -118.4);
	/* Americans don't know kilometers */
	printf("dist: %.1f km (%.1f mi.)\n", d, d / 1.609344);

	return 0;
}


Haversine formula

Solution:
function haversine() {
       var radians = Array.prototype.map.call(arguments, function(deg) { return deg/180.0 * Math.PI; });
       var lat1 = radians[0], lon1 = radians[1], lat2 = radians[2], lon2 = radians[3];
       var R = 6372.8; // km
       var dLat = lat2 - lat1;
       var dLon = lon2 - lon1;
       var a = Math.sin(dLat / 2) * Math.sin(dLat /2) + Math.sin(dLon / 2) * Math.sin(dLon /2) * Math.cos(lat1) * Math.cos(lat2);
       var c = 2 * Math.asin(Math.sqrt(a));
       return R * c;
}
console.log(haversine(36.12, -86.67, 33.94, -118.40));


Haversine formula

Solution:
from math import radians, sin, cos, sqrt, asin

def haversine(lat1, lon1, lat2, lon2):
    R = 6372.8  # Earth radius in kilometers

    dLat = radians(lat2 - lat1)
    dLon = radians(lon2 - lon1)
    lat1 = radians(lat1)
    lat2 = radians(lat2)

    a = sin(dLat / 2)**2 + cos(lat1) * cos(lat2) * sin(dLon / 2)**2
    c = 2 * asin(sqrt(a))

    return R * c

>>> haversine(36.12, -86.67, 33.94, -118.40)
2887.2599506071106
>>>


Hello world/Line printer

[[Category:Hardware]]
[[Category:Printer]]

;Task:
Cause a line printer attached to the computer to print a line containing the message:    Hello World!

;Note:
A line printer is not the same as standard output.

A   line printer   was an older-style printer which prints one line at a time to a continuous ream of paper.

With some systems, a line printer can be any device attached to an appropriate port (such as a parallel port).

Solution:
#include

int main()
{
   FILE *lp;
   lp = fopen("/dev/lp0","w");
   fprintf(lp,"Hello world!\n");
   fclose(lp);
   return 0;
}


Hello world/Line printer

Solution:
// This example runs on Node.js
var fs = require('fs');
// Assuming lp is at /dev/lp0
var lp = fs.openSync('/dev/lp0', 'w');
fs.writeSync(lp, 'Hello, world!\n');
fs.close(lp);


Hello world/Line printer

Solution:
document.write("Hello World!");
print(); //Opens a dialog.


Hello world/Line printer

Solution:
lp = open("/dev/lp0","w")
lp.write("Hello World!\n")
lp.close()


Hello world/Newbie

;Task:
Guide a new user of a language through the steps necessary
to install the programming language and selection of a text editor if needed,
to run the languages' example in the [[Hello world/Text]] task.
* Assume the language-newbie is a programmer in another language.
* Assume the language-newbie is competent in installing software for the platform.
* Assume the language-newbie can use one simple text editor for the OS/platform, (but that may not necessarily be a particular one if the installation needs a particular editor).
* Refer to, (and link to), already existing documentation as much as possible (but provide a summary here).
* Remember to state where to view the output.
* If particular IDE's or editors are required that are not standard, then point to/explain their installation too.

;Note:
* If it is more natural for a language to give output via a GUI or to a file etc, then use that method of output rather than as text to a terminal/command-line, but remember to give instructions on how to view the output generated.
* You may use sub-headings if giving instructions for multiple platforms.

Solution:
===Using gcc===

====Debian Based Systems====
Install gcc
 $ sudo apt-get install gcc

====Red Hat Based Systems====
Install gcc
 $ su
 # yum install gcc

====All Distributions====
After you have installed gcc using instructions above.
Create helloworld.c.
This uses HERE document and bash, the standard shell.
 $ cat > helloworld.c <<HERE
 #include <stdio.h>
 int main( int argc, char *argv[] ) {
      puts( "Hello World!" );
      return 0;
 }
 HERE
Compile it using gcc.
 $ gcc -o helloworld helloworld.c
Run it
 $ ./helloworld


Here document

A   ''here document''    (or "heredoc")   is a way of specifying a text block, preserving the line breaks, indentation and other whitespace within the text.

Depending on the language being used, a   ''here document''   is constructed using a command followed by "<<" (or some other symbol) followed by a token string.

The text block will then start on the next line, and will be followed by the chosen token at the beginning of the following line, which is used to mark the end of the text block.

;Task:
Demonstrate the use of   ''here documents''   within the language.

;Related task:
*   [[Documentation]]

Solution:
const myVar = 123;
const tempLit = `Here is some
multi-line string. And here is
the value of "myVar": ${myVar}
That's all.`;
console.log(tempLit)


Here document

Solution:
print("""\
Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to
""")


Heronian triangles

Hero's formula for the area of a triangle given the length of its three sides    ''a'',   ''b'',   and   ''c''   is given by:

:::: A = \sqrt{s(s-a)(s-b)(s-c)},

where   ''s''   is half the perimeter of the triangle; that is,

:::: s=\frac{a+b+c}{2}.

'''[http://www.had2know.com/academics/heronian-triangles-generator-calculator.html Heronian triangles]'''
are triangles whose sides ''and area'' are all integers.
: An example is the triangle with sides   '''3, 4, 5'''   whose area is   '''6'''   (and whose perimeter is   '''12''').

Note that any triangle whose sides are all an integer multiple of   '''3, 4, 5''';   such as   '''6, 8, 10,'''   will also be a Heronian triangle.

Define a '''Primitive Heronian triangle''' as a Heronian triangle where the greatest common divisor
of all three sides is   '''1'''   (unity).

This will exclude, for example, triangle   '''6, 8, 10.'''

;Task:
# Create a named function/method/procedure/... that implements Hero's formula.
# Use the function to generate all the ''primitive'' Heronian triangles with sides <= 200.
# Show the count of how many triangles are found.
# Order the triangles by first increasing area, then by increasing perimeter, then by increasing maximum side lengths
# Show the first ten ordered triangles in a table of sides, perimeter, and area.
# Show a similar ordered table for those triangles with area = 210

Show all output here.

'''Note''': when generating triangles it may help to restrict a <= b <= c

Solution:
#include
#include
#include

typedef struct{
	int a,b,c;
	int perimeter;
	double area;
}triangle;

typedef struct elem{
	triangle t;
	struct elem* next;
}cell;

typedef cell* list;

void addAndOrderList(list *a,triangle t){
	list iter,temp;
	int flag = 0;

	if(*a==NULL){
		*a = (list)malloc(sizeof(cell));
		(*a)->t = t;
		(*a)->next = NULL;
	}

	else{
		temp = (list)malloc(sizeof(cell));

			iter = *a;
			while(iter->next!=NULL){
				if(((iter->t.areat.area==t.area && iter->t.perimetert.area==t.area && iter->t.perimeter==t.perimeter && iter->t.a<=t.a))
				&&
				(iter->next==NULL||(t.areanext->t.area || t.perimeternext->t.perimeter || t.anext->t.a))){
					temp->t = t;
					temp->next = iter->next;
					iter->next = temp;
					flag = 1;
					break;
				}

				iter = iter->next;
			}

			if(flag!=1){
				temp->t = t;
				temp->next = NULL;
				iter->next = temp;
			}
	}
}

int gcd(int a,int b){
	if(b!=0)
		return gcd(b,a%b);
	return a;
}

void calculateArea(triangle *t){
	(*t).perimeter = (*t).a + (*t).b + (*t).c;
	(*t).area = sqrt(0.5*(*t).perimeter*(0.5*(*t).perimeter - (*t).a)*(0.5*(*t).perimeter - (*t).b)*(0.5*(*t).perimeter - (*t).c));
}

list generateTriangleList(int maxSide,int *count){
	int a,b,c;
	triangle t;
	list herons = NULL;

	*count = 0;

	for(a=1;a<=maxSide;a++){
		for(b=1;b<=a;b++){
			for(c=1;c<=b;c++){
				if(c+b > a && gcd(gcd(a,b),c)==1){
					t = (triangle){a,b,c};
					calculateArea(&t);
					if(t.area/(int)t.area == 1){
						addAndOrderList(&herons,t);
						(*count)++;
					}
				}
			}
		}
	}

	return herons;
}

void printList(list a,int limit,int area){
	list iter = a;
	int count = 1;

	printf("\nDimensions\tPerimeter\tArea");

	while(iter!=NULL && count!=limit+1){
		if(area==-1 ||(area==iter->t.area)){
			printf("\n%d x %d x %d\t%d\t\t%d",iter->t.a,iter->t.b,iter->t.c,iter->t.perimeter,(int)iter->t.area);
			count++;
		}
		iter = iter->next;
	}
}

int main(int argC,char* argV[])
{
	int count;
	list herons = NULL;

	if(argC!=4)
		printf("Usage : %s ",argV[0]);
	else{
		herons = generateTriangleList(atoi(argV[1]),&count);
		printf("Triangles found : %d",count);
		(atoi(argV[3])==-1)?printf("\nPrinting first %s triangles.",argV[2]):printf("\nPrinting triangles with area %s square units.",argV[3]);
		printList(herons,atoi(argV[2]),atoi(argV[3]));
		free(herons);
	}
	return 0;
}


Heronian triangles

Solution:
window.onload = function(){
    var list = [];
    var j = 0;
    for(var c = 1; c <= 200; c++)
        for(var b = 1; b <= c; b++)
            for(var a = 1; a <= b; a++)
	        if(gcd(gcd(a, b), c) == 1 && isHeron(heronArea(a, b, c)))
		    list[j++] = new Array(a, b, c, a + b + c, heronArea(a, b, c));
    sort(list);
    document.write("Primitive Heronian triangles with sides up to 200: " + list.length + "First ten when ordered by increasing area, then perimeter:SidesPerimeterArea");
    for(var i = 0; i < 10; i++)
	document.write("" + list[i][0] + " x " + list[i][1] + " x " + list[i][2] + "" + list[i][3] + "" + list[i][4] + "");
    document.write("Area = 210SidesPerimeterArea");
    for(var i = 0; i < list.length; i++)
	if(list[i][4] == 210)
	    document.write("" + list[i][0] + " x " + list[i][1] + " x " + list[i][2] + "" + list[i][3] + "" + list[i][4] + "");
    function heronArea(a, b, c){
	var s = (a + b + c)/ 2;
	return Math.sqrt(s *(s -a)*(s - b)*(s - c));
    }
    function isHeron(h){
        return h % 1 == 0 && h > 0;
    }
    function gcd(a, b){
	var leftover = 1, dividend = a > b ? a : b, divisor = a > b ? b : a;
	while(leftover != 0){
	    leftover = dividend % divisor;
	    if(leftover > 0){
		dividend = divisor;
		divisor = leftover;
	    }
	}
	return divisor;
    }
    function sort(list){
	var swapped = true;
	var temp = [];
	while(swapped){
	    swapped = false;
	    for(var i = 1; i < list.length; i++){
		if(list[i][4] < list[i - 1][4] || list[i][4] == list[i - 1][4] && list[i][3] < list[i - 1][3]){
		    temp = list[i];
		    list[i] = list[i - 1];
		    list[i - 1] = temp;
		    swapped = true;
		}
	    }
	}
    }
}


Heronian triangles

Solution:
from __future__ import division, print_function
from math import gcd, sqrt

def hero(a, b, c):
    s = (a + b + c) / 2
    a2 = s * (s - a) * (s - b) * (s - c)
    return sqrt(a2) if a2 > 0 else 0

def is_heronian(a, b, c):
    a = hero(a, b, c)
    return a > 0 and a.is_integer()

def gcd3(x, y, z):
    return gcd(gcd(x, y), z)

if __name__ == '__main__':
    MAXSIDE = 200

    N = 1 + MAXSIDE
    h = [(x, y, z)
         for x in range(1, N)
         for y in range(x, N)
         for z in range(y, N) if (x + y > z) and
         1 == gcd3(x, y, z) and
         is_heronian(x, y, z)]

    # By increasing area, perimeter, then sides
    h.sort(key=lambda x: (hero(*x), sum(x), x[::-1]))

    print(
        'Primitive Heronian triangles with sides up to %i:' % MAXSIDE, len(h)
    )
    print('\nFirst ten when ordered by increasing area, then perimeter,',
          'then maximum sides:')
    print('\n'.join('  %14r perim: %3i area: %i'
                    % (sides, sum(sides), hero(*sides)) for sides in h[:10]))
    print('\nAll with area 210 subject to the previous ordering:')
    print('\n'.join('  %14r perim: %3i area: %i'
                    % (sides, sum(sides), hero(*sides)) for sides in h
                    if hero(*sides) == 210))


Hex words

;Definition
For the purposes of this task a '''hex word''' means a word which (in lower case form) consists entirely of the letters '''a, b, c, d, e''' and '''f'''.

;Task
Using [http://wiki.puzzlers.org/pub/wordlists/unixdict.txt unixdict.txt], find all hex words with '''4''' letters or more.

Convert each such word to its decimal equivalent and compute its base 10 digital root.

Display all three in increasing order of digital root and show the total count of such words.

Keeping only words which contain at least '''4''' distinct letters, display the same statistics but in decreasing order of decimal equivalent together with their total count.

Solution:
def digroot(n):
    while n > 9:
        n = sum([int(d) for d in str(n)])
    return n

with open('unixdict.txt') as f:
    lines = [w.strip() for w in f.readlines()]
    words = [w for w in lines if len(w) >= 4 and all(c in 'abcdef' for c in w)]
    results = [[w, int(w, 16)] for w in words]
    for a in results:
        a.append(digroot(a[1]))

    print(f"Hex words in unixdict.txt:\nRoot  Word      Base 10\n", "-"*22)
    for a in sorted(results, key=lambda x:x[2]):
        print(f"{a[2]}     {a[0]:6}{a[1]:10}")

    print("Total count of these words:", len(results))
    print("\nHex words with > 3 distinct letters:\nRoot  Word      Base 10\n", "-"*22)
    results = [a for a in results if len(set(str(a[0]))) > 3]
    for a in sorted(results, key=lambda x:x[2]):
        print(f"{a[2]}     {a[0]:6}{a[1]:10}")

    print("Total count of those words:", len(results))


Hickerson series of almost integers

The following function,   due to D. Hickerson,   is said to generate "Almost integers" by the
[http://mathworld.wolfram.com/AlmostInteger.html "Almost Integer" page of Wolfram MathWorld],   (December 31 2013).   (See formula numbered   '''51'''.)

The function is:           h(n) = {\operatorname{n}!\over2(\ln{2})^{n+1}}

It is said to produce "almost integers" for   '''n'''   between   '''1'''   and   '''17'''.
The purpose of the task is to verify this assertion.

Assume that an "almost integer" has '''either a nine or a zero as its first digit after the decimal point''' of its decimal string representation

;Task:
Calculate all values of the function checking and stating which are "almost integers".

Note: Use extended/arbitrary precision numbers in your calculation if necessary to ensure you have adequate precision of results as for example:
                h(18) = 3385534663256845326.39...

Solution:
#include
#include

void h(int n)
{
	MPFR_DECL_INIT(a, 200);
	MPFR_DECL_INIT(b, 200);

	mpfr_fac_ui(a, n, MPFR_RNDD);		// a = n!

	mpfr_set_ui(b, 2, MPFR_RNDD);		// b = 2
	mpfr_log(b, b, MPFR_RNDD);		// b = log(b)
	mpfr_pow_ui(b, b, n + 1, MPFR_RNDD);	// b = b^(n+1)

	mpfr_div(a, a, b, MPFR_RNDD);		// a = a / b
	mpfr_div_ui(a, a, 2, MPFR_RNDD);	// a = a / 2

	mpfr_frac(b, a, MPFR_RNDD);		// b = a - [a]
	mpfr_printf("%2d: %23.4Rf  %c\n", n, a,
		mpfr_cmp_d(b, .1) * mpfr_cmp_d(b, .9) > 0 ? 'Y' : 'N');
}

int main(void)
{
	int n;
	for (n = 1; n <= 17; n++) h(n);

	return 0;
}


Hickerson series of almost integers

Solution:
from decimal import Decimal
import math

def h(n):
    'Simple, reduced precision calculation'
    return math.factorial(n) / (2 * math.log(2) ** (n + 1))

def h2(n):
    'Extended precision Hickerson function'
    return Decimal(math.factorial(n)) / (2 * Decimal(2).ln() ** (n + 1))

for n in range(18):
    x = h2(n)
    norm = str(x.normalize())
    almostinteger = (' Nearly integer'
                     if 'E' not in norm and ('.0' in norm or '.9' in norm)
                     else ' NOT nearly integer!')
    print('n:%2i h:%s%s' % (n, norm, almostinteger))


History variables

''Storing the history of objects in a program is a common task.
Maintaining the history of an object in a program has traditionally required programmers either to write specific code for handling the historical data, or to use a library which supports history logging.''

''History variables are variables in a programming language which store not only their current value, but also the values they have contained in the past. Some existing languages do provide support for history variables. However these languages typically have many limits and restrictions on use of history variables.
''

[http://www.bod.com/index.php?id=3435&objk_id=148050 "History Variables:
The Semantics, Formal Correctness, and Implementation of History Variables
in an Imperative Programming Language" by Mallon and Takaoka]

Concept also discussed on [http://lambda-the-ultimate.org/node/3111 LtU] and [http://www.patents.com/us-7111283.html Patents.com].

;Task:
Demonstrate History variable support:
* enable history variable support (if needed)
* define a history variable
* assign three values
* non-destructively display the history
* recall the three values.

For extra points, if the language of choice does not support history variables,
demonstrate how this might be implemented.

Solution:
import sys

HIST = {}

def trace(frame, event, arg):
    for name,val in frame.f_locals.items():
        if name not in HIST:
            HIST[name] = []
        else:
            if HIST[name][-1] is val:
                continue
        HIST[name].append(val)
    return trace

def undo(name):
    HIST[name].pop(-1)
    return HIST[name][-1]

def main():
    a = 10
    a = 20

    for i in range(5):
        c = i

    print "c:", c, "-> undo x3 ->",
    c = undo('c')
    c = undo('c')
    c = undo('c')
    print c
    print 'HIST:', HIST

sys.settrace(trace)
main()


Hofstadter-Conway $10,000 sequence

The definition of the sequence is colloquially described as:
*   Starting with the list [1,1],
*   Take the last number in the list so far: 1, I'll call it x.
*   Count forward x places from the beginning of the list to find the first number to add (1)
*   Count backward x places from the end of the list to find the second number to add (1)
*   Add the two indexed numbers from the list and the result becomes the next number in the list (1+1)
*   This would then produce [1,1,2] where 2 is the third element of the sequence.

Note that indexing for the description above starts from alternately the left and right ends of the list and starts from an index of ''one''.

A less wordy description of the sequence is:
    a(1)=a(2)=1
    a(n)=a(a(n-1))+a(n-a(n-1))

The sequence begins:
    1, 1, 2, 2, 3, 4, 4, 4, 5, ...

Interesting features of the sequence are that:
*   a(n)/n   tends to   0.5   as   n   grows towards infinity.
*   a(n)/n   where   n   is a power of   2   is   0.5
*   For   n>4   the maximal value of   a(n)/n   between successive powers of 2 decreases.

a(n) / n   for   n   in   1..256

The sequence is so named because John Conway [http://www.nytimes.com/1988/08/30/science/intellectual-duel-brash-challenge-swift-response.html offered a prize] of $10,000 to the first person who could
find the first position,   p   in the sequence where
    │a(n)/n│ < 0.55  for all  n > p
It was later found that Hofstadter had also done prior work on the sequence.

The 'prize' was won quite quickly by [https://en.wikipedia.org/wiki/Colin_Lingwood_Mallows Dr. Colin L. Mallows] who proved the properties of the sequence and allowed him to find the value of   n   (which is much smaller than the 3,173,375,556 quoted in the NYT article).

;Task:
#   Create a routine to generate members of the Hofstadter-Conway $10,000 sequence.
#   Use it to show the maxima of   a(n)/n   between successive powers of two up to   2**20
#   As a stretch goal:   compute the value of   n   that would have won the prize and confirm it is true for   n   up to 2**20

;Also see:
*   [http://www.jstor.org/stable/2324028 Conways Challenge Sequence], Mallows' own account.
*   [http://mathworld.wolfram.com/Hofstadter-Conway10000-DollarSequence.html Mathworld Article].

Solution:
#include
#include

int a_list[1<<20 + 1];

int doSqnc( int m)
{
    int max_df = 0;
    int p2_max = 2;
    int v, n;
    int k1 = 2;
    int lg2 = 1;
    double amax = 0;
    a_list[0] = -50000;
    a_list[1] = a_list[2] = 1;
    v = a_list[2];

    for (n=3; n <= m;  n++) {
        v = a_list[n] = a_list[v] + a_list[n-v];
        if ( amax < v*1.0/n) amax = v*1.0/n;
        if ( 0 == (k1&n)) {
            printf("Maximum between 2^%d and 2^%d was %f\n", lg2,lg2+1, amax);
            amax = 0;
            lg2++;
        }
        k1 = n;
    }
    return 1;
}


Hofstadter-Conway $10,000 sequence

Solution:
var hofst_10k = function(n) {
	var memo = [1, 1];

	var a = function(n) {
		var result = memo[n-1];
		if (typeof result !== 'number') {
			result = a(a(n-1))+a(n-a(n-1));
			memo[n-1] = result;
		}
		return result;
	}
	return a;
}();

var maxima_between_twos = function(exp) {
	var current_max = 0;
	for(var i = Math.pow(2,exp)+1; i < Math.pow(2,exp+1); i += 1) {
		current_max = Math.max(current_max, hofst_10k(i)/i);
	}
	return current_max;
}

for(var i = 1; i <= 20; i += 1) {
	console.log("Maxima between 2^"+i+"-2^"+(i+1)+" is: "+maxima_between_twos(i)+"\n");
}


Hofstadter-Conway $10,000 sequence

Solution:
from __future__ import division

def maxandmallows(nmaxpower2):
    nmax = 2**nmaxpower2
    mx = (0.5, 2)
    mxpow2 = []
    mallows = None

    # Hofstadter-Conway sequence starts at hc[1],
    # hc[0] is not part of the series.
    hc = [None, 1, 1]

    for n in range(2, nmax + 1):
        ratio = hc[n] / n
        if ratio > mx[0]:
            mx = (ratio, n)
        if ratio >= 0.55:
            mallows = n
        if ratio == 0.5:
            print("In the region %7i < n <= %7i: max a(n)/n = %6.4f at  n = %i" %
		  (n//2, n, mx[0], mx[1]))
            mxpow2.append(mx[0])
            mx = (ratio, n)
        hc.append(hc[hc[n]] + hc[-hc[n]])

    return hc, mallows if mxpow2 and mxpow2[-1] < 0.55 and n > 4 else None

if __name__ == '__main__':
    hc, mallows = maxandmallows(20)
    if mallows:
        print("\nYou too might have won $1000 with the mallows number of %i" % mallows)


Hofstadter Figure-Figure sequences

These two sequences of positive integers are defined as:
:::: \begin{align}
R(1)&=1\ ;\ S(1)=2 \\
R(n)&=R(n-1)+S(n-1), \quad n>1.
\end{align}

The sequence S(n) is further defined as the sequence of positive integers '''''not''''' present in R(n).

Sequence R starts:
    1, 3, 7, 12, 18, ...
Sequence S starts:
    2, 4, 5, 6, 8, ...

;Task:
# Create two functions named '''ffr''' and '''ffs''' that when given '''n''' return '''R(n)''' or '''S(n)''' respectively.(Note that R(1) = 1 and S(1) = 2 to avoid off-by-one errors).
# No maximum value for '''n''' should be assumed.
# Calculate and show that the first ten values of '''R''' are: 1, 3, 7, 12, 18, 26, 35, 45, 56, and 69
# Calculate and show that the first 40 values of '''ffr''' plus the first 960 values of '''ffs''' include all the integers from 1 to 1000 exactly once.

;References:
* Sloane's [http://oeis.org/A005228 A005228] and [http://oeis.org/A030124 A030124].
* [http://mathworld.wolfram.com/HofstadterFigure-FigureSequence.html Wolfram MathWorld]
* Wikipedia: Hofstadter Figure-Figure sequences.

Solution:
#include
#include

// simple extensible array stuff
typedef unsigned long long xint;

typedef struct {
	size_t len, alloc;
	xint *buf;
} xarray;

xarray rs, ss;

void setsize(xarray *a, size_t size)
{
	size_t n = a->alloc;
	if (!n) n = 1;

	while (n < size) n <<= 1;
	if (a->alloc < n) {
		a->buf = realloc(a->buf, sizeof(xint) * n);
		if (!a->buf) abort();
		a->alloc = n;
	}
}

void push(xarray *a, xint v)
{
	while (a->alloc <= a->len)
		setsize(a, a->alloc * 2);

	a->buf[a->len++] = v;
}

// sequence stuff
void RS_append(void);

xint R(int n)
{
	while (n > rs.len) RS_append();
	return rs.buf[n - 1];
}

xint S(int n)
{
	while (n > ss.len) RS_append();
	return ss.buf[n - 1];
}

void RS_append()
{
	int n = rs.len;
	xint r = R(n) + S(n);
	xint s = S(ss.len);

	push(&rs, r);
	while (++s < r) push(&ss, s);
	push(&ss, r + 1); // pesky 3
}

int main(void)
{
	push(&rs, 1);
	push(&ss, 2);

	int i;
	printf("R(1 .. 10):");
	for (i = 1; i <= 10; i++)
		printf(" %llu", R(i));

	char seen[1001] = { 0 };
	for (i = 1; i <=  40; i++) seen[ R(i) ] = 1;
	for (i = 1; i <= 960; i++) seen[ S(i) ] = 1;
	for (i = 1; i <= 1000 && seen[i]; i++);

	if (i <= 1000) {
		fprintf(stderr, "%d not seen\n", i);
		abort();
	}

	puts("\nfirst 1000 ok");
	return 0;
}


Hofstadter Figure-Figure sequences

Solution:
var R = [null, 1];
var S = [null, 2];

var extend_sequences = function (n) {
	var current = Math.max(R[R.length-1],S[S.length-1]);
	var i;
	while (R.length <= n || S.length <= n) {
		i = Math.min(R.length, S.length) - 1;
		current += 1;
		if (current === R[i] + S[i]) {
			R.push(current);
		} else {
			S.push(current);
		}
	}
}

var ffr = function(n) {
	extend_sequences(n);
	return R[n];
};

var ffs = function(n) {
	extend_sequences(n);
	return S[n];
};

for (var i = 1; i <=10; i += 1) {
   console.log('R('+ i +') = ' + ffr(i));
}

var int_array = [];

for (var i = 1; i <= 40; i += 1) {
	int_array.push(ffr(i));
}
for (var i = 1; i <= 960; i += 1) {
	int_array.push(ffs(i));
}

int_array.sort(function(a,b){return a-b;});

for (var i = 1; i <= 1000; i += 1) {
	if (int_array[i-1] !== i) {
		throw "Something's wrong!"
	} else { console.log("1000 integer check ok."); }
}


Hofstadter Figure-Figure sequences

Solution:
def ffr(n):
    if n < 1 or type(n) != int: raise ValueError("n must be an int >= 1")
    try:
        return ffr.r[n]
    except IndexError:
        r, s = ffr.r, ffs.s
        ffr_n_1 = ffr(n-1)
        lastr = r[-1]
        # extend s up to, and one past, last r
        s += list(range(s[-1] + 1, lastr))
        if s[-1] < lastr: s += [lastr + 1]
        # access s[n-1] temporarily extending s if necessary
        len_s = len(s)
        ffs_n_1 = s[n-1] if len_s > n else (n - len_s) + s[-1]
        ans = ffr_n_1 + ffs_n_1
        r.append(ans)
        return ans
ffr.r = [None, 1]

def ffs(n):
    if n < 1 or type(n) != int: raise ValueError("n must be an int >= 1")
    try:
        return ffs.s[n]
    except IndexError:
        r, s = ffr.r, ffs.s
        for i in range(len(r), n+2):
            ffr(i)
            if len(s) > n:
                return s[n]
        raise Exception("Whoops!")
ffs.s = [None, 2]

if __name__ == '__main__':
    first10 = [ffr(i) for i in range(1,11)]
    assert first10 == [1, 3, 7, 12, 18, 26, 35, 45, 56, 69], "ffr() value error(s)"
    print("ffr(n) for n = [1..10] is", first10)
    #
    bin = [None] + [0]*1000
    for i in range(40, 0, -1):
        bin[ffr(i)] += 1
    for i in range(960, 0, -1):
        bin[ffs(i)] += 1
    if all(b == 1 for b in bin[1:1000]):
        print("All Integers 1..1000 found OK")
    else:
        print("All Integers 1..1000 NOT found only once: ERROR")


Hofstadter Q sequence

:: \begin{align}
Q(1)&=Q(2)=1, \\
Q(n)&=Q\big(n-Q(n-1)\big)+Q\big(n-Q(n-2)\big), \quad n>2.
\end{align}

It is defined like the [[Fibonacci sequence]], but whereas the next term in the Fibonacci sequence is the sum of the previous two terms, in the Q sequence the previous two terms tell you how far to go back in the Q sequence to find the two numbers to sum to make the next term of the sequence.

;Task:
* Confirm and display that the first ten terms of the sequence are: 1, 1, 2, 3, 3, 4, 5, 5, 6, and 6
* Confirm and display that the 1000th term is:   502

;Optional extra credit
* Count and display how many times a member of the sequence is less than its preceding term for terms up to and including the 100,000th term.
* Ensure that the extra credit solution   ''safely''   handles being initially asked for an '''n'''th term where   '''n'''   is large.
(This point is to ensure that caching and/or recursion limits, if it is a concern, is correctly handled).

Solution:
#include
#include

#define N 100000
int main()
{
	int i, flip, *q = (int*)malloc(sizeof(int) * N) - 1;

	q[1] = q[2] = 1;

	for (i = 3; i <= N; i++)
		q[i] = q[i - q[i - 1]] + q[i - q[i - 2]];

	for (i = 1; i <= 10; i++)
		printf("%d%c", q[i], i == 10 ? '\n' : ' ');

	printf("%d\n", q[1000]);

	for (flip = 0, i = 1; i < N; i++)
		flip += q[i] > q[i + 1];

	printf("flips: %d\n", flip);
	return 0;
}


Hofstadter Q sequence

Solution:
var hofstadterQ = function() {
   var memo = [1,1,1];
   var Q    = function (n) {
      var result = memo[n];
      if (typeof result !== 'number') {
         result  = Q(n - Q(n-1)) + Q(n - Q(n-2));
         memo[n] = result;
      }
      return result;
   };
   return Q;
}();

for (var i = 1; i <=10; i += 1) {
   console.log('Q('+ i +') = ' + hofstadterQ(i));
}

console.log('Q(1000) = ' + hofstadterQ(1000));


Hofstadter Q sequence

Solution:
from sys import getrecursionlimit

def q1(n):
    if n < 1 or type(n) != int: raise ValueError("n must be an int >= 1")
    try:
        return q.seq[n]
    except IndexError:
        len_q, rlimit = len(q.seq), getrecursionlimit()
        if (n - len_q) > (rlimit // 5):
            for i in range(len_q, n, rlimit // 5):
                q(i)
        ans = q(n - q(n - 1)) + q(n - q(n - 2))
        q.seq.append(ans)
        return ans

if __name__ == '__main__':
    tmp = q1(100000)
    print("Q(i+1) < Q(i) for i [1..100000] is true %i times." %
          sum(k1 < k0 for k0, k1 in zip(q.seq[1:], q.seq[2:])))


Honeycombs

The task is to produce a matrix of 20 hexagon shaped widgets in a honeycomb arrangement. The matrix should be arranged in such a manner that there are five
columns of four hexagons. The hexagons in columns one, three and five are aligned horizontally, whereas the hexagons in columns two and four occupy a lower position within the arrangement. Each hexagon should be the same colour, and should
display a unique randomly selected single capital letter on the front. The application should now wait for the user to select a hexagon, either by using a pointing device, or by pressing a key that carries a corresponding letter on a hexagon. For platforms that support pointing devices and keyboards, the application should support both methods of selection. A record of the chosen letters should be maintained and the code should be suitably commented, at the point where the the selected letter has been determined. The selected hexagon should now change colour on the display. The cycle repeats until the user has chosen all of the letters. Note that each letter can only be selected once and previously selected hexagons retain their colour after selection. The program terminates when all letters have been chosen.

Optionally: output the list of selected letters and show the last selected letter, cater for a different number of columns or a different number of hexagons in each column, cater for two players, (turns alternate and the hexagons change a different colour depending on whether they were selected by player one or player two and records of both players selections are maintained.)

[[image:honeycomb.gif]]

Solution:
/* Program for gtk3 */
/* discovery: essential to use consistent documentation */
/* compilation on linux: */
/* $ a=./hexagon && make -k "CFLAGS=$( pkg-config --cflags gtk+-3.0 )" "LOADLIBES=$( pkg-config --libs gtk+-3.0 )" $a && $a --gtk-debug=all */
/* search for  to do */
/* The keyboard and mouse callbacks increment the "selected" status, */
/* of the matching hexagon, */
/* then invalidate the drawing window which triggers a draw event. */
/* The draw callback redraws the screen and tests for completion, */
/* upon which the program spits back the characters selected and exits */

#include
#include
#include
#include

static GdkPixbuf*create_pixbuf(const gchar*filename) {
  GdkPixbuf*pixbuf;
  GError*error = NULL;
  pixbuf = gdk_pixbuf_new_from_file(filename, &error);
  if(!pixbuf) {
    fprintf(stderr,"\n%s\n", error->message);
    g_error_free(error);
  }
  return pixbuf;
}

#define NGON struct ngon
NGON {
  double Cx,Cy, r;
  int sides, selected;
  char c;
};

GRand*random_numbers = NULL;

#define R 20
#define TAU (2*M_PI)	   /* http://laughingsquid.com/pi-is-wrong/ */
#define OFFSET_X (1+sin(TAU/12))
#define OFFSET_Y (cos(TAU/12))
#define ODD(A) ((A)&1)

static void initialize_hexagons(NGON*hs,size_t n) {
  NGON*h;
  gint i,broken;
  GQueue*shuffler = g_queue_new();
  if (NULL == shuffler) {
    fputs("\ncannot allocate shuffling queue.  quitting!\n",stderr);
    exit(EXIT_FAILURE);
  }
  /* randomize characters by stuffing them onto a double end queue
     and popping them off from random positions */
  if ((broken = (NULL == random_numbers)))
    random_numbers = g_rand_new();
  for (i = 'A'; i <= 'Z'; ++i)
    g_queue_push_head(shuffler,GINT_TO_POINTER(i));
  memset(hs,0,n*(sizeof(NGON)));
  hs[n-1].sides = -1;		/* assign the sentinel */
  for (h = hs; !h->sides; ++h) {
    int div = (h-hs)/4, mod = (h-hs)%4;
    h->sides = 6;
    h->c = GPOINTER_TO_INT(
	     g_queue_pop_nth(
	       shuffler,
	       g_rand_int_range(
		 random_numbers,
		 (gint32)0,
		 (gint32)g_queue_get_length(shuffler))));
    fputc(h->c,stderr);
    h->r = R;
    h->Cx = R*(2+div*OFFSET_X), h->Cy = R*(2*(1+mod*OFFSET_Y)+ODD(div)*OFFSET_Y);
    fprintf(stderr,"(%g,%g)\n",h->Cx,h->Cy);
  }
  fputc('\n',stderr);
  g_queue_free(shuffler);
  if (broken)
    g_rand_free(random_numbers);
}

static void add_loop(cairo_t*cr,NGON*hs,int select) {
  NGON*h;
  double r,Cx,Cy,x,y;
  int i, sides;
  for (h = hs; 0 < (sides = h->sides); ++h)
    if ((select && h->selected) || (select == h->selected)) {
      r = h->r, Cx = h->Cx, Cy = h->Cy;
      i = 0;
      x = Cx+r*cos(TAU*i/sides), y = Cy+r*sin(TAU*i/sides), cairo_move_to(cr,x,y);
      for (i = 1; i < sides; ++i)
        x = Cx+r*cos(TAU*i/sides), y = Cy+r*sin(TAU*i/sides), cairo_line_to(cr,x,y);
      cairo_close_path(cr);
    }
}

static int make_labels(cairo_t*cr,NGON*hs,int select) {
  NGON*h;
  int i = 0;
  char text[2];
  text[1] = 0;
  for (h = hs; 0 < h->sides; ++h)
    if ((select && h->selected) || (select == h->selected))
      /* yuck, need to measure the font.  Better to use pango_cairo */
      *text = h->c, cairo_move_to(cr,h->Cx,h->Cy), cairo_show_text(cr,text), ++i;
  return i;
}

static int archive(int a) {
  static GQueue*q = NULL;
  if ((NULL == q) && (NULL == (q = g_queue_new()))) {
    fputs("\ncannot allocate archival queue.  quitting!\n",stderr);
    exit(EXIT_FAILURE);
  }
  if (a < -1)			/* reset */
    return g_queue_free(q), q = NULL, 0;
  if (-1 == a)			/* pop off tail */
    return g_queue_is_empty(q) ? 0 : GPOINTER_TO_INT(g_queue_pop_tail(q));
  if (!a)			/* peek most recent entry */
    return g_queue_is_empty(q) ? 0 : GPOINTER_TO_INT(g_queue_peek_head(q));
  g_queue_push_head(q,GINT_TO_POINTER(a)); /* store */
  return a;
}

/* to do: use appropriate sizing, use the cairo transformation matrix */
static gboolean draw(GtkWidget*widget,cairo_t*cr,gpointer data) {

  /* unselected fill in yellow */
  cairo_set_source_rgba(cr,0.8,0.8,0,1),
  add_loop(cr,(NGON*)data,0);
  cairo_fill(cr);

  /* selected fill, purple */
  cairo_set_source_rgba(cr,0.8,0,0.8,1);
  add_loop(cr,(NGON*)data,1);
  cairo_fill_preserve(cr);

  /* all outlines gray, background shows through, fun fun! */
  cairo_set_line_width (cr, 3.0);
  cairo_set_source_rgba(cr,0.7,0.7,0.7,0.7);
  add_loop(cr,(NGON*)data,0);
  cairo_stroke(cr);

  /* select labels */
  cairo_set_source_rgba(cr,0,1,0,1);
  make_labels(cr,(NGON*)data,1);
  cairo_stroke(cr);

  /* unselected labels */
  cairo_set_source_rgba(cr,1,0,0,1);
  /* to do: clean up this exit code */
  if (!make_labels(cr,(NGON*)data,0)) {
    int c;
    putchar('\n');
    while ((c = archive(-1)))
      putchar(c);
    puts("\nfinished");
    archive(-2);
    exit(EXIT_SUCCESS);
  }
  cairo_stroke(cr);

  return TRUE;
}

/*the widget is a GtkDrawingArea*/
static gboolean button_press_event(GtkWidget*widget,const GdkEvent*event,gpointer data) {
  NGON*h,*hs = (NGON*)data;
  gdouble x_win, y_win;
  if (!gdk_event_get_coords(event,&x_win,&y_win))
    fputs("\nBUTTON, gdk_event_get_coords(event,&x_win,&y_win)) failed\n",stderr);
  else {
    fprintf(stderr,"x_win=%g y_win=%g\n",(double)x_win,(double)y_win);
    for (h = hs; 0 < h->sides; ++h) /* detection algorithm: */
      /* if mouse click within inner radius of hexagon */
      /* Much easier than all in-order cross products have same sign test! */
      if ((pow((x_win-h->Cx),2)+pow((y_win-h->Cy),2)) < pow((h->r*cos(TAU/(180/h->sides))),2)) {
	++h->selected;
	archive(h->c);
	/* discovery: gdk_window_invalidate_region with NULL second argument does not work */
	gdk_window_invalidate_rect(gtk_widget_get_window(widget),(const GdkRectangle*)NULL,TRUE);
	break;
      }
  }
  return TRUE;
}

static gboolean key_press_event(GtkWidget*widget,const GdkEvent*event,gpointer data) {
  NGON*h,*hs = (NGON*)data;
  guint keyval;
  int unicode;
  if (!gdk_event_get_keyval(event,&keyval))
    fputs("\nKEY!  gdk_event_get_keyval(event,&keyval)) failed.\n",stderr);
  else {
    unicode = (int)gdk_keyval_to_unicode(gdk_keyval_to_upper(keyval));
    fprintf(stderr,"key with unicode value: %d\n",unicode);
    for (h = hs; 0 < h->sides; ++h) /* look for a matching character associated with a hexagon */
      if (h->c == unicode) {
	++(h->selected);
	archive(h->c);
	/* discovery: gdk_window_invalidate_region with NULL second argument does not work */
	gdk_window_invalidate_rect(gtk_widget_get_window(widget),(const GdkRectangle*)NULL,TRUE);
	break;
      }
  }
  return TRUE;
}

int main(int argc,char*argv[]) {
  GtkWidget *window, *vbox, /* *label, */ *drawing_area;
  NGON ngons[21];	   /* sentinal has negative number of sides */

  /* discovery: gtk_init removes gtk debug flags, such as --gtk-debug=all */
  /*   also calls gdk_init which handles --display and --screen or other X11 communication issues */
  gtk_init(&argc, &argv);

  /* GTK VERSION 3.2.0 */
  fprintf(stderr,"GTK VERSION %d.%d.%d\n",GTK_MAJOR_VERSION,GTK_MINOR_VERSION,GTK_MICRO_VERSION);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  /* discovery: to make window transparent I have to use the alpha channel correctly */

  /* discovery: GTK_WINDOW(GtkWidget*) casts the widget to window */
  /* discovery: window in the function name?  use GTK_WINDOW.  g_ in function name?  use G_OBJECT */
  gtk_window_set_title(GTK_WINDOW(window), "Rosetta Code Honeycomb, C with GTK");
  gtk_window_set_default_size(GTK_WINDOW(window), 308, 308+12+8); /* XxY */
  /* discovery: making the window vanish does not stop the program */
  /* discovery: NULL is placeholder for extra data sent to the callback */
  g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);

  /* I created /tmp/favicon.ico from http://rosettacode.org/favicon.ico */
  /* Your window manager could use the icon, if it exists, and you fix the file name */
  gtk_window_set_icon(GTK_WINDOW(window),create_pixbuf("/tmp/favicon.ico"));

  vbox = gtk_vbox_new(TRUE,1);
  gtk_container_add(GTK_CONTAINER(window),vbox);

  /* to do: fix the label widget */
  /* I did not learn to control multiple box packing, and I was */
  /* too lazy to make the label widget accessible.  Plan was to */
  /* insert the most recent character using "peek" option of the archive */
#if 0
  label = gtk_label_new("None Selected");
  gtk_widget_set_size_request(label,308,20);
  gtk_box_pack_end(GTK_BOX(vbox),label,FALSE,TRUE,4);
#endif

  drawing_area = gtk_drawing_area_new();
  gtk_widget_set_events(drawing_area,GDK_BUTTON_PRESS_MASK|GDK_KEY_PRESS_MASK|GDK_EXPOSURE_MASK);

  random_numbers = g_rand_new();
  initialize_hexagons(ngons,G_N_ELEMENTS(ngons));
  /* Discovery: expose_event changed to draw signal.  We no longer need configure-event */
  g_signal_connect(G_OBJECT(drawing_area),"draw",G_CALLBACK(draw),(gpointer)ngons);

  g_signal_connect(G_OBJECT(drawing_area),"button-press-event",G_CALLBACK(button_press_event),(gpointer)ngons);
  g_signal_connect(G_OBJECT(drawing_area),"key-press-event",G_CALLBACK(key_press_event),(gpointer)ngons);
  gtk_widget_set_size_request(drawing_area, 308, 308); /* XxY */
  gtk_box_pack_start(GTK_BOX(vbox),drawing_area,TRUE,TRUE,4);

  /* Discovery: must allow focus to receive keyboard events */
  gtk_widget_set_can_focus(drawing_area,TRUE);

  /* Discovery: can set show for individual widgets or use show_all */
  gtk_widget_show_all(window);
  gtk_main();
  g_rand_free(random_numbers);
  return EXIT_SUCCESS;
}


Honeycombs

Solution: [[Honeycombs/Python|Rambling python3 code with tkinter]]


Horner's rule for polynomial evaluation

A fast scheme for evaluating a polynomial such as:
: -19+7x-4x^2+6x^3\,
when
: x=3\;.
is to arrange the computation as follows:
: ((((0) x + 6) x + (-4)) x + 7) x + (-19)\;
And compute the result from the innermost brackets outwards as in this pseudocode:
 coefficients ''':=''' [-19, 7, -4, 6] ''# list coefficients of all x^0..x^n in order''
 x ''':=''' 3
 accumulator ''':=''' 0
 '''for''' i '''in''' ''length''(coefficients) '''downto''' 1 '''do'''
     ''# Assumes 1-based indexing for arrays''
     accumulator ''':=''' ( accumulator * x ) + coefficients[i]
 '''done'''
 ''# accumulator now has the answer''

'''Task Description'''
:Create a routine that takes a list of coefficients of a polynomial in order of increasing powers of x; together with a value of x to compute its value at, and return the value of the polynomial at that value using [http://www.physics.utah.edu/~detar/lessons/c++/array/node1.html Horner's rule].

Cf. [[Formal power series]]

Solution:
#include

double horner(double *coeffs, int s, double x)
{
  int i;
  double res = 0.0;

  for(i=s-1; i >= 0; i--)
  {
    res = res * x + coeffs[i];
  }
  return res;
}

int main()
{
  double coeffs[] = { -19.0, 7.0, -4.0, 6.0 };

  printf("%5.1f\n", horner(coeffs, sizeof(coeffs)/sizeof(double), 3.0));
  return 0;
}


Horner's rule for polynomial evaluation

Solution:
function horner(coeffs, x) {
    return coeffs.reduceRight( function(acc, coeff) { return(acc * x + coeff) }, 0);
}
console.log(horner([-19,7,-4,6],3));  // ==> 128


Horner's rule for polynomial evaluation

Solution:
>>> try: from functools import reduce
except: pass

>>> def horner(coeffs, x):
	return reduce(lambda acc, c: acc * x + c, reversed(coeffs), 0)

>>> horner( (-19, 7, -4, 6), 3)
128


ISBN13 check digit

;Task:
Validate the check digit of an ISBN-13 code:
::*   Multiply every other digit by  '''3'''.
::*   Add these numbers and the other digits.
::*   Take the remainder of this number after division by  '''10'''.
::*   If it is  '''0''',   the ISBN-13 check digit is correct.

You might use the following codes for testing:
::::*   978-0596528126              (good)
::::*   978-0596528120          (bad)
::::*   978-1788399081              (good)
::::*   978-1788399083          (bad)

Show output here, on this page

;See also:
:*   for details:   [https://isbn-information.com/the-13-digit-isbn.html 13-digit ISBN method of validation].       (installs cookies.)

Solution:
#include

int check_isbn13(const char *isbn) {
    int ch = *isbn, count = 0, sum = 0;
    /* check isbn contains 13 digits and calculate weighted sum */
    for ( ; ch != 0; ch = *++isbn, ++count) {
        /* skip hyphens or spaces */
        if (ch == ' ' || ch == '-') {
            --count;
            continue;
        }
        if (ch < '0' || ch > '9') {
            return 0;
        }
        if (count & 1) {
            sum += 3 * (ch - '0');
        } else {
            sum += ch - '0';
        }
    }
    if (count != 13) return 0;
    return !(sum%10);
}

int main() {
    int i;
    const char* isbns[] = {"978-1734314502", "978-1734314509", "978-1788399081", "978-1788399083"};
    for (i = 0; i < 4; ++i) {
        printf("%s: %s\n", isbns[i], check_isbn13(isbns[i]) ? "good" : "bad");
    }
    return 0;
}


ISBN13 check digit

Solution:
def is_isbn13(n):
    n = n.replace('-','').replace(' ', '')
    if len(n) != 13:
        return False
    product = (sum(int(ch) for ch in n[::2])
               + sum(int(ch) * 3 for ch in n[1::2]))
    return product % 10 == 0

if __name__ == '__main__':
    tests = '''
978-1734314502
978-1734314509
978-1788399081
978-1788399083'''.strip().split()
    for t in tests:
        print(f"ISBN13 {t} validates {is_isbn13(t)}")


I before E except after C

The phrase      "I before E, except after C"     is a
widely known mnemonic which is supposed to help when spelling English words.

;Task:
Using the word list from   [http://wiki.puzzlers.org/pub/wordlists/unixdict.txt http://wiki.puzzlers.org/pub/wordlists/unixdict.txt],
check if the two sub-clauses of the phrase are plausible individually:
:::#   ''"I before E when not preceded by C"''
:::#   ''"E before I when preceded by C"''

If both sub-phrases are plausible then the original phrase can be said to be plausible.

Something is plausible if the number of words having the feature is more than two times the number of words having the opposite feature (where feature is 'ie' or 'ei' preceded or not by 'c' as appropriate).

;Stretch goal:
As a stretch goal use the entries from the table of [http://ucrel.lancs.ac.uk/bncfreq/lists/1_2_all_freq.txt Word Frequencies in Written and Spoken English: based on the British National Corpus], (selecting those rows with three space or tab separated words only), to see if the phrase is plausible when word frequencies are taken into account.

''Show your output here as well as your program.''

;cf.:
* [http://news.bbc.co.uk/1/hi/education/8110573.stm Schools to rethink 'i before e'] - BBC news, 20 June 2009
* [http://www.youtube.com/watch?v=duqlZXiIZqA I Before E Except After C] - QI Series 8 Ep 14, (humorous)
* [http://ucrel.lancs.ac.uk/bncfreq/ Companion website] for the book: "Word Frequencies in Written and Spoken English: based on the British National Corpus".

Solution:
%{
  /*
    compilation and example on a GNU linux system:

    $ flex --case-insensitive --noyywrap --outfile=cia.c source.l
    $ make LOADLIBES=-lfl cia
    $ ./cia < unixdict.txt
    I before E when not preceded by C: plausible
    E before I when preceded by C: implausible
    Overall, the rule is: implausible
  */
  int cie, cei, ie, ei;
%}

%%

cie ++cie, ++ie; /* longer patterns are matched preferentially, consuming input */
cei ++cei, ++ei;
ie ++ie;
ei ++ei;
.|\n ;

%%

int main() {
  cie = cei = ie = ei = 0;
  yylex();
  printf("%s: %s\n","I before E when not preceded by C", (2*ei < ie ? "plausible" : "implausible"));
  printf("%s: %s\n","E before I when preceded by C", (2*cie < cei ? "plausible" : "implausible"));
  printf("%s: %s\n","Overall, the rule is", (2*(cie+ei) < (cei+ie) ? "plausible" : "implausible"));
  return 0;
}


I before E except after C

Solution:
import urllib.request
import re

PLAUSIBILITY_RATIO = 2

def plausibility_check(comment, x, y):
    print('\n  Checking plausibility of: %s' % comment)
    if x > PLAUSIBILITY_RATIO * y:
        print('    PLAUSIBLE. As we have counts of %i vs %i, a ratio of %4.1f times'
              % (x, y, x / y))
    else:
        if x > y:
            print('    IMPLAUSIBLE. As although we have counts of %i vs %i, a ratio of %4.1f times does not make it plausible'
                  % (x, y, x / y))
        else:
            print('    IMPLAUSIBLE, probably contra-indicated. As we have counts of %i vs %i, a ratio of %4.1f times'
                  % (x, y, x / y))
    return x > PLAUSIBILITY_RATIO * y

def simple_stats(url='http://wiki.puzzlers.org/pub/wordlists/unixdict.txt'):
    words = urllib.request.urlopen(url).read().decode().lower().split()
    cie = len({word for word in words if 'cie' in word})
    cei = len({word for word in words if 'cei' in word})
    not_c_ie = len({word for word in words if re.search(r'(^ie|[^c]ie)', word)})
    not_c_ei = len({word for word in words if re.search(r'(^ei|[^c]ei)', word)})
    return cei, cie, not_c_ie, not_c_ei

def print_result(cei, cie, not_c_ie, not_c_ei):
    if ( plausibility_check('I before E when not preceded by C', not_c_ie, not_c_ei)
         & plausibility_check('E before I when preceded by C', cei, cie) ):
        print('\nOVERALL IT IS PLAUSIBLE!')
    else:
        print('\nOVERALL IT IS IMPLAUSIBLE!')
    print('(To be plausible, one count must exceed another by %i times)' % PLAUSIBILITY_RATIO)

print('Checking plausibility of "I before E except after C":')
print_result(*simple_stats())


Identity matrix

[[Category:Matrices]]

;Task:
Build an   identity matrix   of a size known at run-time.

An ''identity matrix'' is a square matrix of size '''''n'' × ''n''''',
where the diagonal elements are all '''1'''s (ones),
and all the other elements are all '''0'''s (zeroes).

I_n = \begin{bmatrix}
  1      & 0      & 0      & \cdots & 0      \\
  0      & 1      & 0      & \cdots & 0      \\
  0      & 0      & 1      & \cdots & 0      \\
  \vdots & \vdots & \vdots & \ddots & \vdots \\
  0      & 0      & 0      & \cdots & 1      \\
\end{bmatrix}

;Related tasks:
*   [[Spiral matrix]]
*   [[Zig-zag matrix]]
*   [[Ulam_spiral_(for_primes)]]

Solution:
#include
#include
int main(int argc, char** argv) {
   if (argc < 2) {
      printf("usage: identitymatrix \n");
      exit(EXIT_FAILURE);
   }
   int rowsize = atoi(argv[1]);
   if (rowsize < 0) {
      printf("Dimensions of matrix cannot be negative\n");
      exit(EXIT_FAILURE);
   }
   int numElements = rowsize * rowsize;
   if (numElements < rowsize) {
      printf("Squaring %d caused result to overflow to %d.\n", rowsize, numElements);
      abort();
   }
   int** matrix = calloc(numElements, sizeof(int*));
   if (!matrix) {
      printf("Failed to allocate %d elements of %ld bytes each\n", numElements, sizeof(int*));
      abort();
   }
   for (unsigned int row = 0;row < rowsize;row++) {
      matrix[row] = calloc(numElements, sizeof(int));
      if (!matrix[row]) {
         printf("Failed to allocate %d elements of %ld bytes each\n", numElements, sizeof(int));
         abort();
      }
      matrix[row][row] = 1;
   }
   printf("Matrix is: \n");
   for (unsigned int row = 0;row < rowsize;row++) {
      for (unsigned int column = 0;column < rowsize;column++) {
         printf("%d ", matrix[row][column]);
      }
      printf("\n");
   }
}


Identity matrix

Solution:
(() => {

    // identityMatrix :: Int -> [[Int]]
    const identityMatrix = n =>
        Array.from({
            length: n
        }, (_, i) => Array.from({
            length: n
        }, (_, j) => i !== j ? 0 : 1));

    // ----------------------- TEST ------------------------
    return identityMatrix(5)
        .map(JSON.stringify)
        .join('\n');
})();


Identity matrix

Solution:
def identity(size):
    matrix = [[0]*size for i in range(size)]
    #matrix = [[0] * size] * size    #Has a flaw. See http://stackoverflow.com/questions/240178/unexpected-feature-in-a-python-list-of-lists

    for i in range(size):
        matrix[i][i] = 1

    for rows in matrix:
        for elements in rows:
            print elements,
        print ""


Identity matrix

Solution:
'''Identity matrices by maps and equivalent list comprehensions'''

import operator

# idMatrix :: Int -> [[Int]]
def idMatrix(n):
    '''Identity matrix of order n,
       expressed as a nested map.
    '''
    eq = curry(operator.eq)
    xs = range(0, n)
    return list(map(
        lambda x: list(map(
            compose(int)(eq(x)),
            xs
        )),
        xs
    ))

# idMatrix3 :: Int -> [[Int]]
def idMatrix2(n):
    '''Identity matrix of order n,
       expressed as a nested comprehension.
    '''
    xs = range(0, n)
    return ([int(x == y) for x in xs] for y in xs)

# TEST ----------------------------------------------------
def main():
    '''
        Identity matrix of dimension five,
        by two different routes.
    '''
    for f in [idMatrix, idMatrix2]:
        print(
            '\n' + f.__name__ + ':',
            '\n\n' + '\n'.join(map(str, f(5))),
        )

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

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

# curry :: ((a, b) -> c) -> a -> b -> c
def curry(f):
    '''A curried function derived
       from an uncurried function.'''
    return lambda a: lambda b: f(a, b)

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


Idiomatically determine all the characters that can be used for symbols

Idiomatically determine all the characters that can be used for ''symbols''.
The word ''symbols'' is meant things like names of variables, procedures (i.e., named fragments of programs, functions, subroutines, routines), statement labels, events or conditions, and in general, anything a computer programmer can choose to ''name'', but not being restricted to this list. ''Identifiers'' might be another name for ''symbols''.

The method should find the characters regardless of the hardware architecture that is being used  (ASCII, EBCDIC, or other).

;Task requirements

Display the set of all the characters that can be used for symbols which can be used (allowed) by the computer program.
You may want to mention what hardware architecture is being used, and if applicable, the operating system.

Note that most languages have additional restrictions on what characters can't be used for the first character of a variable or statement label, for instance.  These type of restrictions needn't be addressed here (but can be mentioned).

;See also
* Idiomatically determine all the lowercase and uppercase letters.

Solution: See [[Idiomatically_determine_all_the_lowercase_and_uppercase_letters#Python|String class isidentifier]].


right

Idiomatically determine all the lowercase and uppercase letters   (of the Latin [English] alphabet)   being used currently by a computer programming language.
The method should find the letters regardless of the hardware architecture that is being used (ASCII, EBCDIC, or other).

;Task requirements

Display the set of all:
::::::*   lowercase letters
::::::*   uppercase letters

that can be used (allowed) by the computer program,

where   ''letter''   is a member of the Latin (English) alphabet:     '''a''' ──► '''z'''     and     '''A''' ──► '''Z'''.

You may want to mention what hardware architecture is being used, and if applicable, the operating system.

;See also
* Idiomatically determine all the characters that can be used for symbols.

Solution:
#include

int main(int argc, char const *argv[]) {
  for (char c = 0x41; c < 0x5b; c ++) putchar(c);
  putchar('\n');
  for (char c = 0x61; c < 0x7b; c ++) putchar(c);
  putchar('\n');
  return 0;
}


Solution:
classes = (str.isupper, str.islower, str.isalnum, str.isalpha, str.isdecimal,
           str.isdigit, str.isidentifier, str.isnumeric, str.isprintable,
           str.isspace, str.istitle)

for stringclass in classes:
    chars = ''.join(chr(i) for i in range(0x10FFFF+1) if stringclass(chr(i)))
    print('\nString class %s has %i characters the first of which are:\n  %r'
          % (stringclass.__name__, len(chars), chars[:100]))


Imaginary base numbers

Imaginary base numbers are a non-standard positional numeral system which uses an imaginary number as its radix. The most common is quater-imaginary with radix 2i.

''The quater-imaginary numeral system was first proposed by [https://en.wikipedia.org/wiki/Donald_Knuth Donald Knuth] in 1955 as a submission for a high school science talent search. [http://www.fact-index.com/q/qu/quater_imaginary_base.html  [Ref.]]''

Other imaginary bases are possible too but are not as widely discussed and aren't specifically named.

'''Task:''' Write a set of procedures (functions, subroutines, however they are referred to in your language) to convert base 10 numbers to an imaginary base and back.

At a minimum, support quater-imaginary (base 2i).

For extra kudos, support positive or negative bases 2i through 6i (or higher).

As a stretch goal, support converting non-integer numbers ( E.G. 227.65625+10.859375i ) to an imaginary base.

See [https://en.wikipedia.org/wiki/Quater-imaginary_base Wikipedia: Quater-imaginary_base] for more details.

For reference, here are some some decimal and complex numbers converted to quater-imaginary.

Base 10
Base 2i

1
 1

2
 2

3
 3

4
 10300

5
 10301

6
 10302

7
 10303

8
 10200

9
 10201

10
 10202

11
 10203

12
 10100

13
 10101

14
 10102

15
 10103

16
 10000

Base 10
Base 2i

−1
 103

−2
 102

−3
 101

−4
 100

−5
 203

−6
 202

−7
 201

−8
 200

−9
 303

−10
 302

−11
 301

−12
 300

−13
 1030003

−14
 1030002

−15
 1030001

−16
 1030000

Base 10
Base 2i

1i
10.2

2i
10.0

3i
20.2

4i
20.0

5i
30.2

6i
30.0

7i
103000.2

8i
103000.0

9i
103010.2

10i
103010.0

11i
103020.2

12i
103020.0

13i
103030.2

14i
103030.0

15i
102000.2

16i
102000.0

Base 10
Base 2i

−1i
0.2

−2i
1030.0

−3i
1030.2

−4i
1020.0

−5i
1020.2

−6i
1010.0

−7i
1010.2

−8i
1000.0

−9i
1000.2

−10i
2030.0

−11i
2030.2

−12i
2020.0

−13i
2020.2

−14i
2010.0

−15i
2010.2

−16i
2000.0

Solution:
#include
#include
#include

int find(char *s, char c) {
    for (char *i = s; *i != 0; i++) {
        if (*i == c) {
            return i - s;
        }
    }
    return -1;
}

void reverse(char *b, char *e) {
    for (e--; b < e; b++, e--) {
        char t = *b;
        *b = *e;
        *e = t;
    }
}

//////////////////////////////////////////////////////

struct Complex {
    double rel, img;
};

void printComplex(struct Complex c) {
    printf("(%3.0f + %3.0fi)", c.rel, c.img);
}

struct Complex makeComplex(double rel, double img) {
    struct Complex c = { rel, img };
    return c;
}

struct Complex addComplex(struct Complex a, struct Complex b) {
    struct Complex c = { a.rel + b.rel, a.img + b.img };
    return c;
}

struct Complex mulComplex(struct Complex a, struct Complex b) {
    struct Complex c = { a.rel * b.rel - a.img * b.img, a.rel * b.img - a.img * b.rel };
    return c;
}

struct Complex mulComplexD(struct Complex a, double b) {
    struct Complex c = { a.rel * b, a.img * b };
    return c;
}

struct Complex negComplex(struct Complex a) {
    return mulComplexD(a, -1.0);
}

struct Complex divComplex(struct Complex a, struct Complex b) {
    double re = a.rel * b.rel + a.img * b.img;
    double im = a.img * b.rel - a.rel * b.img;
    double d = b.rel * b.rel + b.img * b.img;
    struct Complex c = { re / d, im / d };
    return c;
}

struct Complex inv(struct Complex c) {
    double d = c.rel * c.rel + c.img * c.img;
    struct Complex i = { c.rel / d, -c.img / d };
    return i;
}

const struct Complex TWO_I = { 0.0, 2.0 };
const struct Complex INV_TWO_I = { 0.0, -0.5 };

//////////////////////////////////////////////////////

struct QuaterImaginary {
    char *b2i;
    int valid;
};

struct QuaterImaginary makeQuaterImaginary(char *s) {
    struct QuaterImaginary qi = { s, 0 }; // assume invalid until tested
    size_t i, valid = 1, cnt = 0;

    if (*s != 0) {
        for (i = 0; s[i] != 0; i++) {
            if (s[i] < '0' || '3' < s[i]) {
                if (s[i] == '.') {
                    cnt++;
                } else {
                    valid = 0;
                    break;
                }
            }
        }
        if (valid && cnt > 1) {
            valid = 0;
        }
    }

    qi.valid = valid;
    return qi;
}

void printQuaterImaginary(struct QuaterImaginary qi) {
    if (qi.valid) {
        printf("%8s", qi.b2i);
    } else {
        printf(" ERROR  ");
    }
}

//////////////////////////////////////////////////////

struct Complex qi2c(struct QuaterImaginary qi) {
    size_t len = strlen(qi.b2i);
    int pointPos = find(qi.b2i, '.');
    size_t posLen = (pointPos > 0) ? pointPos : len;
    struct Complex sum = makeComplex(0.0, 0.0);
    struct Complex prod = makeComplex(1.0, 0.0);
    size_t j;

    for (j = 0; j < posLen; j++) {
        double k = qi.b2i[posLen - 1 - j] - '0';
        if (k > 0.0) {
            sum = addComplex(sum, mulComplexD(prod, k));
        }
        prod = mulComplex(prod, TWO_I);
    }
    if (pointPos != -1) {
        prod = INV_TWO_I;
        for (j = posLen + 1; j < len; j++) {
            double k = qi.b2i[j] - '0';
            if (k > 0.0) {
                sum = addComplex(sum, mulComplexD(prod, k));
            }
            prod = mulComplex(prod, INV_TWO_I);
        }
    }
    return sum;
}

// only works properly if the real and imaginary parts are integral
struct QuaterImaginary c2qi(struct Complex c, char *out) {
    char *p = out;
    int re, im, fi;

    *p = 0;
    if (c.rel == 0.0 && c.img == 0.0) {
        return makeQuaterImaginary("0");
    }

    re = (int)c.rel;
    im = (int)c.img;
    fi = -1;
    while (re != 0) {
        int rem = re % -4;
        re /= -4;
        if (rem < 0) {
            rem += 4;
            re++;
        }
        *p++ = rem + '0';
        *p++ = '0';
        *p = 0;
    }
    if (im != 0) {
        size_t index = 1;
        struct Complex fc = divComplex((struct Complex) { 0.0, c.img }, (struct Complex) { 0.0, 2.0 });
        double f = fc.rel;
        im = (int)ceil(f);
        f = -4.0 * (f - im);
        while (im != 0) {
            int rem = im % -4;
            im /= -4;
            if (rem < 0) {
                rem += 4;
                im++;
            }
            if (index < (p - out)) {
                out[index] = rem + '0';
            } else {
                *p++ = '0';
                *p++ = rem + '0';
                *p = 0;
            }
            index += 2;
        }
        fi = (int)f;
    }

    reverse(out, p);
    if (fi != -1) {
        *p++ = '.';
        *p++ = fi + '0';
        *p = 0;
    }
    while (out[0] == '0' && out[1] != '.') {
        size_t i;
        for (i = 0; out[i] != 0; i++) {
            out[i] = out[i + 1];
        }
    }
    if (*out == '.') {
        reverse(out, p);
        *p++ = '0';
        *p = 0;
        reverse(out, p);
    }
    return makeQuaterImaginary(out);
}

//////////////////////////////////////////////////////

int main() {
    char buffer[16];
    int i;

    for (i = 1; i <= 16; i++) {
        struct Complex c1 = { i, 0.0 };
        struct QuaterImaginary qi = c2qi(c1, buffer);
        struct Complex c2 = qi2c(qi);
        printComplex(c1);
        printf(" -> ");
        printQuaterImaginary(qi);
        printf(" -> ");
        printComplex(c2);

        printf("     ");

        c1 = negComplex(c1);
        qi = c2qi(c1, buffer);
        c2 = qi2c(qi);
        printComplex(c1);
        printf(" -> ");
        printQuaterImaginary(qi);
        printf(" -> ");
        printComplex(c2);

        printf("\n");
    }

    printf("\n");

    for (i = 1; i <= 16; i++) {
        struct Complex c1 = { 0.0, i };
        struct QuaterImaginary qi = c2qi(c1, buffer);
        struct Complex c2 = qi2c(qi);
        printComplex(c1);
        printf(" -> ");
        printQuaterImaginary(qi);
        printf(" -> ");
        printComplex(c2);

        printf("     ");

        c1 = negComplex(c1);
        qi = c2qi(c1, buffer);
        c2 = qi2c(qi);
        printComplex(c1);
        printf(" -> ");
        printQuaterImaginary(qi);
        printf(" -> ");
        printComplex(c2);

        printf("\n");
    }

    return 0;
}


Imaginary base numbers

Solution:
import math
import re

def inv(c):
    denom = c.real * c.real + c.imag * c.imag
    return complex(c.real / denom, -c.imag / denom)

class QuaterImaginary:
    twoI = complex(0, 2)
    invTwoI = inv(twoI)

    def __init__(self, str):
        if not re.match("^[0123.]+$", str) or str.count('.') > 1:
            raise Exception('Invalid base 2i number')
        self.b2i = str

    def toComplex(self):
        pointPos = self.b2i.find('.')
        posLen = len(self.b2i) if (pointPos < 0) else pointPos
        sum = complex(0, 0)
        prod = complex(1, 0)
        for j in xrange(0, posLen):
            k = int(self.b2i[posLen - 1 - j])
            if k > 0:
                sum += prod * k
            prod *= QuaterImaginary.twoI
        if pointPos != -1:
            prod = QuaterImaginary.invTwoI
            for j in xrange(posLen + 1, len(self.b2i)):
                k = int(self.b2i[j])
                if k > 0:
                    sum += prod * k
                prod *= QuaterImaginary.invTwoI
        return sum

    def __str__(self):
        return str(self.b2i)

def toQuaterImaginary(c):
    if c.real == 0.0 and c.imag == 0.0:
        return QuaterImaginary("0")

    re = int(c.real)
    im = int(c.imag)
    fi = -1
    ss = ""
    while re != 0:
        re, rem = divmod(re, -4)
        if rem < 0:
            rem += 4
            re += 1
        ss += str(rem) + '0'
    if im != 0:
        f = c.imag / 2
        im = int(math.ceil(f))
        f = -4 * (f - im)
        index = 1
        while im != 0:
            im, rem = divmod(im, -4)
            if rem < 0:
                rem += 4
                im += 1
            if index < len(ss):
                ss[index] = str(rem)
            else:
                ss += '0' + str(rem)
            index = index + 2
        fi = int(f)
    ss = ss[::-1]
    if fi != -1:
        ss += '.' + str(fi)
    ss = ss.lstrip('0')
    if ss[0] == '.':
        ss = '0' + ss
    return QuaterImaginary(ss)

for i in xrange(1,17):
    c1 = complex(i, 0)
    qi = toQuaterImaginary(c1)
    c2 = qi.toComplex()
    print "{0:8} -> {1:>8} -> {2:8}     ".format(c1, qi, c2),

    c1 = -c1
    qi = toQuaterImaginary(c1)
    c2 = qi.toComplex()
    print "{0:8} -> {1:>8} -> {2:8}".format(c1, qi, c2)
print

for i in xrange(1,17):
    c1 = complex(0, i)
    qi = toQuaterImaginary(c1)
    c2 = qi.toComplex()
    print "{0:8} -> {1:>8} -> {2:8}     ".format(c1, qi, c2),

    c1 = -c1
    qi = toQuaterImaginary(c1)
    c2 = qi.toComplex()
    print "{0:8} -> {1:>8} -> {2:8}".format(c1, qi, c2)

print "done"


Include a file

;Task:
Demonstrate the language's ability to include source code from other files.

;See Also

* [[Compiler/Simple file inclusion pre processor]]

Solution:
/* Standard and other library header names are enclosed between chevrons */
#include

/* User/in-project header names are usually enclosed between double-quotes */
#include "myutil.h"


Include a file

Solution:
var s = document.createElement('script');
s.type = 'application/javascript';

// path to the desired file
s.src = 'http://code.jquery.com/jquery-1.6.2.js';
document.body.appendChild(s);


Increasing gaps between consecutive Niven numbers

Note:   '''Niven'''   numbers are also called   '''Harshad'''        numbers.
::::   They are also called                     '''multidigital'''   numbers.

'''Niven''' numbers are positive integers which are evenly divisible by the sum of its
digits   (expressed in base ten).

''Evenly divisible''   means   ''divisible with no remainder''.

;Task:
:*   find the gap (difference) of a Niven number from the previous Niven number
:*   if the gap is   ''larger''   than the (highest) previous gap,   then:
:::*   show the index (occurrence) of the gap      (the 1st gap is   '''1''')
:::*   show the index of the Niven number that starts the gap     (1st Niven number is   '''1''',   33rd Niven number is   '''100''')
:::*   show the Niven number that starts the gap
:::*   show all numbers with comma separators where appropriate   (optional)
:::*   I.E.:   the gap size of   '''60'''   starts at the   33,494th   Niven number which is Niven number   '''297,864'''
:*   show all increasing gaps up to the   ten millionth   ('''10,000,000th''')   Niven number
:*   (optional)   show all gaps up to whatever limit is feasible/practical/realistic/reasonable/sensible/viable on your computer
:*   show all output here, on this page

;Related task:
:*   [https://rosettacode.org/wiki/Harshad_or_Niven_series Harshad or Niven series].

;Also see:
:*   [https://cs.uwaterloo.ca/journals/JIS/VOL6/Doyon/doyon.html Journal of Integer Sequences, Vol. 6 (2004), Article 03.2.5, Large and Small Gaps Between Consecutive Niven Numbers].
:*   [https://cs.uwaterloo.ca/journals/JIS/VOL6/Doyon/doyon.pdf (PDF) version of the (above) article by Doyon].

Solution:
#include
#include
#include
#include

// Returns the sum of the digits of n given the
// sum of the digits of n - 1
uint64_t digit_sum(uint64_t n, uint64_t sum) {
    ++sum;
    while (n > 0 && n % 10 == 0) {
        sum -= 9;
        n /= 10;
    }
    return sum;
}

inline bool divisible(uint64_t n, uint64_t d) {
    if ((d & 1) == 0 && (n & 1) == 1)
        return false;
    return n % d == 0;
}

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

    uint64_t previous = 1, gap = 0, sum = 0;
    int niven_index = 0, gap_index = 1;

    printf("Gap index  Gap    Niven index    Niven number\n");
    for (uint64_t niven = 1; gap_index <= 32; ++niven) {
        sum = digit_sum(niven, sum);
        if (divisible(niven, sum)) {
            if (niven > previous + gap) {
                gap = niven - previous;
                printf("%'9d %'4llu %'14d %'15llu\n", gap_index++,
                       gap, niven_index, previous);
            }
            previous = niven;
            ++niven_index;
        }
    }
    return 0;
}


Solution:
"""

Python implementation of

http://rosettacode.org/wiki/Increasing_gaps_between_consecutive_Niven_numbers

"""

# based on C example

# Returns the sum of the digits of n given the
# sum of the digits of n - 1
def digit_sum(n, sum):
    sum += 1
    while n > 0 and n % 10 == 0:
        sum -= 9
        n /= 10

    return sum

previous = 1
gap = 0
sum = 0
niven_index = 0
gap_index = 1

print("Gap index  Gap    Niven index    Niven number")

niven = 1

while gap_index <= 22:
    sum = digit_sum(niven, sum)
    if niven % sum == 0:
        if niven > previous + gap:
            gap = niven - previous;
            print('{0:9d} {1:4d}  {2:13d}     {3:11d}'.format(gap_index, gap, niven_index, previous))
            gap_index += 1
        previous = niven
        niven_index += 1
    niven += 1


Index finite lists of positive integers

It is known that the set of finite lists of positive integers is    countable.

This means that there exists a subset of natural integers which can be mapped to the set of finite lists of positive integers.

;Task:
Implement such a mapping:
:*   write a function     ''rank''     which assigns an integer to any finite, arbitrarily long list of arbitrary large positive integers.
:*   write a function          ''unrank''        which is the   ''rank''    inverse function.

Demonstrate your solution by:
:*   picking a random-length list of random positive integers
:*   turn it into an integer,   and
:*   get the list back.

There are many ways to do this.   Feel free to choose any one you like.

;Extra credit:
Make the   ''rank''   function as a    bijection   and show   ''unrank(n)''   for   '''n'''   varying from   '''0'''   to   '''10'''.

Solution:
def rank(x): return int('a'.join(map(str, [1] + x)), 11)

def unrank(n):
	s = ''
	while n: s,n = "0123456789a"[n%11] + s, n//11
	return map(int, s.split('a'))[1:]

l = [1, 2, 3, 10, 100, 987654321]
print l
n = rank(l)
print n
l = unrank(n)
print l