Kolakoski sequence

The natural numbers, (excluding zero); with the property that:
: ''if you form a new sequence from the counts of runs of the same number in the first sequence, this new sequence is the same as the first sequence''.

;Example:
This is ''not'' a Kolakoski sequence:
1,1,2,2,2,1,2,2,1,2,...
Its sequence of run counts, (sometimes called a run length encoding, (RLE); but a true RLE also gives the character that each run encodes), is calculated like this:

: Starting from the leftmost number of the sequence we have 2 ones, followed by 3 twos, then 1 ones, 2 twos, 1 one, ...

The above gives the RLE of:
2, 3, 1, 2, 1, ...

The original sequence is different from its RLE in this case. '''It would be the same for a true Kolakoski sequence'''.

;Creating a Kolakoski sequence:

Lets start with the two numbers (1, 2) that we will cycle through; i.e. they will be used in this order: 1,2,1,2,1,2,....

# We start the sequence s with the first item from the cycle c: 1
# An index, k, into the, (expanding), sequence will step, or index through each item of the sequence s from the first, at its own rate.
We will arrange that the k'th item of s states how many ''times'' the ''last'' item of sshould appear at the end of s.

We started s with 1 and therefore s[k] states that it should appear only the 1 time.

Increment k
Get the next item from c and append it to the end of sequence s. s will then become: 1, 2
k was moved to the second item in the list and s[k] states that it should appear two times, so append another of the last item to the sequence s: 1, 2,2
Increment k
Append the next item from the cycle to the list: 1, 2,2, 1
k is now at the third item in the list that states that the last item should appear twice so add another copy of the last item to the sequence s: 1, 2,2, 1,1
increment k

...

'''Note''' that the RLE of 1, 2, 2, 1, 1, ... begins 1, 2, 2 which is the beginning of the original sequence. The generation algorithm ensures that this will always be the case.

;Task:
# Create a routine/proceedure/function/... that given an initial ordered list/array/tuple etc of the natural numbers (1, 2), returns the next number from the list when accessed in a cycle.
# Create another routine that when given the initial ordered list (1, 2) and the minimum length of the sequence  to generate; uses the first routine and the algorithm above, to generate at least the requested first members of the kolakoski sequence.
# Create a routine that when given a sequence, creates the run length encoding of that sequence (as defined above) and returns the result of checking if sequence starts with the exact members of its RLE. (But ''note'', due to sampling, do not compare the last member of the RLE).
# Show, on this page, (compactly), the first 20 members of the sequence generated from (1, 2)
# Check the sequence againt its RLE.
# Show, on this page, the first 20 members of the sequence generated from (2, 1)
# Check the sequence againt its RLE.
# Show, on this page, the first 30 members of the Kolakoski sequence generated from (1, 3, 1, 2)
# Check the sequence againt its RLE.
# Show, on this page, the first 30 members of the Kolakoski sequence generated from (1, 3, 2, 1)
# Check the sequence againt its RLE.
(There are rules on generating Kolakoski sequences from this method that are broken by the last example)

Solution:
#include
#include

#define TRUE 1
#define FALSE 0

typedef int bool;

int next_in_cycle(int *c, int len, int index) {
    return c[index % len];
}

void kolakoski(int *c, int *s, int clen, int slen) {
    int i = 0, j, k = 0;
    while (TRUE) {
        s[i] = next_in_cycle(c, clen, k);
        if (s[k] > 1) {
            for (j = 1; j < s[k]; ++j) {
                if (++i == slen) return;
                s[i] = s[i - 1];
            }
        }
        if (++i == slen) return;
        k++;
    }
}

bool possible_kolakoski(int *s, int len) {
    int i, j = 0, prev = s[0], count = 1;
    int *rle = calloc(len, sizeof(int));
    bool result = TRUE;
    for (i = 1; i < len; ++i) {
        if (s[i] == prev) {
            count++;
        }
        else {
            rle[j++] = count;
            count = 1;
            prev = s[i];
        }
    }
    /* no point adding final 'count' to rle as we're not going to compare it anyway */
    for (i = 0; i < j; i++) {
        if (rle[i] != s[i]) {
           result = FALSE;
           break;
        }
    }
    free(rle);
    return result;
}

void print_array(int *a, int len) {
    int i;
    printf("[");
    for (i = 0; i < len; ++i) {
       printf("%d", a[i]);
       if (i < len - 1) printf(", ");
    }
    printf("]");
}

int main() {
    int i, clen, slen, *s;
    int c0[2] = {1, 2};
    int c1[2] = {2, 1};
    int c2[4] = {1, 3, 1, 2};
    int c3[4] = {1, 3, 2, 1};
    int *cs[4] = {c0, c1, c2, c3};
    bool p;
    int clens[4] = {2, 2, 4, 4};
    int slens[4] = {20, 20, 30, 30};
    for (i = 0; i < 4; ++i) {
        clen = clens[i];
        slen = slens[i];
        s = calloc(slen, sizeof(int));
        kolakoski(cs[i], s, clen, slen);
        printf("First %d members of the sequence generated by ", slen);
        print_array(cs[i], clen);
        printf(":\n");
        print_array(s, slen);
        printf("\n");
        p = possible_kolakoski(s, slen);
        printf("Possible Kolakoski sequence? %s\n\n", p ? "True" : "False");
        free(s);
    }
    return 0;
}


Kolakoski sequence

Solution:
import itertools

def cycler(start_items):
	return itertools.cycle(start_items).__next__

def _kolakoski_gen(start_items):
    s, k = [], 0
    c = cycler(start_items)
    while True:
        c_next = c()
        s.append(c_next)
        sk = s[k]
        yield sk
        if sk > 1:
            s += [c_next] * (sk - 1)
        k += 1

def kolakoski(start_items=(1, 2), length=20):
    return list(itertools.islice(_kolakoski_gen(start_items), length))

def _run_len_encoding(truncated_series):
    return [len(list(group)) for grouper, group in itertools.groupby(truncated_series)][:-1]

def is_series_eq_its_rle(series):
    rle = _run_len_encoding(series)
    return (series[:len(rle)] == rle) if rle else not series

if __name__ == '__main__':
    for start_items, length in [((1, 2), 20), ((2, 1), 20),
                                ((1, 3, 1, 2), 30), ((1, 3, 2, 1), 30)]:
        print(f'\n## {length} members of the series generated from {start_items} is:')
        s = kolakoski(start_items, length)
        print(f'  {s}')
        ans = 'YES' if is_series_eq_its_rle(s) else 'NO'
        print(f'  Does it look like a Kolakoski sequence: {ans}')


Kosaraju

[[Category:Algorithm]]

Kosaraju's algorithm (also known as the Kosaraju–Sharir algorithm) is a linear time algorithm to find the strongly connected components of a directed graph. Aho, Hopcroft and Ullman credit it to an unpublished paper from 1978 by S. Rao Kosaraju. The same algorithm was independently discovered by Micha Sharir and published by him in 1981. It makes use of the fact that the transpose graph (the same graph with the direction of every edge reversed) has exactly the same strongly connected components as the original graph.

For this task consider the directed graph with these connections:
  0 -> 1
  1 -> 2
  2 -> 0
  3 -> 1,  3 -> 2,  3 -> 4
  4 -> 3,  4 -> 5
  5 -> 2,  5 -> 6
  6 -> 5
  7 -> 4, 7  -> 6, 7 -> 7

And report the kosaraju strongly connected component for each node.

;References:
* The article on Wikipedia.

Solution:
def kosaraju(g):
    class nonlocal: pass

    # 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
    size = len(g)

    vis = [False]*size # vertexes that have been visited
    l = [0]*size
    nonlocal.x = size
    t = [[]]*size   # transpose graph

    def visit(u):
        if not vis[u]:
            vis[u] = True
            for v in g[u]:
                visit(v)
                t[v] = t[v] + [u]
            nonlocal.x = nonlocal.x - 1
            l[nonlocal.x] = u

    # 2. For each vertex u of the graph do visit(u)
    for u in range(len(g)):
        visit(u)
    c = [0]*size

    def assign(u, root):
        if vis[u]:
            vis[u] = False
            c[u] = root
            for v in t[u]:
                assign(v, root)

    # 3: For each element u of l in order, do assign(u, u)
    for u in l:
        assign(u, u)

    return c

g = [[1], [2], [0], [1,2,4], [3,5], [2,6], [5], [4,6,7]]
print kosaraju(g)


Lah numbers

Lah numbers, sometimes referred to as ''Stirling numbers of the third kind'', are coefficients of polynomial expansions expressing rising factorials in terms of falling factorials.

Unsigned Lah numbers count the number of ways a set of '''n''' elements can be partitioned into '''k''' non-empty linearly ordered subsets.

Lah numbers are closely related to Stirling numbers of the first & second kinds, and may be derived from them.

Lah numbers obey the identities and relations:
   L(n, 0), L(0, k) = 0   # for n, k > 0
   L(n, n) = 1
   L(n, 1) = n!
   L(n, k) =           ( n! * (n - 1)! ) / ( k! * (k - 1)! ) / (n - k)!      # For unsigned Lah numbers
      ''or''
   L(n, k) = (-1)**n * ( n! * (n - 1)! ) / ( k! * (k - 1)! ) / (n - k)!      # For   signed Lah numbers

;Task:
:* Write a routine (function, procedure, whatever) to find '''unsigned Lah numbers'''. There are several methods to generate unsigned Lah numbers. You are free to choose the most appropriate for your language. If your language has a built-in, or easily, publicly available library implementation, it is acceptable to use that.

:* Using the routine, generate and show here, on this page, a table (or triangle) showing the unsigned Lah numbers, '''L(n, k)''', up to '''L(12, 12)'''. it is optional to show the row / column for n == 0 and k == 0. It is optional to show places where L(n, k) == 0 (when k > n).

:* If your language supports large integers, find and show here, on this page, the maximum value of '''L(n, k)''' where '''n == 100'''.

;See also:

:* '''Wikipedia - Lah number'''
:* '''OEIS:A105278 - Unsigned Lah numbers'''
:* '''OEIS:A008297 - Signed Lah numbers'''

;Related Tasks:

:* '''Stirling numbers of the first kind'''
:* '''Stirling numbers of the second kind'''
:* '''Bell numbers'''

Solution:
#include
#include

uint64_t factorial(uint64_t n) {
    uint64_t res = 1;
    if (n == 0) return res;
    while (n > 0) res *= n--;
    return res;
}

uint64_t lah(uint64_t n, uint64_t k) {
    if (k == 1) return factorial(n);
    if (k == n) return 1;
    if (k > n) return 0;
    if (k < 1 || n < 1) return 0;
    return (factorial(n) * factorial(n - 1)) / (factorial(k) * factorial(k - 1)) / factorial(n - k);
}

int main() {
    int row, i;

    printf("Unsigned Lah numbers: L(n, k):\n");
    printf("n/k ");
    for (i = 0; i < 13; i++) {
        printf("%10d ", i);
    }
    printf("\n");
    for (row = 0; row < 13; row++) {
        printf("%-3d", row);
        for (i = 0; i < row + 1; i++) {
            uint64_t l = lah(row, i);
            printf("%11lld", l);
        }
        printf("\n");
    }

    return 0;
}


Lah numbers

Solution:
from math import (comb,
                  factorial)

def lah(n, k):
    if k == 1:
        return factorial(n)
    if k == n:
        return 1
    if k > n:
        return 0
    if k < 1 or n < 1:
        return 0
    return comb(n, k) * factorial(n - 1) // factorial(k - 1)

def main():
    print("Unsigned Lah numbers: L(n, k):")
    print("n/k ", end='\t')
    for i in range(13):
        print("%11d" % i, end='\t')
    print()
    for row in range(13):
        print("%-4d" % row, end='\t')
        for i in range(row + 1):
            l = lah(row, i)
            print("%11d" % l, end='\t')
        print()
    print("\nMaximum value from the L(100, *) row:")
    max_val = max(lah(100, a) for a in range(100))
    print(max_val)

if __name__ == '__main__':
    main()


Largest int from concatenated ints

;Task:
Given a set of positive integers, write a function to order the integers in such a way that the concatenation of the numbers forms the largest possible integer and return this integer.

Use the following two sets of integers as tests   and   show your program output here.

:::::*   {1, 34, 3, 98, 9, 76, 45, 4}
:::::*   {54, 546, 548, 60}

;Possible algorithms:
# A solution could be found by trying all combinations and return the best.
# Another way to solve this is to note that in the best arrangement, for any two adjacent original integers '''X''' and '''Y''', the concatenation '''X''' followed by '''Y''' will be numerically greater than or equal to the concatenation '''Y''' followed by '''X.
# Yet another way to solve this is to pad the integers to the same size by repeating the digits then sort using these repeated integers as a sort key.

;See also:
*   [http://www.quora.com/Algorithms/What-is-the-most-efficient-way-to-arrange-the-given-numbers-to-form-the-biggest-number Algorithms: What is the most efficient way to arrange the given numbers to form the biggest number?]
*   [http://stackoverflow.com/questions/14532105/constructing-the-largest-number-possible-by-rearranging-a-list/14539943#14539943 Constructing the largest number possible by rearranging a list]

Solution:
#include
#include
#include

int catcmp(const void *a, const void *b)
{
	char ab[32], ba[32];
	sprintf(ab, "%d%d", *(int*)a, *(int*)b);
	sprintf(ba, "%d%d", *(int*)b, *(int*)a);
	return strcmp(ba, ab);
}

void maxcat(int *a, int len)
{
	int i;
	qsort(a, len, sizeof(int), catcmp);
	for (i = 0; i < len; i++)
		printf("%d", a[i]);
	putchar('\n');
}

int main(void)
{
	int x[] = {1, 34, 3, 98, 9, 76, 45, 4};
	int y[] = {54, 546, 548, 60};

	maxcat(x, sizeof(x)/sizeof(x[0]));
	maxcat(y, sizeof(y)/sizeof(y[0]));

	return 0;
}


Largest int from concatenated ints

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

     // maxCombine :: [Int] -> Int
     function maxCombine(xs) {
         return parseInt(
             xs.sort(
                 function (x, y) {
                     var a = x.toString(),
                         b = y.toString(),
                         ab = parseInt(a + b),
                         ba = parseInt(b + a);

                     return ab > ba ? -1 : (ab < ba ? 1 : 0);
                 }
             )
             .join(''), 10
         );
     }

     return [
        [1, 34, 3, 98, 9, 76, 45, 4],
        [54, 546, 548, 60]
     ].map(maxCombine);

 })();


Largest int from concatenated ints

Solution:
try:
    cmp     # Python 2 OK or NameError in Python 3
    def maxnum(x):
        return ''.join(sorted((str(n) for n in x),
                              cmp=lambda x,y:cmp(y+x, x+y)))
except NameError:
    # Python 3
    from functools import cmp_to_key
    def cmp(x, y):
        return -1 if x


Largest number divisible by its digits

;Task:
Find the largest base 10 integer whose digits are all different,   and   is evenly divisible by each of its individual digits.

These numbers are also known as   '''Lynch-Bell numbers''',   numbers   '''n'''   such that the
(base ten) digits are all different (and do not include zero)   and   '''n'''   is divisible by each of its individual digits.

;Example:
'''135'''   is evenly divisible by   '''1''',   '''3''',   and   '''5'''.

Note that the digit zero (0) can not be in the number as integer division by zero is undefined.

The digits must all be unique so a base ten number will have at most '''9''' digits.

Feel free to use analytics and clever algorithms to reduce the search space your example needs to visit, but it must do an actual search. (Don't just feed it the answer and verify it is correct.)

;Stretch goal:
Do the same thing for hexadecimal.

;Related tasks:
:*   [https://rosettacode.org/wiki/Gapful_numbers gapful numbers].
:*   [https://rosettacode.org/wiki/Palindromic_gapful_numbers palindromic gapful numbers].

;Also see:
:*   The OEIS sequence:   [http://oeis.org/A115569 A115569: Lynch-Bell numbers].

Solution:
#include
#include

#define TRUE 1
#define FALSE 0

typedef char bool;

typedef unsigned long long uint64;

bool div_by_all(uint64 num, char digits[], int len) {
    int i, d;
    for (i = 0; i < len; ++i) {
        d = digits[i];
        d = (d <= '9') ? d - '0' : d - 'W';
        if (num % d != 0) return FALSE;
    }
    return TRUE;
}

int main() {
    uint64 i, magic = 15 * 14 * 13 * 12 * 11;
    uint64 high = 0xfedcba987654321 / magic * magic;
    int j, len;
    char c, *p, s[17], sd[16], found[16];

    for (i = high; i >= magic; i -= magic) {
        if (i % 16 == 0) continue;   // can't end in '0'
        snprintf(s, 17, "%llx", i);  // always generates lower case a-f
        if (strchr(s, '0') - s >= 0) continue; // can't contain '0'
        for (j = 0; j < 16; ++j) found[j] = FALSE;
        len = 0;
        for (p = s; *p; ++p) {
            if (*p <= '9') {
                c = *p - '0';
            } else {
                c = *p - 87;
            }
            if (!found[c]) {
                found[c] = TRUE;
                sd[len++] = *p;
            }
        }
        if (len != p - s) {
            continue;  // digits must be unique
        }
        if (div_by_all(i, sd, len)) {
            printf("Largest hex number is %llx\n", i);
            break;
        }
    }
    return 0;
}


Largest number divisible by its digits

Solution:
===base 10===
Using the insights presented in the preamble to the Raku (base 10) example:


Largest number divisible by its digits

Solution:
'''Largest number divisible by its digits'''

from itertools import (chain, permutations)
from functools import (reduce)
from math import (gcd)

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

    # (Division by zero is not an option, so 0 and 5 are omitted)
    digits = [1, 2, 3, 4, 6, 7, 8, 9]

    # Least common multiple of the digits above
    lcmDigits = reduce(lcm, digits)

    # Any 7 items drawn from the digits above,
    # including any two of [1, 4, 7]
    sevenDigits = ((delete)(digits)(x) for x in [1, 4, 7])

    print(
        max(
            (
                intFromDigits(x) for x
                in concatMap(permutations)(sevenDigits)
            ),
            key=lambda n: n if 0 == n % lcmDigits else 0
        )
    )

# intFromDigits :: [Int] -> Int
def intFromDigits(xs):
    '''An integer derived from an
       ordered list of digits.
    '''
    return reduce(lambda a, x: a * 10 + x, xs, 0)

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

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

# delete :: Eq a => [a] -> a -> [a]
def delete(xs):
    '''xs with the first instance of
       x removed.
    '''
    def go(x):
        ys = xs.copy()
        ys.remove(x)
        return ys
    return go

# lcm :: Int -> Int -> Int
def lcm(x, y):
    '''The smallest positive integer divisible
       without remainder by both x and y.
    '''
    return 0 if (0 == x or 0 == y) else abs(
        y * (x // gcd(x, y))
    )

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


Last Friday of each month

[[Category:Date and time]]

;Task:
Write a program or a script that returns the date of the last Fridays of each month of a given year.

The year may be given through any simple input method in your language (command line, std in, etc).

Example of an expected output:
./last_fridays 2012
2012-01-27
2012-02-24
2012-03-30
2012-04-27
2012-05-25
2012-06-29
2012-07-27
2012-08-31
2012-09-28
2012-10-26
2012-11-30
2012-12-28

;Related tasks
* [[Five weekends]]
* [[Day of the week]]
* [[Find the last Sunday of each month]]

Solution:
#include
#include

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

	if (c < 2 || (y = atoi(v[1])) <= 1700) return 1;
 	days[1] -= (y % 4) || (!(y % 100) && (y % 400));
	w = y * 365 + (y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400 + 6;

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

	return 0;
}


Last Friday of each month

Solution:
var last_friday_of_month, print_last_fridays_of_month;

last_friday_of_month = function(year, month) {
  var i, last_day;
  i = 0;
  while (true) {
    last_day = new Date(year, month, i);
    if (last_day.getDay() === 5) {
      return last_day.toDateString();
    }
    i -= 1;
  }
};

print_last_fridays_of_month = function(year) {
  var month, results;
  results = [];
  for (month = 1; month <= 12; ++month) {
    results.push(console.log(last_friday_of_month(year, month)));
  }
  return results;
};

(function() {
  var year;
  year = parseInt(process.argv[2]);
  return print_last_fridays_of_month(year);
})();


Last Friday of each month

Solution:
import calendar

def last_fridays(year):
    for month in range(1, 13):
        last_friday = max(week[calendar.FRIDAY]
            for week in calendar.monthcalendar(year, month))
        print('{:4d}-{:02d}-{:02d}'.format(year, month, last_friday))


Last letter-first letter

A certain children's game involves starting with a word in a particular category.   Each participant in turn says a word, but that word must begin with the final letter of the previous word.   Once a word has been given, it cannot be repeated.   If an opponent cannot give a word in the category, they fall out of the game.

For example, with   "animals"   as the category,

Child 1: dog
Child 2: goldfish
Child 1: hippopotamus
Child 2: snake
...

;Task:
Take the following selection of 70 English Pokemon names   (extracted from   Wikipedia's list of Pokemon)   and generate the/a sequence with the highest possible number of Pokemon names where the subsequent name starts with the final letter of the preceding name.

No Pokemon name is to be repeated.

audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine
nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko
tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask

Extra brownie points for dealing with the full list of   646   names.

Solution:
#include
#include
#include
#include

#define forall(i, n) for (int i = 0; i < n; i++)
typedef struct edge { char s, e, *str; struct edge *lnk; } edge;
typedef struct { edge* e[26]; int nin, nout, in[26], out[26];} node;
typedef struct { edge *e, *tail; int len, has[26]; } chain;

node nodes[26];
edge *names, **tmp;
int n_names;

/* add edge to graph */
void store_edge(edge *g)
{
	if (!g) return;
	int i = g->e, j = g->s;
	node *n = nodes + j;

	g->lnk = n->e[i];

	n->e[i] = g, n->out[i]++, n->nout++;
	n = nodes + i, n->in[j]++, n->nin++;
}

/* unlink an edge between nodes i and j, and return the edge */
edge* remove_edge(int i, int j)
{
	node *n = nodes + i;
	edge *g = n->e[j];
	if (g) {
		n->e[j] = g->lnk;
		g->lnk = 0;
		n->out[j]--, n->nout--;

		n = nodes + j;
		n->in[i]--;
		n->nin--;
	}
	return g;
}

void read_names()
{
	FILE *fp = fopen("poke646", "rt");
	int i, len;
	char *buf;
	edge *p;

	if (!fp) abort();

	fseek(fp, 0, SEEK_END);
	len = ftell(fp);
	buf = malloc(len + 1);
	fseek(fp, 0, SEEK_SET);
	fread(buf, 1, len, fp);
	fclose(fp);

	buf[len] = 0;
	for (n_names = i = 0; i < len; i++)
		if (isspace(buf[i]))
			buf[i] = 0, n_names++;

	if (buf[len-1]) n_names++;

	memset(nodes, 0, sizeof(node) * 26);
	tmp = calloc(n_names, sizeof(edge*));

	p = names = malloc(sizeof(edge) * n_names);
	for (i = 0; i < n_names; i++, p++) {
		if (i)	p->str = names[i-1].str + len + 1;
		else	p->str = buf;

		len = strlen(p->str);
		p->s = p->str[0] - 'a';
		p->e = p->str[len-1] - 'a';
		if (p->s < 0 || p->s >= 26 || p->e < 0 || p->e >= 26) {
			printf("bad name %s: first/last char must be letter\n",
				p->str);
			abort();
		}
	}
	printf("read %d names\n", n_names);
}

void show_chain(chain *c)
{
	printf("%d:", c->len);
	for (edge * e = c->e; e || !putchar('\n'); e = e->lnk)
		printf(" %s", e->str);
}

/* Which next node has most enter or exit edges. */
int widest(int n, int out)
{
	if (nodes[n].out[n]) return n;

	int mm = -1, mi = -1;
	forall(i, 26) {
		if (out) {
			if (nodes[n].out[i] && nodes[i].nout > mm)
				mi = i, mm = nodes[i].nout;
		} else {
			if (nodes[i].out[n] && nodes[i].nin > mm)
				mi = i, mm = nodes[i].nin;
		}
	}

	return mi;
}

void insert(chain *c, edge *e)
{
	e->lnk = c->e;
	if (!c->tail) c->tail = e;
	c->e = e;
	c->len++;
}

void append(chain *c, edge *e)
{
	if (c->tail) c->tail->lnk = e;
	else c->e = e;
	c->tail = e;
	c->len++;
}

edge * shift(chain *c)
{
	edge *e = c->e;
	if (e) {
		c->e = e->lnk;
		if (!--c->len) c->tail = 0;
	}
	return e;
}

chain* make_chain(int s)
{
	chain *c = calloc(1, sizeof(chain));

	/* extend backwards */
	for (int i, j = s; (i = widest(j, 0)) >= 0; j = i)
		insert(c, remove_edge(i, j));

	/* extend forwards */
	for (int i, j = s; (i = widest(j, 1)) >= 0; j = i)
		append(c, remove_edge(j, i));

	for (int step = 0;; step++) {
		edge *e = c->e;

		for (int i = 0; i < step; i++)
			if (!(e = e->lnk)) break;
		if (!e) return c;

		int n = 0;
		for (int i, j = e->s; (i = widest(j, 0)) >= 0; j = i) {
			if (!(e = remove_edge(i, j))) break;
			tmp[n++] = e;
		}

		if (n > step) {
			forall(i, step) store_edge(shift(c));
			forall(i, n) insert(c, tmp[i]);
			step = -1;
		} else while (--n >= 0)
			store_edge(tmp[n]);
	}
	return c;
}

int main(void)
{
	int best = 0;
	read_names();

	forall(i, 26) {
		/* rebuild the graph */
		memset(nodes, 0, sizeof(nodes));
		forall(j, n_names) store_edge(names + j);

		/* make a chain from node i */
		chain *c = make_chain(i);
		if (c->len > best) {
			show_chain(c);
			best = c->len;
		}
		free(c);
	}

	printf("longest found: %d\n", best);
	return 0;
}


Last letter-first letter

Solution:
/**
 * Find the letter the word ends on
 * @param {string} word
 * @returns {string}
 */
const endsWith = word => word[word.length - 1];

/**
 * Remove the used elements from the candidate elements
 * @param {Array} words Candidate words
 * @param {Array} used Used words
 * @returns {*}
 */
const getCandidates = (words, used) => words.filter(e => !used.includes(e));

/**
 * Build a map of letters to words that start with that letter
 * @param {Array} words
 * @returns {Map>}
 */
const buildLookup = words => {
  const lookup = new Map();
  words.forEach(e => {
    const start = e[0];
    lookup.set(start, [...(lookup.get(start) || []), e]);
  });
  return lookup;
};

/**
 * Main function
 * @param {Array} names
 */
const findPaths = names => {
  const t0 = process.hrtime();
  console.log('Checking:', names.length, 'names');
  const lookup = buildLookup(names);

  let maxNum = 0;
  let maxPaths = [];

  const parseResult = arr => {
    if (typeof arr[0] === 'object') {
      arr.forEach(el => parseResult(el))
    } else {
      if (arr.length > maxNum) {
        maxNum = arr.length;
        maxPaths = [arr];
      }
      if (arr.length === maxNum) {
        maxPaths.push(arr)
      }
    }
  };

  const searchWords = (word, res) => {
    const cs = getCandidates(lookup.get(endsWith(word)) || [], res);
    return cs.length ? cs.map(e => searchWords(e, [...res, e])) : res;
  };

  names.forEach(word => {
    const res = searchWords(word, [word]);
    parseResult(res);
  });

  const t1 = process.hrtime(t0);
  console.info('Execution time (hr): %ds %dms', t1[0], t1[1] / 1000000);
  console.log('Max Path:', maxNum);
  console.log('Matching Paths:', maxPaths.length);
  console.log('Example Path:', maxPaths[0]);

};

const pokimon = ["audino", "bagon", "baltoy", "banette",
  "bidoof", "braviary", "bronzor", "carracosta", "charmeleon",
  "cresselia", "croagunk", "darmanitan", "deino", "emboar",
  "emolga", "exeggcute", "gabite", "girafarig", "gulpin",
  "haxorus", "heatmor", "heatran", "ivysaur", "jellicent",
  "jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba",
  "loudred", "lumineon", "lunatone", "machamp", "magnezone",
  "mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu",
  "pinsir", "poliwrath", "poochyena", "porygon2", "porygonz",
  "registeel", "relicanth", "remoraid", "rufflet", "sableye",
  "scolipede", "scrafty", "seaking", "sealeo", "silcoon",
  "simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga",
  "trapinch", "treecko", "tyrogue", "vigoroth", "vulpix",
  "wailord", "wartortle", "whismur", "wingull", "yamask"];

findPaths(pokimon);


Last letter-first letter

Solution:
import psyco

nsolutions = 0

def search(sequences, ord_minc, curr_word, current_path,
           current_path_len, longest_path):
    global nsolutions

    current_path[current_path_len] = curr_word
    current_path_len += 1

    if current_path_len == len(longest_path):
        nsolutions += 1
    elif current_path_len > len(longest_path):
        nsolutions = 1
        longest_path[:] = current_path[:current_path_len]

    # recursive search
    last_char_index = ord(curr_word[-1]) - ord_minc
    if last_char_index >= 0 and last_char_index < len(sequences):
        for pair in sequences[last_char_index]:
            if not pair[1]:
                pair[1] = True
                search(sequences, ord_minc, pair[0], current_path,
                       current_path_len, longest_path)
                pair[1] = False

def find_longest_chain(words):
    ord_minc = ord(min(word[0] for word in words))
    ord_maxc = ord(max(word[0] for word in words))
    sequences = [[] for _ in xrange(ord_maxc - ord_minc + 1)]
    for word in words:
        sequences[ord(word[0]) - ord_minc].append([word, False])

    current_path = [None] * len(words)
    longest_path = []

    # try each item as possible start
    for seq in sequences:
        for pair in seq:
            pair[1] = True
            search(sequences, ord_minc, pair[0],
                   current_path, 0, longest_path)
            pair[1] = False

    return longest_path

def main():
    global nsolutions

    pokemon = """audino bagon baltoy banette bidoof braviary
bronzor carracosta charmeleon cresselia croagunk darmanitan deino
emboar emolga exeggcute gabite girafarig gulpin haxorus heatmor
heatran ivysaur jellicent jumpluff kangaskhan kricketune landorus
ledyba loudred lumineon lunatone machamp magnezone mamoswine nosepass
petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede
scrafty seaking sealeo silcoon simisear snivy snorlax spoink starly
tirtouga trapinch treecko tyrogue vigoroth vulpix wailord wartortle
whismur wingull yamask""".lower().split()

    # remove duplicates
    pokemon = sorted(set(pokemon))

    sol = find_longest_chain(pokemon)
    print "Maximum path length:", len(sol)
    print "Paths of that length:", nsolutions
    print "Example path of that length:"
    for i in xrange(0, len(sol), 7):
        print " ", " ".join(sol[i : i+7])

psyco.full()
main()


Latin Squares in reduced form

A Latin Square is in its reduced form if the first row and first column contain items in their natural order. The order n is the number of items. For any given n there is a set of reduced Latin Squares whose size increases rapidly with n. g is a number which identifies a unique element within the set of reduced Latin Squares of order n. The objective of this task is to construct the set of all Latin Squares of a given order and to provide a means which given suitable values for g any element within the set may be obtained.

For a reduced Latin Square the first row is always 1 to n. The second row is all [[Permutations/Derangements]] of 1 to n starting with 2. The third row is all [[Permutations/Derangements]] of 1 to n starting with 3 which do not clash (do not have the same item in any column) with row 2. The fourth row is all [[Permutations/Derangements]] of 1 to n starting with 4 which do not clash with rows 2 or 3. Likewise continuing to the nth row.

Demonstrate by:
* displaying the four reduced Latin Squares of order 4.
* for n = 1 to 6 (or more) produce the set of reduced Latin Squares; produce a table which shows the size of the set of reduced Latin Squares and compares this value times n! times (n-1)! with the values in OEIS A002860.

Solution:
def dList(n, start):
    start -= 1 # use 0 basing
    a = range(n)
    a[start] = a[0]
    a[0] = start
    a[1:] = sorted(a[1:])
    first = a[1]
    # rescursive closure permutes a[1:]
    r = []
    def recurse(last):
        if (last == first):
            # bottom of recursion. you get here once for each permutation.
            # test if permutation is deranged.
            # yes, save a copy with 1 based indexing
            for j,v in enumerate(a[1:]):
                if j + 1 == v:
                    return # no, ignore it
            b = [x + 1 for x in a]
            r.append(b)
            return
        for i in xrange(last, 0, -1):
            a[i], a[last] = a[last], a[i]
            recurse(last - 1)
            a[i], a[last] = a[last], a[i]
    recurse(n - 1)
    return r

def printSquare(latin,n):
    for row in latin:
        print row
    print

def reducedLatinSquares(n,echo):
    if n <= 0:
        if echo:
            print []
        return 0
    elif n == 1:
        if echo:
            print [1]
        return 1

    rlatin = [None] * n
    for i in xrange(n):
        rlatin[i] = [None] * n
    # first row
    for j in xrange(0, n):
        rlatin[0][j] = j + 1

    class OuterScope:
        count = 0
    def recurse(i):
        rows = dList(n, i)

        for r in xrange(len(rows)):
            rlatin[i - 1] = rows[r]
            justContinue = False
            k = 0
            while not justContinue and k < i - 1:
                for j in xrange(1, n):
                    if rlatin[k][j] == rlatin[i - 1][j]:
                        if r < len(rows) - 1:
                            justContinue = True
                            break
                        if i > 2:
                            return
                k += 1
            if not justContinue:
                if i < n:
                    recurse(i + 1)
                else:
                    OuterScope.count += 1
                    if echo:
                        printSquare(rlatin, n)

    # remaining rows
    recurse(2)
    return OuterScope.count

def factorial(n):
    if n == 0:
        return 1
    prod = 1
    for i in xrange(2, n + 1):
        prod *= i
    return prod

print "The four reduced latin squares of order 4 are:\n"
reducedLatinSquares(4,True)

print "The size of the set of reduced latin squares for the following orders"
print "and hence the total number of latin squares of these orders are:\n"
for n in xrange(1, 7):
    size = reducedLatinSquares(n, False)
    f = factorial(n - 1)
    f *= f * n * size
    print "Order %d: Size %-4d x %d! x %d! => Total %d" % (n, size, n, n - 1, f)


Law of cosines - triples

The [https://en.wikipedia.org/wiki/Law_of_cosines Law of cosines] states that for an angle γ, (gamma) of any triangle, if the sides adjacent to the angle are A and B and the side opposite is C; then the lengths of the sides are related by this formula:
           A2 + B2 - 2ABcos(γ) = C2

;Specific angles:
For an angle of of   '''90º'''   this becomes the more familiar "Pythagoras equation":
           A2 + B2  =  C2

For an angle of   '''60º'''   this becomes the less familiar  equation:
           A2 + B2 - AB  =  C2

And finally for an angle of   '''120º'''   this becomes the equation:
           A2 + B2 + AB  =  C2

;Task:
*   Find all integer solutions (in order) to the three specific cases, distinguishing between each angle being considered.
*   Restrain all sides to the integers   '''1..13'''   inclusive.
*   Show how many results there are for each of the three angles mentioned above.
*   Display results on this page.

Note: Triangles with the same length sides but different order are to be treated as the same.

;Optional Extra credit:
* How many 60° integer triples are there for sides in the range 1..10_000 ''where the sides are not all of the same length''.

;Related Task
* [[Pythagorean triples]]

;See also:
* [https://youtu.be/p-0SOWbzUYI?t=12m11s Visualising Pythagoras: ultimate proofs and crazy contortions] Mathlogger Video

Solution:
/*
 * RossetaCode: Law of cosines - triples
 *
 * An quick and dirty brute force solutions with O(N^3) cost.
 * Anyway it is possible set MAX_SIDE_LENGTH equal to 10000
 * and use fast computer to obtain the "extra credit" badge.
 *
 * Obviously, there are better algorithms.
 */

#include
#include

#define MAX_SIDE_LENGTH 13
//#define DISPLAY_TRIANGLES 1

int main(void)
{
    static char description[3][80] = {
        "gamma =  90 degrees,  a*a + b*b       == c*c",
        "gamma =  60 degrees,  a*a + b*b - a*b == c*c",
        "gamma = 120 degrees,  a*a + b*b + a*b == c*c"
    };
    static int coeff[3] = { 0, 1, -1 };

    for (int k = 0; k < 3; k++)
    {
        int counter = 0;
        for (int a = 1; a <= MAX_SIDE_LENGTH; a++)
            for (int b = 1; b <= a; b++)
                for (int c = 1; c <= MAX_SIDE_LENGTH; c++)
                    if (a * a + b * b - coeff[k] * a * b == c * c)
                    {
                        counter++;
#ifdef DISPLAY_TRIANGLES
                        printf("  %d  %d  %d\n", a, b, c);
#endif
                    }
        printf("%s,  number of triangles = %d\n", description[k], counter);
    }

    return 0;
}


Law of cosines - triples

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

    // main :: IO ()
    const main = () => {

        const
            f90 = dct => x2 => dct[x2],
            f60 = dct => (x2, ab) => dct[x2 - ab],
            f120 = dct => (x2, ab) => dct[x2 + ab],
            f60unequal = dct => (x2, ab, a, b) =>
            (a !== b) ? (
                dct[x2 - ab]
            ) : undefined;

        // triangles :: Dict -> (Int -> Int -> Int -> Int -> Maybe Int)
        //                   -> [String]
        const triangles = (f, n) => {
            const
                xs = enumFromTo(1, n),
                fr = f(xs.reduce((a, x) => (a[x * x] = x, a), {})),
                gc = xs.reduce((a, _) => a, {}),
                setSoln = new Set();
            return (
                xs.forEach(
                    a => {
                        const a2 = a * a;
                        enumFromTo(1, 1 + a).forEach(
                            b => {
                                const
                                    suma2b2 = a2 + b * b,
                                    c = fr(suma2b2, a * b, a, b);
                                if (undefined !== c) {
                                    setSoln.add([a, b, c].sort())
                                };
                            }
                        );
                    }
                ),
                Array.from(setSoln.keys())
            );
        };

        const
            result = 'Triangles of maximum side 13:\n\n' +
            unlines(
                zipWith(
                    (s, f) => {
                        const ks = triangles(f, 13);
                        return ks.length.toString() + ' solutions for ' + s +
                            ' degrees:\n' + unlines(ks) + '\n';
                    },
                    ['120', '90', '60'],
                    [f120, f90, f60]
                )
            ) + '\nUneven triangles of maximum side 10000. Total:\n' +
            triangles(f60unequal, 10000).length

        return (
            //console.log(result),
            result
        );
    };

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

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

    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = (m, n) =>
        m <= n ? iterateUntil(
            x => n <= x,
            x => 1 + x,
            m
        ) : [];

    // iterateUntil :: (a -> Bool) -> (a -> a) -> a -> [a]
    const iterateUntil = (p, f, x) => {
        const vs = [x];
        let h = x;
        while (!p(h))(h = f(h), vs.push(h));
        return vs;
    };

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

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

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = (n, xs) =>
        xs.constructor.constructor.name !== 'GeneratorFunction' ? (
            xs.slice(0, n)
        ) : [].concat.apply([], Array.from({
            length: n
        }, () => {
            const x = xs.next();
            return x.done ? [] : [x.value];
        }));

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

    // Use of `take` and `length` here allows zipping with non-finite lists
    // i.e. generators like cycle, repeat, iterate.

    // Use of `take` and `length` here allows zipping with non-finite lists
    // i.e. generators like cycle, repeat, iterate.

    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = (f, xs, ys) => {
        const
            lng = Math.min(length(xs), length(ys)),
            as = take(lng, xs),
            bs = take(lng, ys);
        return Array.from({
            length: lng
        }, (_, i) => f(as[i], bs[i], i));
    };

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


Law of cosines - triples

Solution:
N = 13

def method1(N=N):
    squares = [x**2 for x in range(0, N+1)]
    sqrset = set(squares)
    tri90, tri60, tri120 = (set() for _ in range(3))
    for a in range(1, N+1):
        a2 = squares[a]
        for b in range(1, a + 1):
            b2 = squares[b]
            c2 = a2 + b2
            if c2 in sqrset:
                tri90.add(tuple(sorted((a, b, int(c2**0.5)))))
            ab = a * b
            c2 -= ab
            if c2 in sqrset:
                tri60.add(tuple(sorted((a, b, int(c2**0.5)))))
            c2 += 2 * ab
            if c2 in sqrset:
                tri120.add(tuple(sorted((a, b, int(c2**0.5)))))
    return  sorted(tri90), sorted(tri60), sorted(tri120)
#%%
if __name__ == '__main__':
    print(f'Integer triangular triples for sides 1..{N}:')
    for angle, triples in zip([90, 60, 120], method1(N)):
        print(f'  {angle:3}° has {len(triples)} solutions:\n    {triples}')
    _, t60, _ = method1(10_000)
    notsame = sum(1 for a, b, c in t60 if a != b or b != c)
    print('Extra credit:', notsame)


Least common multiple

;Task:
Compute the   least common multiple   (LCM)   of two integers.

Given   ''m''   and   ''n'',   the least common multiple is the smallest positive integer that has both   ''m''   and   ''n''   as factors.

;Example:
The least common multiple of   '''12'''   and   '''18'''   is   '''36''',       because:
:*   '''12'''   is a factor     ('''12''' × '''3''' = '''36'''),     and
:*   '''18'''   is a factor     ('''18''' × '''2''' = '''36'''),     and
:*   there is no positive integer less than   '''36'''   that has both factors.

As a special case,   if either   ''m''   or   ''n''   is zero,   then the least common multiple is zero.

One way to calculate the least common multiple is to iterate all the multiples of   ''m'',   until you find one that is also a multiple of   ''n''.

If you already have   ''gcd''   for [[greatest common divisor]],   then this formula calculates   ''lcm''.

:::: \operatorname{lcm}(m, n) = \frac{|m \times n|}{\operatorname{gcd}(m, n)}

One can also find   ''lcm''   by merging the [[prime decomposition]]s of both   ''m''   and   ''n''.

;Related task
:*   [https://rosettacode.org/wiki/Greatest_common_divisor greatest common divisor].

;See also:
*   MathWorld entry:   [http://mathworld.wolfram.com/LeastCommonMultiple.html Least Common Multiple].
*   Wikipedia entry:   Least common multiple.

Solution:
#include

int gcd(int m, int n)
{
        int tmp;
        while(m) { tmp = m; m = n % m; n = tmp; }
        return n;
}

int lcm(int m, int n)
{
        return m / gcd(m, n) * n;
}

int main()
{
        printf("lcm(35, 21) = %d\n", lcm(21,35));
        return 0;
}


Least common multiple

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

    // gcd :: Integral a => a -> a -> a
    let gcd = (x, y) => {
        let _gcd = (a, b) => (b === 0 ? a : _gcd(b, a % b)),
            abs = Math.abs;
        return _gcd(abs(x), abs(y));
    }

    // lcm :: Integral a => a -> a -> a
    let lcm = (x, y) =>
        x === 0 || y === 0 ? 0 : Math.abs(Math.floor(x / gcd(x, y)) * y);

    // TEST
    return lcm(12, 18);

})();


Least common multiple

Solution:
'''Least common multiple'''

from inspect import signature

# lcm :: Int -> Int -> Int
def lcm(x):
    '''The smallest positive integer divisible
       without remainder by both x and y.
    '''
    return lambda y: 0 if 0 in (x, y) else abs(
        y * (x // gcd_(x)(y))
    )

# gcd_ :: Int -> Int -> Int
def gcd_(x):
    '''The greatest common divisor in terms of
       the divisibility preordering.
    '''
    def go(a, b):
        return go(b, a % b) if 0 != b else a
    return lambda y: go(abs(x), abs(y))

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

    print(
        fTable(
            __doc__ + 's of 60 and [12..20]:'
        )(repr)(repr)(
            lcm(60)
        )(enumFromTo(12)(20))
    )

    pairs = [(0, 2), (2, 0), (-6, 14), (12, 18)]
    print(
        fTable(
            '\n\n' + __doc__ + 's of ' + repr(pairs) + ':'
        )(repr)(repr)(
            uncurry(lcm)
        )(pairs)
    )

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

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

# uncurry :: (a -> b -> c) -> ((a, b) -> c)
def uncurry(f):
    '''A function over a tuple, derived from
       a vanilla or curried function.
    '''
    if 1 < len(signature(f).parameters):
        return lambda xy: f(*xy)
    else:
        return lambda xy: f(xy[0])(xy[1])

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

# FORMATTING ----------------------------------------------

# 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 go(xShow, fxShow, f, xs):
        ys = [xShow(x) for x in xs]
        w = max(map(len, ys))
        return s + '\n' + '\n'.join(map(
            lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)),
            xs, ys
        ))
    return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
        xShow, fxShow, f, xs
    )

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


Left factorials

[[Category:Mathematics]]

'''Left factorials''',   !n,   may refer to either   ''subfactorials''   or to   ''factorial sums'';
the same notation can be confusingly seen being used for the two different definitions.

Sometimes,   ''subfactorials''   (also known as ''derangements'')   may use any of the notations:
:::::::*     !''n''`
:::::::*     !''n''
:::::::*     ''n''¡

(It may not be visually obvious, but the last example uses an upside-down exclamation mark.)

This Rosetta Code task will be using this formula   (''factorial sums'')   for   '''left factorial''':

:::::    !n = \sum_{k=0}^{n-1} k!

:::: where

:::::   !0 = 0

;Task
Display the left factorials for:
*   zero      through        ten     (inclusive)
*   20   through   110          (inclusive)   by tens

Display the length (in decimal digits) of the left factorials for:
*   1,000   through   10,000   (inclusive), by thousands.

;Also see:
*   The OEIS entry: [http://oeis.org/A003422 A003422 left factorials]
*   The MathWorld entry: [http://mathworld.wolfram.com/LeftFactorial.html left factorial]
*   The MathWorld entry: [http://mathworld.wolfram.com/FactorialSums.html factorial sums]
*   The MathWorld entry: [http://mathworld.wolfram.com/Subfactorial.html subfactorial]

;Related task:
*   [http://rosettacode.org/wiki/Permutations/Derangements permutations/derangements (subfactorials)]

Solution:
#include
#include
#include
#include

void mpz_left_fac_ui(mpz_t rop, unsigned long op)
{
    mpz_t t1;
    mpz_init_set_ui(t1, 1);
    mpz_set_ui(rop, 0);

    size_t i;
    for (i = 1; i <= op; ++i) {
        mpz_add(rop, rop, t1);
        mpz_mul_ui(t1, t1, i);
    }

    mpz_clear(t1);
}

size_t mpz_digitcount(mpz_t op)
{
    /* mpz_sizeinbase can not be trusted to give accurate base 10 length */
    char *t    = mpz_get_str(NULL, 10, op);
    size_t ret = strlen(t);
    free(t);
    return ret;
}

int main(void)
{
    mpz_t t;
    mpz_init(t);
    size_t i;

    for (i = 0; i <= 110; ++i) {
        if (i <= 10 || i % 10 == 0) {
            mpz_left_fac_ui(t, i);
            gmp_printf("!%u = %Zd\n", i, t);
        }
    }

    for (i = 1000; i <= 10000; i += 1000) {
        mpz_left_fac_ui(t, i);
        printf("!%u has %u digits\n", i, mpz_digitcount(t));
    }

    mpz_clear(t);
    return 0;
}


Left factorials

Solution:
from itertools import islice

def lfact():
    yield 0
    fact, summ, n = 1, 0, 1
    while 1:
        fact, summ, n = fact*n, summ + fact, n + 1
        yield summ

print('first 11:\n  %r' % [lf for i, lf in zip(range(11), lfact())])
print('20 through 110 (inclusive) by tens:')
for lf in islice(lfact(), 20, 111, 10):
    print(lf)
print('Digits in 1,000 through 10,000 (inclusive) by thousands:\n  %r'
      % [len(str(lf)) for lf in islice(lfact(), 1000, 10001, 1000)] )


Levenshtein distance

In information theory and computer science, the '''Levenshtein distance''' is a edit distance). The Levenshtein distance between two strings is defined as the minimum number of edits needed to transform one string into the other, with the allowable edit operations being insertion, deletion, or substitution of a single character.

;Example:
The Levenshtein distance between "'''kitten'''" and "'''sitting'''" is 3, since the following three edits change one into the other, and there isn't a way to do it with fewer than three edits:
::#   '''k'''itten    '''s'''itten       (substitution of 'k' with 's')
::#   sitt'''e'''n    sitt'''i'''n       (substitution of 'e' with 'i')
::#   sittin          sittin'''g'''      (insert 'g' at the end).

''The Levenshtein distance between   "'''rosettacode'''",   "'''raisethysword'''"   is   '''8'''.

''The distance between two strings is same as that when both strings are reversed.''

;Task:
Implements a Levenshtein distance function, or uses a library function, to show the Levenshtein distance between   "kitten"   and   "sitting".

;Related task:
*   [[Longest common subsequence]]

Solution:
#include
#include

/* s, t: two strings; ls, lt: their respective length */
int levenshtein(const char *s, int ls, const char *t, int lt)
{
        int a, b, c;

        /* if either string is empty, difference is inserting all chars
         * from the other
         */
        if (!ls) return lt;
        if (!lt) return ls;

        /* if last letters are the same, the difference is whatever is
         * required to edit the rest of the strings
         */
        if (s[ls - 1] == t[lt - 1])
                return levenshtein(s, ls - 1, t, lt - 1);

        /* else try:
         *      changing last letter of s to that of t; or
         *      remove last letter of s; or
         *      remove last letter of t,
         * any of which is 1 edit plus editing the rest of the strings
         */
        a = levenshtein(s, ls - 1, t, lt - 1);
        b = levenshtein(s, ls,     t, lt - 1);
        c = levenshtein(s, ls - 1, t, lt    );

        if (a > b) a = b;
        if (a > c) a = c;

        return a + 1;
}

int main()
{
        const char *s1 = "rosettacode";
        const char *s2 = "raisethysword";
        printf("distance between `%s' and `%s': %d\n", s1, s2,
                levenshtein(s1, strlen(s1), s2, strlen(s2)));

        return 0;
}


Levenshtein distance

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

    // levenshtein :: String -> String -> Int
    const levenshtein = sa => sb => {
        const cs = chars(sa);
        const go = (ns, c) => {
            const calc = z => tpl => {
                const [c1, x, y] = Array.from(tpl);
                return minimum([
                    succ(y),
                    succ(z),
                    x + (c !== c1 ? 1 : 0)
                ]);
            };
            const [n, ns1] = [ns[0], ns.slice(1)];
            return scanl(calc)(succ(n))(
                zip3(cs)(ns)(ns1)
            );
        };
        return last(
            chars(sb).reduce(
                go,
                enumFromTo(0)(cs.length)
            )
        );
    };

    // ----------------------- TEST ------------------------
    const main = () => [
        ["kitten", "sitting"],
        ["sitting", "kitten"],
        ["rosettacode", "raisethysword"],
        ["raisethysword", "rosettacode"]
    ].map(uncurry(levenshtein));

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

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

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

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

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

    // last :: [a] -> a
    const last = xs => (
        // The last item of a list.
        ys => 0 < ys.length ? (
            ys.slice(-1)[0]
        ) : undefined
    )(xs);

    // minimum :: Ord a => [a] -> a
    const minimum = xs => (
        // The least value of xs.
        ys => 0 < ys.length ? (
            ys.slice(1)
            .reduce((a, y) => y < a ? y : a, ys[0])
        ) : undefined
    )(xs);

    // length :: [a] -> Int
    const length = xs =>
        // Returns Infinity over objects without finite
        // length. This enables zip and zipWith to choose
        // the shorter argument when one is non-finite,
        // like cycle, repeat etc
        'GeneratorFunction' !== xs.constructor.constructor.name ? (
            xs.length
        ) : Infinity;

    // scanl :: (b -> a -> b) -> b -> [a] -> [b]
    const scanl = f => startValue => xs =>
        xs.reduce((a, x) => {
            const v = f(a[0])(x);
            return Tuple(v)(a[1].concat(v));
        }, Tuple(startValue)([startValue]))[1];

    // succ :: Enum a => a -> a
    const succ = x =>
        1 + x;

    // uncurry :: (a -> b -> c) -> ((a, b) -> c)
    const uncurry = f =>
        // A function over a pair, derived
        // from a curried function.
        function () {
            const
                args = arguments,
                xy = Boolean(args.length % 2) ? (
                    args[0]
                ) : args;
            return f(xy[0])(xy[1]);
        };

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

    // MAIN ---
    return JSON.stringify(main())
})();


Levenshtein distance

Solution:
def levenshteinDistance(str1, str2):
    m = len(str1)
    n = len(str2)
    d = [[i] for i in range(1, m + 1)]   # d matrix rows
    d.insert(0, list(range(0, n + 1)))   # d matrix columns
    for j in range(1, n + 1):
        for i in range(1, m + 1):
            if str1[i - 1] == str2[j - 1]:   # Python (string) is 0-based
                substitutionCost = 0
            else:
                substitutionCost = 1
            d[i].insert(j, min(d[i - 1][j] + 1,
                               d[i][j - 1] + 1,
                               d[i - 1][j - 1] + substitutionCost))
    return d[-1][-1]

print(levenshteinDistance("kitten","sitting"))
print(levenshteinDistance("rosettacode","raisethysword"))


Levenshtein distance/Alignment

The [[Levenshtein distance]] algorithm returns the number of atomic operations (insertion, deletion or edition) that must be performed on a string in order to obtain an other one, but it does not say anything about the actual operations used or their order.

An alignment is a notation used to describe the operations used to turn a string into an other.  At some point in the strings, the minus character ('-') is placed in order to signify that a character must be added at this very place.  For instance, an alignment between the words 'place' and 'palace' is:

P-LACE
PALACE

;Task:
Write a function that shows the alignment of two strings for the corresponding levenshtein distance.

As an example, use the words "rosettacode" and "raisethysword".

You can either implement an algorithm, or use a dedicated library (thus showing us how it is named in your language).

Solution:
#include
#include
#include

typedef struct edit_s edit_t, *edit;
struct edit_s {
	char c1, c2;
	int n;
	edit next;
};

void leven(char *a, char *b)
{
	int i, j, la = strlen(a), lb = strlen(b);
	edit *tbl = malloc(sizeof(edit) * (1 + la));
	tbl[0] = calloc((1 + la) * (1 + lb), sizeof(edit_t));
	for (i = 1; i <= la; i++)
		tbl[i] = tbl[i-1] + (1+lb);

	for (i = la; i >= 0; i--) {
		char *aa = a + i;
		for (j = lb; j >= 0; j--) {
			char *bb = b + j;
			if (!*aa && !*bb) continue;

			edit e = &tbl[i][j];
			edit repl = &tbl[i+1][j+1];
			edit dela = &tbl[i+1][j];
			edit delb = &tbl[i][j+1];

			e->c1 = *aa;
			e->c2 = *bb;
			if (!*aa) {
				e->next = delb;
				e->n = e->next->n + 1;
				continue;
			}
			if (!*bb) {
				e->next = dela;
				e->n = e->next->n + 1;
				continue;
			}

			e->next = repl;
			if (*aa == *bb) {
				e->n = e->next->n;
				continue;
			}

			if (e->next->n > delb->n) {
				e->next = delb;
				e->c1 = 0;
			}
			if (e->next->n > dela->n) {
				e->next = dela;
				e->c1 = *aa;
				e->c2 = 0;
			}
			e->n = e->next->n + 1;
		}
	}

	edit p = tbl[0];
	printf("%s -> %s: %d edits\n", a, b, p->n);

	while (p->next) {
		if (p->c1 == p->c2)
			printf("%c", p->c1);
		else {
			putchar('(');
			if (p->c1) putchar(p->c1);
			putchar(',');
			if (p->c2) putchar(p->c2);
			putchar(')');
		}

		p = p->next;
	}
	putchar('\n');

	free(tbl[0]);
	free(tbl);
}

int main(void)
{
	leven("raisethysword", "rosettacode");
	return 0;
}


Levenshtein distance/Alignment

Solution:
from difflib import ndiff

def levenshtein(str1, str2):
    result = ""
    pos, removed = 0, 0
    for x in ndiff(str1, str2):
        if pos 0:
            removed -=1
          else:
            result += "-"
    print(result)

levenshtein("place","palace")
levenshtein("rosettacode","raisethysword")


List rooted trees

You came back from grocery shopping.    After putting away all the goods, you are left with a pile of plastic bags, which you want to save for later use, so you take one bag and stuff all the others into it, and throw it under the sink.   In doing so, you realize that there are various ways of nesting the bags, with all bags viewed as identical.

If we use a matching pair of parentheses to represent a bag, the ways are:

For 1 bag, there's one way:
  ()	<- a bag

for 2 bags, there's one way:
  (())	<- one bag in another

for 3 bags, there are two:
  ((())) <- 3 bags nested Russian doll style
  (()()) <- 2 bags side by side, inside the third

for 4 bags, four:
  (()()())
  ((())())
  ((()()))
  (((())))

Note that because all bags are identical, the two 4-bag strings ((())()) and (()(())) represent the same configuration.

It's easy to see that each configuration for ''n'' bags represents a ''n''-node rooted tree, where a bag is a tree node, and a bag with its content forms a subtree.  The outermost bag is the tree root.  Number of configurations for given ''n'' is given by [https://oeis.org/A000081 OEIS A81].

;Task:
Write a program that, when given ''n'', enumerates all ways of nesting ''n'' bags.   You can use the parentheses notation above, or any tree representation that's unambiguous and preferably intuitive.

This task asks for enumeration of trees only; for counting solutions without enumeration, that OEIS page lists various formulas, but that's not encouraged by this task, especially if implementing it would significantly increase code size.

As an example output, run 5 bags.   There should be 9 ways.

Solution:
#include
#include

typedef unsigned int uint;
typedef unsigned long long tree;
#define B(x) (1ULL<<(x))

tree *list = 0;
uint cap = 0, len = 0;
uint offset[32] = {0, 1, 0};

void append(tree t)
{
	if (len == cap) {
		cap = cap ? cap*2 : 2;
		list = realloc(list, cap*sizeof(tree));
	}
	list[len++] = 1 | t<<1;
}

void show(tree t, uint len)
{
	for (; len--; t >>= 1)
		putchar(t&1 ? '(' : ')');
}

void listtrees(uint n)
{
	uint i;
	for (i = offset[n]; i < offset[n+1]; i++) {
		show(list[i], n*2);
		putchar('\n');
	}
}

/* assemble tree from subtrees
	n:   length of tree we want to make
	t:   assembled parts so far
	sl:  length of subtree we are looking at
	pos: offset of subtree we are looking at
	rem: remaining length to be put together
*/
void assemble(uint n, tree t, uint sl, uint pos, uint rem)
{
	if (!rem) {
		append(t);
		return;
	}

	if (sl > rem) // need smaller subtrees
		pos = offset[sl = rem];
	else if (pos >= offset[sl + 1]) {
		// used up sl-trees, try smaller ones
		if (!--sl) return;
		pos = offset[sl];
	}

	assemble(n, t<<(2*sl) | list[pos], sl, pos, rem - sl);
	assemble(n, t, sl, pos + 1, rem);
}

void mktrees(uint n)
{
	if (offset[n + 1]) return;
	if (n) mktrees(n - 1);

	assemble(n, 0, n-1, offset[n-1], n-1);
	offset[n+1] = len;
}

int main(int c, char**v)
{
	int n;
	if (c < 2 || (n = atoi(v[1])) <= 0 || n > 25) n = 5;

	// init 1-tree
	append(0);

	mktrees((uint)n);
	fprintf(stderr, "Number of %d-trees: %u\n", n, offset[n+1] - offset[n]);
	listtrees((uint)n);

	return 0;
}


List rooted trees

Solution:
def bags(n,cache={}):
	if not n: return [(0, "")]

	upto = sum([bags(x) for x in range(n-1, 0, -1)], [])
	return [(c+1, '('+s+')') for c,s in bagchain((0, ""), n-1, upto)]

def bagchain(x, n, bb, start=0):
	if not n: return [x]

	out = []
	for i in range(start, len(bb)):
		c,s = bb[i]
		if c <= n: out += bagchain((x[0] + c, x[1] + s), n-c, bb, i)
	return out

# Maybe this lessens eye strain. Maybe not.
def replace_brackets(s):
	depth,out = 0,[]
	for c in s:
		if c == '(':
			out.append("([{"[depth%3])
			depth += 1
		else:
			depth -= 1
			out.append(")]}"[depth%3])
	return "".join(out)

for x in bags(5): print(replace_brackets(x[1]))


Long literals, with continuations

This task is about writing a computer program that has long literals   (character
literals that may require specifying the words/tokens on more than one (source)
line,   either with continuations or some other method, such as abutments or
concatenations   (or some other mechanisms).

The literal is to be in the form of a "list",    a literal that contains many
words (tokens) separated by a blank (space),   in this case   (so as to have a
common list),   the (English) names of the chemical elements of the periodic table.

The list is to be in (ascending) order of the (chemical) element's atomic number:

 ''hydrogen helium lithium beryllium boron carbon nitrogen oxygen fluorine neon sodium aluminum silicon ...''

... up to the last known (named) chemical element   (at this time).

Do not include any of the   "unnamed"   chemical element names such as:

 ''ununennium unquadnilium triunhexium penthextrium penthexpentium septhexunium octenntrium ennennbium''

To make computer programming languages comparable,   the statement widths should be
restricted to less than   '''81'''   bytes (characters),   or less
if a computer programming language has more restrictive limitations or standards.

Also mention what column the programming statements can start in if   ''not''
in column one.

The list   ''may''   have leading/embedded/trailing blanks during the
declaration   (the actual program statements),   this is allow the list to be
more readable.   The "final" list shouldn't have any leading/trailing or superfluous
blanks   (when stored in the program's "memory").

This list should be written with the idea in mind that the
program   ''will''   be updated,   most likely someone other than the
original author,   as there will be newer (discovered) elements of the periodic
table being added   (possibly in the near future).   These future updates
should be one of the primary concerns in writing these programs and it should be "easy"
for someone else to add chemical elements to the list   (within the computer
program).

Attention should be paid so as to not exceed the   ''clause length''   of
continued or specified statements,   if there is such a restriction.   If the
limit is greater than (say) 4,000 bytes or so,   it needn't be mentioned here.

;Task:
:*   Write a computer program (by whatever name) to contain a list of the known elements.
:*   The program should eventually contain a long literal of words   (the elements).
:*   The literal should show how one could create a long list of blank-delineated words.
:*   The "final" (stored) list should only have a single blank between elements.
:*   Try to use the most idiomatic approach(es) in creating the final list.
:*   Use continuation if possible, and/or show alternatives   (possibly using concatenation).
:*   Use a program comment to explain what the continuation character is if it isn't obvious.
:*   The program should contain a variable that has the date of the last update/revision.
:*   The program, when run, should display with verbiage:
:::*   The last update/revision date   (and should be unambiguous).
:::*   The number of chemical elements in the list.
:::*   The name of the highest (last) element name.

Show all output here, on this page.

Solution:
"""Long string literal. Requires Python 3.6+ for f-strings."""

revision = "October 13th 2020"

# String literal continuation. Notice the trailing space at the end of each
# line but the last, and the lack of commas. There is exactly one "blank"
# between each item in the list.
elements = (
    "hydrogen helium lithium beryllium boron carbon nitrogen oxygen fluorine "
    "neon sodium magnesium aluminum silicon phosphorous sulfur chlorine argon "
    "potassium calcium scandium titanium vanadium chromium manganese iron "
    "cobalt nickel copper zinc gallium germanium arsenic selenium bromine "
    "krypton rubidium strontium yttrium zirconium niobium molybdenum "
    "technetium ruthenium rhodium palladium silver cadmium indium tin "
    "antimony tellurium iodine xenon cesium barium lanthanum cerium "
    "praseodymium neodymium promethium samarium europium gadolinium terbium "
    "dysprosium holmium erbium thulium ytterbium lutetium hafnium tantalum "
    "tungsten rhenium osmium iridium platinum gold mercury thallium lead "
    "bismuth polonium astatine radon francium radium actinium thorium "
    "protactinium uranium neptunium plutonium americium curium berkelium "
    "californium einsteinium fermium mendelevium nobelium lawrencium "
    "rutherfordium dubnium seaborgium bohrium hassium meitnerium darmstadtium "
    "roentgenium copernicium nihonium flerovium moscovium livermorium "
    "tennessine oganesson"
)

def report():
    """Write a summary report to stdout."""
    items = elements.split()

    print(f"Last revision date: {revision}")
    print(f"Number of elements: {len(items)}")
    print(f"Last element      : {items[-1]}")

if __name__ == "__main__":
    report()


Long year

Most years have 52 weeks, some have 53, according to [https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year ISO8601].

;Task:
Write a function which determines if a given year is long (53 weeks) or not, and demonstrate it.

Solution:
#include
#include

// https://webspace.science.uu.nl/~gent0113/calendar/isocalendar.htm

int p(int year) {
	return (int)((double)year + floor(year/4) - floor(year/100) + floor(year/400)) % 7;
}

int is_long_year(int year) {
	return p(year) == 4 || p(year - 1) == 3;
}

void print_long_years(int from, int to) {
	for (int year = from; year <= to; ++year) {
		if (is_long_year(year)) {
			printf("%d ", year);
		}
	}
}

int main() {

	printf("Long (53 week) years between 1800 and 2100\n\n");
	print_long_years(1800, 2100);
	printf("\n");
	return 0;
}


Long year

Solution:
const isLongYear = (year) => {
  const jan1 = new Date(year, 0, 1);
  const dec31 = new Date(year, 11, 31);
  return (4 == jan1.getDay() || 4 == dec31.getDay())
}

for (let y = 1995; y <= 2045; y++) {
  if (isLongYear(y)) {
    console.log(y)
  }
}


Long year

Solution:
'''Long Year ?'''

from datetime import date

# longYear :: Year Int -> Bool
def longYear(y):
    '''True if the ISO year y has 53 weeks.'''
    return 52 < date(y, 12, 28).isocalendar()[1]

# --------------------------TEST---------------------------
# main :: IO ()
def main():
    '''Longer (53 week) years in the range 2000-2100'''
    for year in [
            x for x in range(2000, 1 + 2100)
            if longYear(x)
    ]:
        print(year)

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


Longest common subsequence

'''Introduction'''

Define a ''subsequence'' to be any output string obtained by deleting zero or more symbols from an input string.

The [http://en.wikipedia.org/wiki/Longest_common_subsequence_problem '''Longest Common Subsequence'''] ('''LCS''') is a subsequence of maximum length common to two or more strings.

Let ''A'' ≡ ''A''[0]… ''A''[m - 1] and ''B'' ≡ ''B''[0]… ''B''[n - 1], m < n be strings drawn from an alphabet Σ of size s, containing every distinct symbol in A + B.

An ordered pair (i, j) will be referred to as a match if ''A''[i] = ''B''[j], where 0 ≤ i < m and 0 ≤ j < n.

The set of matches '''M''' defines a relation over matches: '''M'''[i, j] ⇔ (i, j) ∈ '''M'''.

Define a ''non-strict'' [https://en.wikipedia.org/wiki/Product_order product-order] (≤) over ordered pairs, such that (i1, j1) ≤ (i2, j2) ⇔ i1 ≤ i2 and j1 ≤ j2.  We define (≥) similarly.

We say ordered pairs p1 and p2 are ''comparable'' if either p1 ≤ p2 or p1 ≥ p2 holds.  If i1 < i2 and j2 < j1 (or i2 < i1 and j1 < j2) then neither p1 ≤ p2 nor p1 ≥ p2 are possible, and we say p1 and p2 are ''incomparable''.

Define the ''strict'' product-order (<) over ordered pairs, such that (i1, j1) < (i2, j2) ⇔ i1 < i2 and j1 < j2.  We define (>) similarly.

A chain '''C''' is a subset of '''M''' consisting of at least one element m; and where either m1 < m2 or m1 > m2 for every pair of distinct elements m1 and m2.  An antichain '''D''' is any subset of '''M''' in which every pair of distinct elements m1 and m2 are incomparable.

A chain can be visualized as a strictly increasing curve that passes through matches (i, j) in the m*n coordinate space of '''M'''[i, j].

Every Common Sequence of length ''q'' corresponds to a chain of cardinality ''q'', over the set of matches '''M'''.  Thus, finding an LCS can be restated as the problem of finding a chain of maximum cardinality ''p''.

According to [Dilworth 1950], this cardinality ''p'' equals the minimum number of disjoint antichains into which '''M''' can be decomposed.  Note that such a decomposition into the minimal number p of disjoint antichains may not be unique.

'''Background'''

Where the number of symbols appearing in matches is small relative to the length of the input strings, reuse of the symbols increases; and the number of matches will tend towards O(''m*n'') quadratic growth.  This occurs, for example, in the Bioinformatics application of nucleotide and protein sequencing.

The divide-and-conquer approach of [Hirschberg 1975] limits the space required to O(''n'').  However, this approach requires O(''m*n'') time even in the best case.

This quadratic time dependency may become prohibitive, given very long input strings.  Thus, heuristics are often favored over optimal Dynamic Programming solutions.

In the application of comparing file revisions, records from the input files form a large symbol space; and the number of symbols approaches the length of the LCS.  In this case the number of matches reduces to linear, O(''n'') growth.

A binary search optimization due to [Hunt and Szymanski 1977] can be applied to the basic Dynamic Programming approach, resulting in an expected performance of O(''n log m'').  Performance can degrade to O(''m*n log m'') time in the worst case, as the number of matches grows to O(''m*n'').

'''Note'''

[Rick 2000] describes a linear-space algorithm with a time bound of O(''n*s + p*min(m, n - p)'').

'''Legend'''

 A, B are input strings of lengths m, n respectively
 p is the length of the LCS
 M is the set of matches (i, j) such that A[i] = B[j]
 r is the magnitude of M
 s is the magnitude of the alphabet Σ of distinct symbols in A + B

'''References'''

[Dilworth 1950] "A decomposition theorem for partially ordered sets"
by Robert P. Dilworth, published January 1950,
Annals of Mathematics [Volume 51, Number 1, ''pp.'' 161-166]

[Goeman and Clausen 2002] "A New Practical Linear Space Algorithm for the Longest Common
Subsequence Problem" by Heiko Goeman and Michael Clausen,
published 2002, Kybernetika [Volume 38, Issue 1, ''pp.'' 45-66]

[Hirschberg 1975] "A linear space algorithm for computing maximal common subsequences"
by Daniel S. Hirschberg, published June 1975
Communications of the ACM [Volume 18, Number 6, ''pp.'' 341-343]

[Hunt and McIlroy 1976] "An Algorithm for Differential File Comparison"
by James W. Hunt and M. Douglas McIlroy, June 1976
Computing Science Technical Report, Bell Laboratories 41

[Hunt and Szymanski 1977] "A Fast Algorithm for Computing Longest Common Subsequences"
by James W. Hunt and Thomas G. Szymanski, published May 1977
Communications of the ACM [Volume 20, Number 5, ''pp.'' 350-353]

[Rick 2000] "Simple and fast linear space computation of longest common subsequences"
by Claus Rick, received 17 March 2000, Information Processing Letters,
Elsevier Science [Volume 75, ''pp.'' 275–281]

'''Examples'''

The sequences "1234" and "1224533324" have an LCS of "1234":
 '''1234'''
 '''12'''245'''3'''332'''4'''

For a string example, consider the sequences "thisisatest" and "testing123testing". An LCS would be "tsitest":
 '''t'''hi'''si'''sa'''test'''
 '''t'''e'''s'''t'''i'''ng123'''test'''ing

In this puzzle, your code only needs to deal with strings. Write a function which returns an LCS of two strings (case-sensitive). You don't need to show multiple LCS's.

For more information on this problem please see Wikipedia.

Solution:
#include
#include

#define MAX(a, b) (a > b ? a : b)

int lcs (char *a, int n, char *b, int m, char **s) {
    int i, j, k, t;
    int *z = calloc((n + 1) * (m + 1), sizeof (int));
    int **c = calloc((n + 1), sizeof (int *));
    for (i = 0; i <= n; i++) {
        c[i] = &z[i * (m + 1)];
    }
    for (i = 1; i <= n; i++) {
        for (j = 1; j <= m; j++) {
            if (a[i - 1] == b[j - 1]) {
                c[i][j] = c[i - 1][j - 1] + 1;
            }
            else {
                c[i][j] = MAX(c[i - 1][j], c[i][j - 1]);
            }
        }
    }
    t = c[n][m];
    *s = malloc(t);
    for (i = n, j = m, k = t - 1; k >= 0;) {
        if (a[i - 1] == b[j - 1])
            (*s)[k] = a[i - 1], i--, j--, k--;
        else if (c[i][j - 1] > c[i - 1][j])
            j--;
        else
            i--;
    }
    free(c);
    free(z);
    return t;
}


Longest common subsequence

Solution:
function lcs_greedy(x,y){
  var p1, i, idx,
      symbols = {},
      r = 0,
      p = 0,
      l = 0,
      m = x.length,
      n = y.length,
      s = new Buffer((m < n) ? n : m);

  p1 = popsym(0);

  for (i = 0; i < m; i++) {
    p = (r === p) ? p1 : popsym(i);
    p1 = popsym(i + 1);
    if (p > p1) {
      i += 1;
      idx = p1;
    } else {
      idx = p;
    }

    if (idx === n) {
      p = popsym(i);
    } else {
      r = idx;
      s[l] = x.charCodeAt(i);
      l += 1;
    }
  }
  return s.toString('utf8', 0, l);

  function popsym(index) {
    var s = x[index],
        pos = symbols[s] + 1;

    pos = y.indexOf(s, ((pos > r) ? pos : r));
    if (pos === -1) { pos = n; }
    symbols[s] = pos;
    return pos;
  }
}


Longest common subsequence

Solution:
def lcs(a, b):
    # generate matrix of length of longest common subsequence for substrings of both words
    lengths = [[0] * (len(b)+1) for _ in range(len(a)+1)]
    for i, x in enumerate(a):
        for j, y in enumerate(b):
            if x == y:
                lengths[i+1][j+1] = lengths[i][j] + 1
            else:
                lengths[i+1][j+1] = max(lengths[i+1][j], lengths[i][j+1])

    # read a substring from the matrix
    result = ''
    j = len(b)
    for i in range(1, len(a)+1):
        if lengths[i][j] != lengths[i-1][j]:
            result += a[i-1]

    return result


Longest common substring

;Task:
Write a function that returns the longest common substring of two strings.

Use it within a program that demonstrates sample output from the function, which will consist of the longest common substring between "thisisatest" and "testing123testing".

Note that substrings are consecutive characters within a string.   This distinguishes them from subsequences, which is any sequence of characters within a string, even if there are extraneous characters in between them.

Hence, the [[longest common subsequence]] between "thisisatest" and "testing123testing" is "tsitest", whereas the longest common sub''string'' is just "test".

;References:
*[http://en.wikipedia.org/wiki/Generalized_suffix_tree Generalize Suffix Tree]
*[[Ukkonen’s Suffix Tree Construction]]

Solution:
#include

void lcs(const char * const sa, const char * const sb, char ** const beg, char ** const end) {
    size_t apos, bpos;
    ptrdiff_t len;

    *beg = 0;
    *end = 0;
    len = 0;

    for (apos = 0; sa[apos] != 0; ++apos) {
        for (bpos = 0; sb[bpos] != 0; ++bpos) {
            if (sa[apos] == sb[bpos]) {
                len = 1;
                while (sa[apos + len] != 0 && sb[bpos + len] != 0 && sa[apos + len] == sb[bpos + len]) {
                    len++;
                }
            }

            if (len > *end - *beg) {
                *beg = sa + apos;
                *end = *beg + len;
                len = 0;
            }
        }
    }
}

int main() {
    char *s1 = "thisisatest";
    char *s2 = "testing123testing";
    char *beg, *end, *it;

    lcs(s1, s2, &beg, &end);

    for (it = beg; it != end; it++) {
        putchar(*it);
    }
    printf("\n");

    return 0;
}


Longest common substring

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

    // longestCommon :: String -> String -> String
    const longestCommon = (s1, s2) => maximumBy(
        comparing(length),
        intersect(...apList(
            [s => map(
                concat,
                concatMap(tails, compose(tail, inits)(s))
            )],
            [s1, s2]
        ))
    );

    // main :: IO ()
    const main = () =>
        console.log(
            longestCommon(
                "testing123testing",
                "thisisatest"
            )
        );

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

    // Each member of a list of functions applied to each
    // of a list of arguments, deriving a list of new values.

    // apList (<*>) :: [(a -> b)] -> [a] -> [b]
    const apList = (fs, xs) => //
        fs.reduce((a, f) => a.concat(
            xs.reduce((a, x) => a.concat([f(x)]), [])
        ), []);

    // comparing :: (a -> b) -> (a -> a -> Ordering)
    const comparing = f =>
        (x, y) => {
            const
                a = f(x),
                b = f(y);
            return a < b ? -1 : (a > b ? 1 : 0);
        };

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

    // concat :: [[a]] -> [a]
    // concat :: [String] -> String
    const concat = xs =>
        0 < xs.length ? (() => {
            const unit = 'string' !== typeof xs[0] ? (
                []
            ) : '';
            return unit.concat.apply(unit, xs);
        })() : [];

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

    // inits([1, 2, 3]) -> [[], [1], [1, 2], [1, 2, 3]
    // inits('abc') -> ["", "a", "ab", "abc"]

    // inits :: [a] -> [[a]]
    // inits :: String -> [String]
    const inits = xs => [
            []
        ]
        .concat(('string' === typeof xs ? xs.split('') : xs)
            .map((_, i, lst) => lst.slice(0, i + 1)));

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

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

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

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

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

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

    // tails :: [a] -> [[a]]
    const tails = xs => {
        const
            es = ('string' === typeof xs) ? (
                xs.split('')
            ) : xs;
        return es.map((_, i) => es.slice(i))
            .concat([
                []
            ]);
    };

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


Longest common substring

Solution:
s1 = "thisisatest"
s2 = "testing123testing"
len1, len2 = len(s1), len(s2)
ir, jr = 0, -1
for i1 in range(len1):
    i2 = s2.find(s1[i1])
    while i2 >= 0:
        j1, j2 = i1, i2
        while j1 < len1 and j2 < len2 and s2[j2] == s1[j1]:
            if j1-i1 >= jr-ir:
                ir, jr = i1, j1
            j1 += 1; j2 += 1
        i2 = s2.find(s1[i1], i2+1)
print (s1[ir:jr+1])


Longest increasing subsequence

Calculate and show here a longest increasing subsequence of the list:
:\{3, 2, 6, 4, 5, 1\}
And of the list:
:\{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15\}

Note that a list may have more than one subsequence that is of the maximum length.

;Ref:
# [http://www.youtube.com/watch?v=4fQJGoeW5VE Dynamic Programming #1: Longest Increasing Subsequence] on YouTube
# An efficient solution can be based on Patience sorting.

Solution:
#include
#include

struct node {
	int val, len;
	struct node *next;
};

void lis(int *v, int len)
{
	int i;
	struct node *p, *n = calloc(len, sizeof *n);
	for (i = 0; i < len; i++)
		n[i].val = v[i];

	for (i = len; i--; ) {
		// find longest chain that can follow n[i]
		for (p = n + i; p++ < n + len; ) {
			if (p->val > n[i].val && p->len >= n[i].len) {
				n[i].next = p;
				n[i].len = p->len + 1;
			}
		}
	}

	// find longest chain
	for (i = 0, p = n; i < len; i++)
		if (n[i].len > p->len) p = n + i;

	do printf(" %d", p->val); while ((p = p->next));
	putchar('\n');

	free(n);
}

int main(void)
{
	int x[] = { 3, 2, 6, 4, 5, 1 };
	int y[] = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 };

	lis(x, sizeof(x) / sizeof(int));
	lis(y, sizeof(y) / sizeof(int));
	return 0;
}


Longest increasing subsequence

Solution:
function getLis(input) {
  if (input.length === 0) {
    return [];
  }

  var lisLenPerIndex = [];
  let max = { index: 0, length: 1 };

  for (var i = 0; i < input.length; i++) {
    lisLenPerIndex[i] = 1;
    for (var j = i - 1; j >= 0; j--) {
      if (input[i] > input[j] && lisLenPerIndex[j] >= lisLenPerIndex[i]) {
        var length = lisLenPerIndex[i] = lisLenPerIndex[j] + 1;
        if (length > max.length) {
          max = { index: i, length };
        }
      }
    }
  }

  var lis = [input[max.index]];
  for (var i = max.index; i >= 0 && max.length !== 0; i--) {
    if (input[max.index] > input[i] && lisLenPerIndex[i] === max.length - 1) {
      lis.unshift(input[i]);
      max.length--;
    }
  }

  return lis;
}

console.log(getLongestIncreasingSubsequence([0, 7, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]));
console.log(getLongestIncreasingSubsequence([3, 2, 6, 4, 5, 1]));


Longest increasing subsequence

Solution:
def longest_increasing_subsequence(X):
    """Returns the Longest Increasing Subsequence in the Given List/Array"""
    N = len(X)
    P = [0] * N
    M = [0] * (N+1)
    L = 0
    for i in range(N):
       lo = 1
       hi = L
       while lo <= hi:
           mid = (lo+hi)//2
           if (X[M[mid]] < X[i]):
               lo = mid+1
           else:
               hi = mid-1

       newL = lo
       P[i] = M[newL-1]
       M[newL] = i

       if (newL > L):
           L = newL

    S = []
    k = M[L]
    for i in range(L-1, -1, -1):
        S.append(X[k])
        k = P[k]
    return S[::-1]

if __name__ == '__main__':
    for d in [[3,2,6,4,5,1], [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]]:
        print('a L.I.S. of %s is %s' % (d, longest_increasing_subsequence(d)))


Lucky and even lucky numbers

Note that in the following explanation list indices are assumed to start at ''one''.

;Definition of lucky numbers
''Lucky numbers'' are positive integers that are formed by:

# Form a list of all the positive odd integers > 01, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39 ...
# Return the first number from the list (which is '''1''').
# (Loop begins here)
#* Note then return the second number from the list (which is '''3''').
#* Discard every third, (as noted), number from the list to form the new list1, 3, 7, 9, 13, 15, 19, 21, 25, 27, 31, 33, 37, 39, 43, 45, 49, 51, 55, 57 ...
# (Expanding the loop a few more times...)
#* Note then return the third number from the list (which is '''7''').
#* Discard every 7th, (as noted), number from the list to form the new list1, 3, 7, 9, 13, 15, 21, 25, 27, 31, 33, 37, 43, 45, 49, 51, 55, 57, 63, 67 ...
#* Note then return the 4th number from the list (which is '''9''').
#* Discard every 9th, (as noted), number from the list to form the new list1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 45, 49, 51, 55, 63, 67, 69, 73 ...
#* Take the 5th, i.e. '''13'''.  Remove every 13th.
#* Take the 6th, i.e. '''15'''.  Remove every 15th.
#* Take the 7th, i.e. '''21'''.  Remove every 21th.
#* Take the 8th, i.e. '''25'''.  Remove every 25th.
# (Rule for the loop)
#* Note the nth, which is m.
#* Remove every mth.
#* Increment n.

;Definition of even lucky numbers
This follows the same rules as the definition of lucky numbers above ''except for the very first step'':
# Form a list of all the positive '''even''' integers > 02, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40 ...
# Return the first number from the list (which is '''2''').
# (Loop begins here)
#* Note then return the second number from the list (which is '''4''').
#* Discard every 4th, (as noted), number from the list to form the new list2, 4, 6, 10, 12, 14, 18, 20, 22, 26, 28, 30, 34, 36, 38, 42, 44, 46, 50, 52 ...
# (Expanding the loop a few more times...)
#* Note then return the third number from the list (which is '''6''').
#* Discard every 6th, (as noted), number from the list to form the new list2, 4, 6, 10, 12, 18, 20, 22, 26, 28, 34, 36, 38, 42, 44, 50, 52, 54, 58, 60 ...
#* Take the 4th, i.e. '''10'''.  Remove every 10th.
#* Take the 5th, i.e. '''12'''.  Remove every 12th.
# (Rule for the loop)
#* Note the nth, which is m.
#* Remove every mth.
#* Increment n.

;Task requirements
* Write one or two subroutines (functions) to generate ''lucky numbers'' and ''even lucky numbers''
* Write a command-line interface to allow selection of which kind of numbers and which number(s). Since input is from the command line, tests should be made for the common errors:
** missing arguments
** too many arguments
** number (or numbers) aren't legal
** misspelled argument ('''lucky''' or '''evenLucky''')
* The command line handling should:
** support mixed case handling of the (non-numeric) arguments
** support printing a particular number
** support printing a range of numbers by their index
** support printing a range of numbers by their values
* The resulting list of numbers should be printed on a single line.

The program should support the arguments:

                             what is displayed  (on a single line)
       argument(s)              (optional verbiage is encouraged)
  ╔═══════════════════╦════════════════════════════════════════════════════╗
  ║  j                ║  Jth       lucky number                            ║
  ║  j  ,      lucky  ║  Jth       lucky number                            ║
  ║  j  ,  evenLucky  ║  Jth  even lucky number                            ║
  ║                   ║                                                    ║
  ║  j  k             ║  Jth  through  Kth (inclusive)       lucky numbers ║
  ║  j  k      lucky  ║  Jth  through  Kth (inclusive)       lucky numbers ║
  ║  j  k  evenLucky  ║  Jth  through  Kth (inclusive)  even lucky numbers ║
  ║                   ║                                                    ║
  ║  j -k             ║  all       lucky numbers in the range  j ──► |k|   ║
  ║  j -k      lucky  ║  all       lucky numbers in the range  j ──► |k|   ║
  ║  j -k  evenLucky  ║  all  even lucky numbers in the range  j ──► |k|   ║
  ╚═══════════════════╩════════════════════════════════════════════════════╝
                           where    |k|    is the absolute value of   k

Demonstrate the program by:
* showing the first twenty ''lucky'' numbers
* showing the first twenty ''even lucky'' numbers
* showing all ''lucky'' numbers between 6,000 and 6,100 (inclusive)
* showing all ''even lucky'' numbers in the same range as above
* showing the 10,000th ''lucky'' number (extra credit)
* showing the 10,000th ''even lucky'' number (extra credit)

;See also:
* This task is related to the [[Sieve of Eratosthenes]] task.
* OEIS Wiki [http://oeis.org/wiki/Lucky_numbers Lucky numbers].
* Sequence [https://oeis.org/A000959 A000959 lucky numbers] on The On-Line Encyclopedia of Integer Sequences.
* Sequence [https://oeis.org/A045954 A045954 even lucky numbers or ELN] on The On-Line Encyclopedia of Integer Sequences.
* Entry [http://mathworld.wolfram.com/LuckyNumber.html lucky numbers] on The Eric Weisstein's World of Mathematics.

Solution:
#include
#include
#include

#define LUCKY_SIZE 60000
int luckyOdd[LUCKY_SIZE];
int luckyEven[LUCKY_SIZE];

void compactLucky(int luckyArray[]) {
    int i, j, k;

    for (i = 0; i < LUCKY_SIZE; i++) {
        if (luckyArray[i] == 0) {
            j = i;
            break;
        }
    }

    for (j = i + 1; j < LUCKY_SIZE; j++) {
        if (luckyArray[j] > 0) {
            luckyArray[i++] = luckyArray[j];
        }
    }

    for (; i < LUCKY_SIZE; i++) {
        luckyArray[i] = 0;
    }
}

void initialize() {
    int i, j;

    // unfiltered
    for (i = 0; i < LUCKY_SIZE; i++) {
        luckyEven[i] = 2 * i + 2;
        luckyOdd[i] = 2 * i + 1;
    }

    // odd filter
    for (i = 1; i < LUCKY_SIZE; i++) {
        if (luckyOdd[i] > 0) {
            for (j = luckyOdd[i] - 1; j < LUCKY_SIZE; j += luckyOdd[i]) {
                luckyOdd[j] = 0;
            }
            compactLucky(luckyOdd);
        }
    }

    // even filter
    for (i = 1; i < LUCKY_SIZE; i++) {
        if (luckyEven[i] > 0) {
            for (j = luckyEven[i] - 1; j < LUCKY_SIZE; j += luckyEven[i]) {
                luckyEven[j] = 0;
            }
            compactLucky(luckyEven);
        }
    }
}

void printBetween(size_t j, size_t k, bool even) {
    int i;

    if (even) {
        if (luckyEven[j] == 0 || luckyEven[k] == 0) {
            fprintf(stderr, "At least one argument is too large\n");
            exit(EXIT_FAILURE);
        }
        printf("Lucky even numbers between %d and %d are:", j, k);
        for (i = 0; luckyEven[i] != 0; i++) {
            if (luckyEven[i] > k) {
                break;
            }
            if (luckyEven[i] > j) {
                printf(" %d", luckyEven[i]);
            }
        }
    } else {
        if (luckyOdd[j] == 0 || luckyOdd[k] == 0) {
            fprintf(stderr, "At least one argument is too large\n");
            exit(EXIT_FAILURE);
        }
        printf("Lucky numbers between %d and %d are:", j, k);
        for (i = 0; luckyOdd[i] != 0; i++) {
            if (luckyOdd[i] > k) {
                break;
            }
            if (luckyOdd[i] > j) {
                printf(" %d", luckyOdd[i]);
            }
        }
    }
    printf("\n");
}

void printRange(size_t j, size_t k, bool even) {
    int i;

    if (even) {
        if (luckyEven[k] == 0) {
            fprintf(stderr, "The argument is too large\n");
            exit(EXIT_FAILURE);
        }
        printf("Lucky even numbers %d to %d are:", j, k);
        for (i = j - 1; i < k; i++) {
            printf(" %d", luckyEven[i]);
        }
    } else {
        if (luckyOdd[k] == 0) {
            fprintf(stderr, "The argument is too large\n");
            exit(EXIT_FAILURE);
        }
        printf("Lucky numbers %d to %d are:", j, k);
        for (i = j - 1; i < k; i++) {
            printf(" %d", luckyOdd[i]);
        }
    }
    printf("\n");
}

void printSingle(size_t j, bool even) {
    if (even) {
        if (luckyEven[j] == 0) {
            fprintf(stderr, "The argument is too large\n");
            exit(EXIT_FAILURE);
        }
        printf("Lucky even number %d=%d\n", j, luckyEven[j - 1]);
    } else {
        if (luckyOdd[j] == 0) {
            fprintf(stderr, "The argument is too large\n");
            exit(EXIT_FAILURE);
        }
        printf("Lucky number %d=%d\n", j, luckyOdd[j - 1]);
    }
}

void help() {
    printf("./lucky j [k] [--lucky|--evenLucky]\n");
    printf("\n");
    printf("       argument(s)        |  what is displayed\n");
    printf("==============================================\n");
    printf("-j=m                      |  mth lucky number\n");
    printf("-j=m  --lucky             |  mth lucky number\n");
    printf("-j=m  --evenLucky         |  mth even lucky number\n");
    printf("-j=m  -k=n                |  mth through nth (inclusive) lucky numbers\n");
    printf("-j=m  -k=n  --lucky       |  mth through nth (inclusive) lucky numbers\n");
    printf("-j=m  -k=n  --evenLucky   |  mth through nth (inclusive) even lucky numbers\n");
    printf("-j=m  -k=-n               |  all lucky numbers in the range [m, n]\n");
    printf("-j=m  -k=-n  --lucky      |  all lucky numbers in the range [m, n]\n");
    printf("-j=m  -k=-n  --evenLucky  |  all even lucky numbers in the range [m, n]\n");
}

void process(int argc, char *argv[]) {
    bool evenLucky = false;
    int j = 0;
    int k = 0;

    bool good = false;
    int i;

    for (i = 1; i < argc; ++i) {
        if ('-' == argv[i][0]) {
            if ('-' == argv[i][1]) {
                // long args
                if (0 == strcmp("--lucky", argv[i])) {
                    evenLucky = false;
                } else if (0 == strcmp("--evenLucky", argv[i])) {
                    evenLucky = true;
                } else {
                    fprintf(stderr, "Unknown long argument: [%s]\n", argv[i]);
                    exit(EXIT_FAILURE);
                }
            } else {
                // short args
                if ('j' == argv[i][1] && '=' == argv[i][2] && argv[i][3] != 0) {
                    good = true;
                    j = atoi(&argv[i][3]);
                } else if ('k' == argv[i][1] && '=' == argv[i][2]) {
                    k = atoi(&argv[i][3]);
                } else {
                    fprintf(stderr, "Unknown short argument: [%s]\n", argv[i]);
                    exit(EXIT_FAILURE);
                }
            }
        } else {
            fprintf(stderr, "Unknown argument: [%s]\n", argv[i]);
            exit(EXIT_FAILURE);
        }
    }

    if (!good) {
        help();
        exit(EXIT_FAILURE);
    }

    if (k > 0) {
        printRange(j, k, evenLucky);
    } else if (k < 0) {
        printBetween(j, -k, evenLucky);
    } else {
        printSingle(j, evenLucky);
    }
}

void test() {
    printRange(1, 20, false);
    printRange(1, 20, true);

    printBetween(6000, 6100, false);
    printBetween(6000, 6100, true);

    printSingle(10000, false);
    printSingle(10000, true);
}

int main(int argc, char *argv[]) {
    initialize();

    //test();

    if (argc < 2) {
        help();
        return 1;
    }
    process(argc, argv);

    return 0;
}