Four is magic

Solution:
import random
from collections import OrderedDict

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

def string_representation(i: int) -> str:
    """
    Return the english string representation of an integer
    """
    if i == 0:
        return 'zero'

    words = ['negative'] if i < 0 else []
    working_copy = abs(i)

    for key, value in numbers.items():
        if key <= working_copy:
            times = int(working_copy / key)

            if key >= 100:
                words.append(string_representation(times))

            words.append(value)
            working_copy -= times * key

        if working_copy == 0:
            break

    return ' '.join(words)

def next_phrase(i: int):
    """
    Generate all the phrases
    """
    while not i == 4:  # Generate phrases until four is reached
        str_i = string_representation(i)
        len_i = len(str_i)

        yield str_i, 'is', string_representation(len_i)

        i = len_i

    # the last phrase
    yield string_representation(i), 'is', 'magic'

def magic(i: int) -> str:
    phrases = []

    for phrase in next_phrase(i):
        phrases.append(' '.join(phrase))

    return f'{", ".join(phrases)}.'.capitalize()

if __name__ == '__main__':

    for j in (random.randint(0, 10 ** 3) for i in range(5)):
        print(j, ':\n', magic(j), '\n')

    for j in (random.randint(-10 ** 24, 10 ** 24) for i in range(2)):
        print(j, ':\n', magic(j), '\n')


Four is the number of letters in the ...

The      '''Four is ...'''      sequence is based on the counting of the number of
letters in the words of the (never─ending) sentence:
   Four is the number of letters in the first word of this sentence, two in the second,
   three in the third, six in the fourth, two in the fifth, seven in the sixth, ···

;Definitions and directives:
:*   English is to be used in spelling numbers.
:*   '''Letters'''   are defined as the upper─ and lowercase letters in the Latin alphabet   ('''A──►Z'''   and   '''a──►z''').
:*   Commas are not counted,   nor are hyphens (dashes or minus signs).
:*   '''twenty─three'''   has eleven letters.
:*   '''twenty─three'''   is considered one word   (which is hyphenated).
:*   no   ''' ''and'' '''   words are to be used when spelling a (English) word for a number.
:*   The American version of numbers will be used here in this task   (as opposed to the British version).
          '''2,000,000,000'''   is two billion,   ''not''   two milliard.

;Task:
:*   Write a driver (invoking routine) and a function (subroutine/routine···) that returns the sequence (for any positive integer) of the number of letters in the first   '''N'''    words in the never─ending sentence.   For instance, the portion of the never─ending sentence shown above (2nd sentence of this task's preamble),   the sequence would be:
          '''4  2  3  6  2  7'''
:*   Only construct as much as is needed for the never─ending sentence.
:*   Write a driver (invoking routine) to show the number of letters in the   Nth   word,   ''as well as''   showing the   Nth   word itself.
:*   After each test case, show the total number of characters   (including blanks, commas, and punctuation)   of the sentence that was constructed.
:*   Show all output here.

;Test cases:
  Display the first  201  numbers in the sequence   (and the total number of characters in the sentence).
  Display the number of letters  (and the word itself)  of the       1,000th  word.
  Display the number of letters  (and the word itself)  of the      10,000th  word.
  Display the number of letters  (and the word itself)  of the     100,000th  word.
  Display the number of letters  (and the word itself)  of the   1,000,000th  word.
  Display the number of letters  (and the word itself)  of the  10,000,000th  word  (optional).

;Related tasks:
:*   [[Four is magic]]
:*   [[Look-and-say sequence]]
:*   [[Number names]]
:*   [[Self-describing numbers]]
:*   [[Self-referential sequence]]
:*   [[Spelling of ordinal numbers]]

;Also see:
:*   See the OEIS sequence  A72425  "Four is the number of letters...".
:*   See the OEIS sequence  A72424  "Five's the number of letters..."

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

typedef uint64_t integer;

typedef struct number_names_tag {
    const char* cardinal;
    const char* ordinal;
} number_names;

const number_names small[] = {
    { "zero", "zeroth" }, { "one", "first" }, { "two", "second" },
    { "three", "third" }, { "four", "fourth" }, { "five", "fifth" },
    { "six", "sixth" }, { "seven", "seventh" }, { "eight", "eighth" },
    { "nine", "ninth" }, { "ten", "tenth" }, { "eleven", "eleventh" },
    { "twelve", "twelfth" }, { "thirteen", "thirteenth" },
    { "fourteen", "fourteenth" }, { "fifteen", "fifteenth" },
    { "sixteen", "sixteenth" }, { "seventeen", "seventeenth" },
    { "eighteen", "eighteenth" }, { "nineteen", "nineteenth" }
};

const number_names tens[] = {
    { "twenty", "twentieth" }, { "thirty", "thirtieth" },
    { "forty", "fortieth" }, { "fifty", "fiftieth" },
    { "sixty", "sixtieth" }, { "seventy", "seventieth" },
    { "eighty", "eightieth" }, { "ninety", "ninetieth" }
};

typedef struct named_number_tag {
    const char* cardinal;
    const char* ordinal;
    integer number;
} named_number;

const named_number named_numbers[] = {
    { "hundred", "hundredth", 100 },
    { "thousand", "thousandth", 1000 },
    { "million", "millionth", 1000000 },
    { "billion", "biliionth", 1000000000 },
    { "trillion", "trillionth", 1000000000000 },
    { "quadrillion", "quadrillionth", 1000000000000000ULL },
    { "quintillion", "quintillionth", 1000000000000000000ULL }
};

const char* get_small_name(const number_names* n, bool ordinal) {
    return ordinal ? n->ordinal : n->cardinal;
}

const char* get_big_name(const named_number* n, bool ordinal) {
    return ordinal ? n->ordinal : n->cardinal;
}

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

typedef struct word_tag {
    size_t offset;
    size_t length;
} word_t;

typedef struct word_list_tag {
    GArray* words;
    GString* str;
} word_list;

void word_list_create(word_list* words) {
    words->words = g_array_new(FALSE, FALSE, sizeof(word_t));
    words->str = g_string_new(NULL);
}

void word_list_destroy(word_list* words) {
    g_string_free(words->str, TRUE);
    g_array_free(words->words, TRUE);
}

void word_list_clear(word_list* words) {
    g_string_truncate(words->str, 0);
    g_array_set_size(words->words, 0);
}

void word_list_append(word_list* words, const char* str) {
    size_t offset = words->str->len;
    size_t len = strlen(str);
    g_string_append_len(words->str, str, len);
    word_t word;
    word.offset = offset;
    word.length = len;
    g_array_append_val(words->words, word);
}

word_t* word_list_get(word_list* words, size_t index) {
    return &g_array_index(words->words, word_t, index);
}

void word_list_extend(word_list* words, const char* str) {
    word_t* word = word_list_get(words, words->words->len - 1);
    size_t len = strlen(str);
    word->length += len;
    g_string_append_len(words->str, str, len);
}

size_t append_number_name(word_list* words, integer n, bool ordinal) {
    size_t count = 0;
    if (n < 20) {
        word_list_append(words, get_small_name(&small[n], ordinal));
        count = 1;
    } else if (n < 100) {
        if (n % 10 == 0) {
            word_list_append(words, get_small_name(&tens[n/10 - 2], ordinal));
        } else {
            word_list_append(words, get_small_name(&tens[n/10 - 2], false));
            word_list_extend(words, "-");
            word_list_extend(words, get_small_name(&small[n % 10], ordinal));
        }
        count = 1;
    } else {
        const named_number* num = get_named_number(n);
        integer p = num->number;
        count += append_number_name(words, n/p, false);
        if (n % p == 0) {
            word_list_append(words, get_big_name(num, ordinal));
            ++count;
        } else {
            word_list_append(words, get_big_name(num, false));
            ++count;
            count += append_number_name(words, n % p, ordinal);
        }
    }
    return count;
}

size_t count_letters(word_list* words, size_t index) {
    const word_t* word = word_list_get(words, index);
    size_t letters = 0;
    const char* s = words->str->str + word->offset;
    for (size_t i = 0, n = word->length; i < n; ++i) {
        if (isalpha((unsigned char)s[i]))
            ++letters;
    }
    return letters;
}

void sentence(word_list* result, size_t count) {
    static const char* words[] = {
        "Four", "is", "the", "number", "of", "letters", "in", "the",
        "first", "word", "of", "this", "sentence,"
    };
    word_list_clear(result);
    size_t n = sizeof(words)/sizeof(words[0]);
    for (size_t i = 0; i < n; ++i)
        word_list_append(result, words[i]);
    for (size_t i = 1; count > n; ++i) {
        n += append_number_name(result, count_letters(result, i), false);
        word_list_append(result, "in");
        word_list_append(result, "the");
        n += 2;
        n += append_number_name(result, i + 1, true);
        // Append a comma to the final word
        word_list_extend(result, ",");
    }
}

size_t sentence_length(const word_list* words) {
    size_t n = words->words->len;
    if (n == 0)
        return 0;
    return words->str->len + n - 1;
}

int main() {
    setlocale(LC_ALL, "");
    size_t n = 201;
    word_list result = { 0 };
    word_list_create(&result);
    sentence(&result, n);
    printf("Number of letters in first %'lu words in the sequence:\n", n);
    for (size_t i = 0; i < n; ++i) {
        if (i != 0)
            printf("%c", i % 25 == 0 ? '\n' : ' ');
        printf("%'2lu", count_letters(&result, i));
    }
    printf("\nSentence length: %'lu\n", sentence_length(&result));
    for (n = 1000; n <= 10000000; n *= 10) {
        sentence(&result, n);
        const word_t* word = word_list_get(&result, n - 1);
        const char* s = result.str->str + word->offset;
        printf("The %'luth word is '%.*s' and has %lu letters. ", n,
               (int)word->length, s, count_letters(&result, n - 1));
        printf("Sentence length: %'lu\n" , sentence_length(&result));
    }
    word_list_destroy(&result);
    return 0;
}


Solution:
# Python implementation of Rosetta Code Task
# http://rosettacode.org/wiki/Four_is_the_number_of_letters_in_the_...
# Uses inflect
# https://pypi.org/project/inflect/

import inflect

def count_letters(word):
    """
    count letters ignore , or -, or space
    """
    count = 0
    for letter in word:
        if letter != ',' and letter !='-' and letter !=' ':
            count += 1

    return count

def split_with_spaces(sentence):
    """
    Takes string with partial sentence and returns
    list of words with spaces included.

    Leading space is attached to first word.
    Later spaces attached to prior word.
    """
    sentence_list = []
    curr_word = ""
    for c in sentence:
        if c == " " and curr_word != "":
            # append space to end of non-empty words
            # assumed no more than 1 consecutive space.
            sentence_list.append(curr_word+" ")
            curr_word = ""
        else:
            curr_word += c

    # add trailing word that does not end with a space

    if len(curr_word) > 0:
        sentence_list.append(curr_word)

    return sentence_list

def my_num_to_words(p, my_number):
    """
    Front end to inflect's number_to_words

    Get's rid of ands and commas in large numbers.
    """

    number_string_list = p.number_to_words(my_number, wantlist=True, andword='')

    number_string = number_string_list[0]

    for i in range(1,len(number_string_list)):
        number_string += " " + number_string_list[i]

    return number_string

def build_sentence(p, max_words):
    """

    Builds at most max_words of the task following the pattern:

    Four is the number of letters in the first word of this sentence, two in the second,
    three in the third, six in the fourth, two in the fifth, seven in the sixth,

    """

    # start with first part of sentence up first comma as a list

    sentence_list = split_with_spaces("Four is the number of letters in the first word of this sentence,")

    num_words = 13

    # which word number we are doing next
    # two/second is first one in loop

    word_number = 2

    # loop until sentance is at least as long as needs be

    while num_words < max_words:
        # Build something like
        # ,two in the second

        # get second or whatever we are on

        ordinal_string = my_num_to_words(p, p.ordinal(word_number))

        # get two or whatever the length is of the word_number word

        word_number_string = my_num_to_words(p, count_letters(sentence_list[word_number - 1]))

        # sentence addition

        new_string = " "+word_number_string+" in the "+ordinal_string+","

        new_list = split_with_spaces(new_string)

        sentence_list += new_list

        # add new word count

        num_words += len(new_list)

        # increment word number

        word_number += 1

    return sentence_list, num_words

def word_and_counts(word_num):
    """

    Print's lines like this:

    Word     1000 is "in", with 2 letters.  Length of sentence so far: 6279

    """

    sentence_list, num_words = build_sentence(p, word_num)

    word_str = sentence_list[word_num - 1].strip(' ,')

    num_letters = len(word_str)

    num_characters = 0

    for word in sentence_list:
       num_characters += len(word)

    print('Word {0:8d} is "{1}", with {2} letters.  Length of the sentence so far: {3}  '.format(word_num,word_str,num_letters,num_characters))

p = inflect.engine()

sentence_list, num_words = build_sentence(p, 201)

print(" ")
print("The lengths of the first 201 words are:")
print(" ")

print('{0:3d}:  '.format(1),end='')

total_characters = 0

for word_index in range(201):

    word_length = count_letters(sentence_list[word_index])

    total_characters += len(sentence_list[word_index])

    print('{0:2d}'.format(word_length),end='')
    if (word_index+1) % 20 == 0:
        # newline every 20
        print(" ")
        print('{0:3d}:  '.format(word_index + 2),end='')
    else:
        print(" ",end='')

print(" ")
print(" ")
print("Length of the sentence so far: "+str(total_characters))
print(" ")

"""

Expected output this part:

Word     1000 is "in", with 2 letters.  Length of the sentence so far: 6279
Word    10000 is "in", with 2 letters.  Length of the sentence so far: 64140
Word   100000 is "one", with 3 letters.  Length of the sentence so far: 659474
Word  1000000 is "the", with 3 letters.  Length of the sentence so far: 7113621
Word 10000000 is "thousand", with 8 letters.  Length of the sentence so far: 70995756

"""

word_and_counts(1000)
word_and_counts(10000)
word_and_counts(100000)
word_and_counts(1000000)
word_and_counts(10000000)


Function prototype

Some languages provide the facility to declare functions and subroutines through the use of function prototyping.

;Task:
Demonstrate the methods available for declaring prototypes within the language. The provided solutions should include:

* An explanation of any placement restrictions for prototype declarations
* A prototype declaration for a function that does not require arguments
* A prototype declaration for a function that requires two arguments
* A prototype declaration for a function that utilizes varargs
* A prototype declaration for a function that utilizes optional arguments
* A prototype declaration for a function that utilizes named parameters
* Example of prototype declarations for subroutines or procedures (if these differ from functions)
* An explanation and example of any special forms of prototyping not covered by the above

Languages that do not provide function prototyping facilities should be omitted from this task.

Solution:
int noargs(void); /* Declare a function with no argument that returns an integer */
int twoargs(int a,int b); /* Declare a function with two arguments that returns an integer */
int twoargs(int ,int); /* Parameter names are optional in a prototype definition */
int anyargs(); /* An empty parameter list can be used to declare a function that accepts varargs */
int atleastoneargs(int, ...); /* One mandatory integer argument followed by varargs */


Function prototype

Solution:
// A prototype declaration for a function that does not require arguments
function List() {}

List.prototype.push = function() {
  return [].push.apply(this, arguments);
};

List.prototype.pop = function() {
  return [].pop.call(this);
};

var l = new List();
l.push(5);
l.length; // 1
l[0]; 5
l.pop(); // 5
l.length; // 0

// A prototype declaration for a function that utilizes varargs
function List() {
  this.push.apply(this, arguments);
}

List.prototype.push = function() {
  return [].push.apply(this, arguments);
};

List.prototype.pop = function() {
  return [].pop.call(this);
};

var l = new List(5, 10, 15);
l.length; // 3
l[0]; 5
l.pop(); // 15
l.length; // 2


Functional coverage tree

Functional coverage is a measure of how much a particular function of a system
has been verified as correct. It is used heavily in tracking the completeness
of the verification of complex System on Chip (SoC) integrated circuits, where
it can also be used to track how well the functional ''requirements'' of the
system have been verified.

This task uses a sub-set of the calculations sometimes used in tracking
functional coverage but uses a more familiar(?) scenario.

;Task Description:
The head of the clean-up crews for "The Men in a very dark shade of grey when
viewed at night" has been tasked with managing the cleansing of two properties
after an incident involving aliens.

She arranges the task hierarchically with a manager for the crews working on
each house who return with a breakdown of how they will report on progress in
each house.

The overall hierarchy of (sub)tasks is as follows,
cleaning
    house1
        bedrooms
        bathrooms
            bathroom1
            bathroom2
            outside lavatory
        attic
        kitchen
        living rooms
            lounge
            dining room
            conservatory
            playroom
        basement
        garage
        garden
    house2
        upstairs
            bedrooms
                suite 1
                suite 2
                bedroom 3
                bedroom 4
            bathroom
            toilet
            attics
        groundfloor
            kitchen
            living rooms
                lounge
                dining room
                conservatory
                playroom
            wet room & toilet
            garage
            garden
            hot tub suite
        basement
            cellars
            wine cellar
            cinema

The head of cleanup knows that her managers will report fractional completion of leaf tasks (tasks with no child tasks of their own), and she knows that she will want to modify the weight of values of completion as she sees fit.

Some time into the cleaning, and some coverage reports have come in and she thinks see needs to weight the big house2 60-40 with respect to coverage from house1 She prefers a tabular view of her data where missing weights are assumed to be 1.0 and missing coverage 0.0.
NAME_HIERARCHY                  |WEIGHT  |COVERAGE  |
cleaning                        |        |          |
    house1                      |40      |          |
        bedrooms                |        |0.25      |
        bathrooms               |        |          |
            bathroom1           |        |0.5       |
            bathroom2           |        |          |
            outside_lavatory    |        |1         |
        attic                   |        |0.75      |
        kitchen                 |        |0.1       |
        living_rooms            |        |          |
            lounge              |        |          |
            dining_room         |        |          |
            conservatory        |        |          |
            playroom            |        |1         |
        basement                |        |          |
        garage                  |        |          |
        garden                  |        |0.8       |
    house2                      |60      |          |
        upstairs                |        |          |
            bedrooms            |        |          |
                suite_1         |        |          |
                suite_2         |        |          |
                bedroom_3       |        |          |
                bedroom_4       |        |          |
            bathroom            |        |          |
            toilet              |        |          |
            attics              |        |0.6       |
        groundfloor             |        |          |
            kitchen             |        |          |
            living_rooms        |        |          |
                lounge          |        |          |
                dining_room     |        |          |
                conservatory    |        |          |
                playroom        |        |          |
            wet_room_&_toilet   |        |          |
            garage              |        |          |
            garden              |        |0.9       |
            hot_tub_suite       |        |1         |
        basement                |        |          |
            cellars             |        |1         |
            wine_cellar         |        |1         |
            cinema              |        |0.75      |

;Calculation:
The coverage of a node in the tree is calculated as the weighted average of the coverage of its children evaluated bottom-upwards in the tree.

'''The task is to''' calculate the overall coverage of the cleaning task and display the coverage at all levels of the hierarchy on this page, in a manner that visually shows the hierarchy, weights and coverage of all nodes.

;Extra Credit:
After calculating the coverage for all nodes, one can also calculate the additional/delta top level coverage that would occur if any (sub)task were to be fully covered from its current fractional coverage. This is done by multiplying the extra coverage that could be gained 1-coverage for any node, by the product of the `powers` of its parent nodes from the top down to the node.
The power of a direct child of any parent is given by the power of the parent multiplied by the weight of the child divided by the sum of the weights of all the direct children.

The pseudo code would be:

    method delta_calculation(this, power):
        sum_of_weights = sum(node.weight for node in children)
        this.delta  = (1 - this.coverage) * power
        for node in self.children:
            node.delta_calculation(power * node.weight / sum_of_weights)
        return this.delta

Followed by a call to:

    top.delta_calculation(power=1)

'''Note:''' to aid in getting the data into your program you might want to use an alternative, more functional description of the starting data given on the discussion page.

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

    // updatedCoverageOutline :: String -> String
    const updatedCoverageOutline = outlineText => {
        const
            delimiter = '|',
            indentedLines = indentLevelsFromLines(lines(outlineText)),
            columns = init(tokenizeWith(delimiter)(snd(indentedLines[0])));

        // SERIALISATION OF UPDATED PARSE TREE (TO NEW OUTLINE TEXT)
        return tabulation(delimiter)(
            columns.concat('SHARE OF RESIDUE\n')
        ) + unlines(
            indentedLinesFromTree(
                showCoverage(delimiter))('    ')(

                // TWO TRAVERSAL COMPUTATIONS

                withResidueShares(1.0)(
                    foldTree(weightedCoverage)(

                        // PARSE TREE (FROM OUTLINE TEXT)
                        fmapTree(compose(
                            partialRecord, tokenizeWith(delimiter)
                        ))(fst(
                            forestFromLineIndents(tail(indentedLines))
                        ))
                    )
                ))
        );
    };

    // TEST -----------------------------------------------
    // main :: IO ()
    const main = () =>
        console.log(
            // strOutline is included as literal text
            // at the foot of this code listing.
            updatedCoverageOutline(strOutline)
        );

    // COVERAGE AND SHARES OF RESIDUE ---------------------

    // weightedCoverage :: Dict -> Forest Dict -> Tree Dict
    const weightedCoverage = x => xs => {
        const
            cws = map(compose(
                fanArrow(x => x.coverage)(x => x.weight),
                root
            ))(xs),
            totalWeight = cws.reduce((a, tpl) => a + snd(tpl), 0);
        return Node(
            insertDict('coverage')(
                cws.reduce((a, tpl) => {
                    const [c, w] = Array.from(tpl);
                    return a + (c * w);
                }, x.coverage) / (
                    0 < totalWeight ? totalWeight : 1
                )
            )(x)
        )(xs);
    };

    // withResidueShares :: Float -> Tree Dict -> Tree Dict
    const withResidueShares = shareOfTotal => tree => {
        const go = fraction => node => {
            const
                nodeRoot = node.root,
                forest = node.nest,
                weights = forest.map(x => x.root.weight),
                weightTotal = sum(weights);
            return Node(
                insertDict('share')(
                    fraction * (1 - nodeRoot.coverage)
                )(nodeRoot)
            )(
                zipWith(go)(
                    weights.map(w => fraction * (w / weightTotal))
                )(forest)
            );
        };
        return go(shareOfTotal)(tree);
    };

    // OUTLINE PARSED TO TREE -----------------------------

    // forestFromLineIndents :: [(Int, String)] -> [Tree String]
    const forestFromLineIndents = tuples => {
        const go = xs =>
            0 < xs.length ? (() => {
                const [n, s] = Array.from(xs[0]);
                // Lines indented under this line,
                // tupled with all the rest.
                const [firstTreeLines, rest] = Array.from(
                    span(x => n < x[0])(xs.slice(1))
                );
                // This first tree, and then the rest.
                return [Node(s)(go(firstTreeLines))]
                    .concat(go(rest));
            })() : [];
        return go(tuples);
    };

    // indentLevelsFromLines :: [String] -> [(Int, String)]
    const indentLevelsFromLines = xs => {
        const
            indentTextPairs = xs.map(compose(
                firstArrow(length), span(isSpace)
            )),
            indentUnit = minimum(indentTextPairs.flatMap(pair => {
                const w = fst(pair);
                return 0 < w ? [w] : [];
            }));
        return indentTextPairs.map(
            firstArrow(flip(div)(indentUnit))
        );
    };

    // partialRecord :: [String] -> Dict
    const partialRecord = xs => {
        const [name, weightText, coverageText] = take(3)(
            xs.concat(['', '', ''])
        );
        return {
            name: name || '?',
            weight: parseFloat(weightText) || 1.0,
            coverage: parseFloat(coverageText) || 0.0,
            share: 0.0
        };
    };

    // tokenizeWith :: String -> String -> [String]
    const tokenizeWith = delimiter =>
        // A sequence of trimmed tokens obtained by
        // splitting s on the supplied delimiter.
        s => s.split(delimiter).map(x => x.trim());

    // TREE SERIALIZED TO OUTLINE -------------------------

    // indentedLinesFromTree :: (String -> a -> String) ->
    // String -> Tree a -> [String]
    const indentedLinesFromTree = showRoot =>
        strTab => tree => {
            const go = indent =>
                node => [showRoot(indent)(node.root)]
                .concat(node.nest.flatMap(go(strTab + indent)));
            return go('')(tree);
        };

    // showN :: Int -> Float -> String
    const showN = p =>
        n => justifyRight(7)(' ')(n.toFixed(p));

    // showCoverage :: String -> String -> Dict -> String
    const showCoverage = delimiter =>
        indent => x => tabulation(delimiter)(
            [indent + x.name, showN(0)(x.weight)]
            .concat([x.coverage, x.share].map(showN(4)))
        );

    // tabulation :: String -> [String] -> String
    const tabulation = delimiter =>
        // Up to 4 tokens drawn from the argument list,
        // as a single string with fixed left-justified
        // white-space widths, between delimiters.
        compose(
            intercalate(delimiter + ' '),
            zipWith(flip(justifyLeft)(' '))([31, 9, 9, 9])
        );

    // GENERIC AND REUSABLE FUNCTIONS ---------------------

    // Node :: a -> [Tree a] -> Tree a
    const Node = v => xs => ({
        type: 'Node',
        root: v, // any type of value (consistent across tree)
        nest: xs || []
    });

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

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (...fs) =>
        x => fs.reduceRight((a, f) => f(a), 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);
        })() : [];

    // div :: Int -> Int -> Int
    const div = x => y => Math.floor(x / y);

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

    // Compose a function from a simple value to a tuple of
    // the separate outputs of two different functions

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

    // Lift a simple function to one which applies to a tuple,
    // transforming only the first item of the tuple

    // firstArrow :: (a -> b) -> ((a, c) -> (b, c))
    const firstArrow = f => xy => Tuple(f(xy[0]))(
        xy[1]
    );

    // flip :: (a -> b -> c) -> b -> a -> c
    const flip = f =>
        1 < f.length ? (
            (a, b) => f(b, a)
        ) : (x => y => f(y)(x));

    // fmapTree :: (a -> b) -> Tree a -> Tree b
    const fmapTree = f => tree => {
        const go = node => Node(f(node.root))(
            node.nest.map(go)
        );
        return go(tree);
    };

    // foldTree :: (a -> [b] -> b) -> Tree a -> b
    const foldTree = f => tree => {
        const go = node => f(node.root)(
            node.nest.map(go)
        );
        return go(tree);
    };

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

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

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

    // insertDict :: String -> a -> Dict -> Dict
    const insertDict = k => v => dct =>
        Object.assign({}, dct, {
            [k]: v
        });

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

    // isSpace :: Char -> Bool
    const isSpace = c => /\s/.test(c);

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

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

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

    // lines :: String -> [String]
    const lines = s => s.split(/[\r\n]/);

    // map :: (a -> b) -> [a] -> [b]
    const map = f => xs =>
        (Array.isArray(xs) ? (
            xs
        ) : xs.split('')).map(f);

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

    // root :: Tree a -> a
    const root = tree => tree.root;

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

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

    // span :: (a -> Bool) -> [a] -> ([a], [a])
    const span = p => xs => {
        const iLast = xs.length - 1;
        return splitAt(
            until(i => iLast < i || !p(xs[i]))(
                succ
            )(0)
        )(xs);
    };

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

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

    // sum :: [Num] -> Num
    const sum = xs =>
        xs.reduce((a, x) => a + x, 0);

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

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

    // uncurry :: (a -> b -> c) -> ((a, b) -> c)
    const uncurry = f =>
        (x, y) => f(x)(y);

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

    // until :: (a -> Bool) -> (a -> a) -> a -> a
    const until = p => f => x => {
        let v = x;
        while (!p(v)) v = f(v);
        return v;
    };

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

    // SOURCE OUTLINE -----------------------------------------

    const strOutline = `NAME_HIERARCHY                  |WEIGHT  |COVERAGE  |
cleaning                        |        |          |
    house1                      |40      |          |
        bedrooms                |        |0.25      |
        bathrooms               |        |          |
            bathroom1           |        |0.5       |
            bathroom2           |        |          |
            outside_lavatory    |        |1         |
        attic                   |        |0.75      |
        kitchen                 |        |0.1       |
        living_rooms            |        |          |
            lounge              |        |          |
            dining_room         |        |          |
            conservatory        |        |          |
            playroom            |        |1         |
        basement                |        |          |
        garage                  |        |          |
        garden                  |        |0.8       |
    house2                      |60      |          |
        upstairs                |        |          |
            bedrooms            |        |          |
                suite_1         |        |          |
                suite_2         |        |          |
                bedroom_3       |        |          |
                bedroom_4       |        |          |
            bathroom            |        |          |
            toilet              |        |          |
            attics              |        |0.6       |
        groundfloor             |        |          |
            kitchen             |        |          |
            living_rooms        |        |          |
                lounge          |        |          |
                dining_room     |        |          |
                conservatory    |        |          |
                playroom        |        |          |
            wet_room_&_toilet   |        |          |
            garage              |        |          |
            garden              |        |0.9       |
            hot_tub_suite       |        |1         |
        basement                |        |          |
            cellars             |        |1         |
            wine_cellar         |        |1         |
            cinema              |        |0.75      |`;

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


Functional coverage tree

Solution:
from itertools import zip_longest

fc2 = '''\
cleaning,,
    house1,40,
        bedrooms,,.25
        bathrooms,,
            bathroom1,,.5
            bathroom2,,
            outside_lavatory,,1
        attic,,.75
        kitchen,,.1
        living_rooms,,
            lounge,,
            dining_room,,
            conservatory,,
            playroom,,1
        basement,,
        garage,,
        garden,,.8
    house2,60,
        upstairs,,
            bedrooms,,
                suite_1,,
                suite_2,,
                bedroom_3,,
                bedroom_4,,
            bathroom,,
            toilet,,
            attics,,.6
        groundfloor,,
            kitchen,,
            living_rooms,,
                lounge,,
                dining_room,,
                conservatory,,
                playroom,,
            wet_room_&_toilet,,
            garage,,
            garden,,.9
            hot_tub_suite,,1
        basement,,
            cellars,,1
            wine_cellar,,1
            cinema,,.75

'''

NAME, WT, COV = 0, 1, 2

def right_type(txt):
    try:
        return float(txt)
    except ValueError:
        return txt

def commas_to_list(the_list, lines, start_indent=0):
    '''
    Output format is a nest of lists and tuples
    lists are for coverage leaves without children items in the list are name, weight, coverage
    tuples are 2-tuples for nodes with children. The first element is a list representing the
    name, weight, coverage of the node (some to be calculated); the second element is a list of
    child elements which may be 2-tuples or lists as above.

    the_list is modified in-place
    lines must be a generator of successive lines of input like fc2
    '''
    for n, line in lines:
        indent = 0
        while line.startswith(' ' * (4 * indent)):
            indent += 1
        indent -= 1
        fields = [right_type(f) for f in line.strip().split(',')]
        if indent == start_indent:
            the_list.append(fields)
        elif indent > start_indent:
            lst = [fields]
            sub = commas_to_list(lst, lines, indent)
            the_list[-1] = (the_list[-1], lst)
            if sub not in (None, ['']) :
                the_list.append(sub)
        else:
            return fields if fields else None
    return None

def pptreefields(lst, indent=0, widths=['%-32s', '%-8g', '%-10g']):
    '''
    Pretty prints the format described from function commas_to_list as a table with
    names in the first column suitably indented and all columns having a fixed
    minimum column width.
    '''
    lhs = ' ' * (4 * indent)
    for item in lst:
        if type(item) != tuple:
            name, *rest = item
            print(widths[0] % (lhs + name), end='|')
            for width, item in zip_longest(widths[1:len(rest)], rest, fillvalue=widths[-1]):
                if type(item) == str:
                    width = width[:-1] + 's'
                print(width % item, end='|')
            print()
        else:
            item, children = item
            name, *rest = item
            print(widths[0] % (lhs + name), end='|')
            for width, item in zip_longest(widths[1:len(rest)], rest, fillvalue=widths[-1]):
                if type(item) == str:
                    width = width[:-1] + 's'
                print(width % item, end='|')
            print()
            pptreefields(children, indent+1)

def default_field(node_list):
    node_list[WT] = node_list[WT] if node_list[WT] else 1.0
    node_list[COV] = node_list[COV] if node_list[COV] else 0.0

def depth_first(tree, visitor=default_field):
    for item in tree:
        if type(item) == tuple:
            item, children = item
            depth_first(children, visitor)
        visitor(item)

def covercalc(tree):
    '''
    Depth first weighted average of coverage
    '''
    sum_covwt, sum_wt = 0, 0
    for item in tree:
        if type(item) == tuple:
            item, children = item
            item[COV] = covercalc(children)
        sum_wt  += item[WT]
        sum_covwt += item[COV] * item[WT]
    cov = sum_covwt / sum_wt
    return cov

if __name__ == '__main__':
    lstc = []
    commas_to_list(lstc, ((n, ln) for n, ln in enumerate(fc2.split('\n'))))
    #pp(lstc, width=1, indent=4, compact=1)

    #print('\n\nEXPANDED DEFAULTS\n')
    depth_first(lstc)
    #pptreefields(['NAME_HIERARCHY WEIGHT COVERAGE'.split()] + lstc)

    print('\n\nTOP COVERAGE = %f\n' % covercalc(lstc))
    depth_first(lstc)
    pptreefields(['NAME_HIERARCHY WEIGHT COVERAGE'.split()] + lstc)


Fusc sequence

;Definitions:
The   '''fusc'''   integer sequence is defined as:
::*   fusc(0) = 0
::*   fusc(1) = 1
::*   for '''n'''>1,   the   '''n'''th   term is defined as:
::::*   if   '''n'''   is       even;     fusc(n) = fusc(n/2)
::::*   if   '''n'''   is   odd;     fusc(n) = fusc((n-1)/2)   +   fusc((n+1)/2)

Note that MathWorld's definition starts with unity, not zero.   This task will be using the OEIS' version   (above).

;An observation:
:::::*   fusc(A) = fusc(B)

where   '''A'''   is some non-negative integer expressed in binary,   and
where   '''B'''   is the binary value of   '''A'''   reversed.

Fusc numbers are also known as:
::*   fusc function   (named by Dijkstra, 1982)
::*   Stern's Diatomic series   (although it starts with unity, not zero)
::*   Stern-Brocot sequence   (although it starts with unity, not zero)

;Task:
::*   show the first   '''61'''   fusc numbers (starting at zero) in a horizontal format.
::*   show the fusc number (and its index) whose length is greater than any previous fusc number length.
::::*   (the length is the number of decimal digits when the fusc number is expressed in base ten.)
::*   show all numbers with commas   (if appropriate).
::*   show all output here.

;Related task:
::*   RosettaCode Stern-Brocot sequence

;Also see:
::*   the MathWorld entry:   [http://mathworld.wolfram.com/SternsDiatomicSeries.html Stern's Diatomic Series].
::*   the OEIS      entry:   [http://oeis.org/A2487 A2487].

Solution:
#include
#include

int fusc(int n){
        if(n==0||n==1)
                return n;
        else if(n%2==0)
                return fusc(n/2);
        else
                return fusc((n-1)/2) + fusc((n+1)/2);
}

int numLen(int n){
        int sum = 1;

        while(n>9){
                n = n/10;
                sum++;
        }

        return sum;
}

void printLargeFuscs(int limit){
        int i,f,len,maxLen = 1;

        printf("\n\nPrinting all largest Fusc numbers upto %d \nIndex-------Value",limit);

        for(i=0;i<=limit;i++){
                f = fusc(i);
                len = numLen(f);

                if(len>maxLen){
                        maxLen = len;
                        printf("\n%5d%12d",i,f);
                }
        }
}

int main()
{
        int i;

        printf("Index-------Value");
        for(i=0;i<61;i++)
                printf("\n%5d%12d",i,fusc(i));
        printLargeFuscs(INT_MAX);
        return 0;
}


Fusc sequence

Solution:
from collections import deque
from itertools import islice, count

def fusc():
    q = deque([1])
    yield 0
    yield 1

    while True:
        x = q.popleft()
        q.append(x)
        yield x

        x += q[0]
        q.append(x)
        yield x

def longest_fusc():
    sofar = 0
    for i, f in zip(count(), fusc()):
        if f >= sofar:
            yield(i, f)
            sofar = 10 * sofar or 10

print('First 61:')
print(list(islice(fusc(), 61)))

print('\nLength records:')
for i, f in islice(longest_fusc(), 6):
    print(f'fusc({i}) = {f}')


Gapful numbers

Numbers   (positive integers expressed in base ten)   that are (evenly) divisible by the number formed by the
first and last digit are known as   '''gapful numbers'''.

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

All   one─   and two─digit   numbers have this property and are trivially excluded.   Only
numbers    ≥  '''100'''   will be considered for this Rosetta Code task.

;Example:
'''187'''   is a   '''gapful'''   number because it is evenly divisible by the
number   '''17'''   which is formed by the first and last decimal digits
of    '''187'''.

About   7.46%   of positive integers are   ''gapful''.

;Task:
:*   Generate and show all sets of numbers (below) on one line (horizontally) with a title,   here on this page
:*   Show the first   '''30'''   gapful numbers
:*   Show the first   '''15'''   gapful numbers    ≥           '''1,000,000'''
:*   Show the first   '''10'''   gapful numbers    ≥                               '''1,000,000,000'''

;Related tasks:
:*   [https://rosettacode.org/wiki/Harshad_or_Niven_series Harshad or Niven series].
:*   [https://rosettacode.org/wiki/Palindromic_gapful_numbers palindromic gapful numbers].
:*   [https://rosettacode.org/wiki/Largest_number_divisible_by_its_digits largest number divisible by its digits].

;Also see:
:*   The OEIS entry:   [https://oeis.org/A108343 A108343 gapful numbers].
:*   numbersaplenty [http://www.numbersaplenty.com/set/gapful_number/ gapful numbers]

Solution:
#include

void generateGaps(unsigned long long int start,int count){

    int counter = 0;
    unsigned long long int i = start;
    char str[100];

    printf("\nFirst %d Gapful numbers >= %llu :\n",count,start);

    while(counter
Output :
First 30 Gapful numbers >= 100 :

  1 : 100
  2 : 105
  3 : 108
  4 : 110
  5 : 120
  6 : 121
  7 : 130
  8 : 132
  9 : 135
 10 : 140
 11 : 143
 12 : 150
 13 : 154
 14 : 160
 15 : 165
 16 : 170
 17 : 176
 18 : 180
 19 : 187
 20 : 190
 21 : 192
 22 : 195
 23 : 198
 24 : 200
 25 : 220
 26 : 225
 27 : 231
 28 : 240
 29 : 242
 30 : 253

First 15 Gapful numbers >= 1000000 :

  1 : 1000000
  2 : 1000005
  3 : 1000008
  4 : 1000010
  5 : 1000016
  6 : 1000020
  7 : 1000021
  8 : 1000030
  9 : 1000032
 10 : 1000034
 11 : 1000035
 12 : 1000040
 13 : 1000050
 14 : 1000060
 15 : 1000065

First 15 Gapful numbers >= 1000000000 :

  1 : 1000000000
  2 : 1000000001
  3 : 1000000005
  4 : 1000000008
  5 : 1000000010
  6 : 1000000016
  7 : 1000000020
  8 : 1000000027
  9 : 1000000030
 10 : 1000000032
 11 : 1000000035
 12 : 1000000039
 13 : 1000000040
 14 : 1000000050
 15 : 1000000053


Gapful numbers

Solution:
// Function to construct a new integer from the first and last digits of another
function gapfulness_divisor (number) {
	var digit_string = number.toString(10)
	var digit_count = digit_string.length
	var first_digit = digit_string.substring(0, 1)
	var last_digit = digit_string.substring(digit_count - 1)
	return parseInt(first_digit.concat(last_digit), 10)
}

// Divisibility test to determine gapfulness
function is_gapful (number) {
	return number % gapfulness_divisor(number) == 0
}

// Function to search for the least gapful number greater than a given integer
function next_gapful (number) {
	do {
		++number
	} while (!is_gapful(number))
	return number
}

// Constructor for a list of gapful numbers starting from given lower bound
function gapful_numbers (start, amount) {
	var list = [], count = 0, number = start
	if (amount > 0 && is_gapful(start)) {
		list.push(start)
	}
	while (list.length < amount) {
		number = next_gapful(number)
		list.push(number)
	}
	return list
}

// Formatter for a comma-separated list of gapful numbers
function single_line_gapfuls (start, amount) {
	var list = gapful_numbers(start, amount)
	return list.join(", ")
}

// Windows console output wrapper
function print(message) {
	WScript.StdOut.WriteLine(message)
}

// Main algorithm

function print_gapfuls_with_header(start, amount) {
	print("First " + start + " gapful numbers starting at " + amount)
	print(single_line_gapfuls(start, amount))
}

print_gapfuls_with_header(100, 30)
print_gapfuls_with_header(1000000, 15)
print_gapfuls_with_header(1000000000, 10)


Gapful numbers

Solution:
from itertools import islice, count
for start, n in [(100, 30), (1_000_000, 15), (1_000_000_000, 10)]:
    print(f"\nFirst {n} gapful numbers from {start:_}")
    print(list(islice(( x for x in count(start)
                        if (x % (int(str(x)[0]) * 10 + (x % 10)) == 0) )
                      , n)))


Gauss-Jordan matrix inversion

;Task:
Invert matrix   '''A'''   using Gauss-Jordan method.

'''A'''   being an   '''n''' × '''n'''   matrix.

Solution:
/*----------------------------------------------------------------------
gjinv - Invert a matrix, Gauss-Jordan algorithm
A is destroyed.  Returns 1 for a singular matrix.

___Name_____Type______In/Out____Description_____________________________
   a[n*n]   double*   In        An N by N matrix
   n        int       In        Order of matrix
   b[n*n]   double*   Out       Inverse of A
----------------------------------------------------------------------*/
#include
int gjinv (double *a, int n, double *b)
{
	int i, j, k, p;
	double f, g, tol;
	if (n < 1) return -1;  /* Function Body */
	f = 0.;  /* Frobenius norm of a */
	for (i = 0; i < n; ++i) {
		for (j = 0; j < n; ++j) {
			g = a[j+i*n];
			f += g * g;
		}
	}
	f = sqrt(f);
	tol = f * 2.2204460492503131e-016;
	for (i = 0; i < n; ++i) {  /* Set b to identity matrix. */
		for (j = 0; j < n; ++j) {
			b[j+i*n] = (i == j) ? 1. : 0.;
		}
	}
	for (k = 0; k < n; ++k) {  /* Main loop */
		f = fabs(a[k+k*n]);  /* Find pivot. */
		p = k;
		for (i = k+1; i < n; ++i) {
			g = fabs(a[k+i*n]);
			if (g > f) {
				f = g;
				p = i;
			}
		}
		if (f < tol) return 1;  /* Matrix is singular. */
		if (p != k) {  /* Swap rows. */
			for (j = k; j < n; ++j) {
				f = a[j+k*n];
				a[j+k*n] = a[j+p*n];
				a[j+p*n] = f;
			}
			for (j = 0; j < n; ++j) {
				f = b[j+k*n];
				b[j+k*n] = b[j+p*n];
				b[j+p*n] = f;
			}
		}
		f = 1. / a[k+k*n];  /* Scale row so pivot is 1. */
		for (j = k; j < n; ++j) a[j+k*n] *= f;
		for (j = 0; j < n; ++j) b[j+k*n] *= f;
		for (i = 0; i < n; ++i) {  /* Subtract to get zeros. */
			if (i == k) continue;
			f = a[k+i*n];
			for (j = k; j < n; ++j) a[j+i*n] -= a[j+k*n] * f;
			for (j = 0; j < n; ++j) b[j+i*n] -= b[j+k*n] * f;
		}
	}
	return 0;
} /* end of gjinv */


Gauss-Jordan matrix inversion

Solution:
import numpy as np
from numpy.linalg import inv
a = np.array([[1., 2., 3.], [4., 1., 6.],[ 7., 8., 9.]])
ainv = inv(a)

print(a)
print(ainv)


Gaussian elimination

;Task:
Solve   '''Ax=b'''   using Gaussian elimination then backwards substitution.

'''A'''   being an   '''n''' by '''n'''   matrix.

Also,   '''x''' and '''b'''   are   '''n''' by '''1'''   vectors.

To improve accuracy, please use partial pivoting and scaling.

;See also:
:*   the Wikipedia entry:   Gaussian elimination

Solution:
#include
#include
#include

#define mat_elem(a, y, x, n) (a + ((y) * (n) + (x)))

void swap_row(double *a, double *b, int r1, int r2, int n)
{
	double tmp, *p1, *p2;
	int i;

	if (r1 == r2) return;
	for (i = 0; i < n; i++) {
		p1 = mat_elem(a, r1, i, n);
		p2 = mat_elem(a, r2, i, n);
		tmp = *p1, *p1 = *p2, *p2 = tmp;
	}
	tmp = b[r1], b[r1] = b[r2], b[r2] = tmp;
}

void gauss_eliminate(double *a, double *b, double *x, int n)
{
#define A(y, x) (*mat_elem(a, y, x, n))
	int i, j, col, row, max_row,dia;
	double max, tmp;

	for (dia = 0; dia < n; dia++) {
		max_row = dia, max = A(dia, dia);

		for (row = dia + 1; row < n; row++)
			if ((tmp = fabs(A(row, dia))) > max)
				max_row = row, max = tmp;

		swap_row(a, b, dia, max_row, n);

		for (row = dia + 1; row < n; row++) {
			tmp = A(row, dia) / A(dia, dia);
			for (col = dia+1; col < n; col++)
				A(row, col) -= tmp * A(dia, col);
			A(row, dia) = 0;
			b[row] -= tmp * b[dia];
		}
	}
	for (row = n - 1; row >= 0; row--) {
		tmp = b[row];
		for (j = n - 1; j > row; j--)
			tmp -= x[j] * A(row, j);
		x[row] = tmp / A(row, row);
	}
#undef A
}

int main(void)
{
	double a[] = {
		1.00, 0.00, 0.00,  0.00,  0.00, 0.00,
		1.00, 0.63, 0.39,  0.25,  0.16, 0.10,
		1.00, 1.26, 1.58,  1.98,  2.49, 3.13,
		1.00, 1.88, 3.55,  6.70, 12.62, 23.80,
		1.00, 2.51, 6.32, 15.88, 39.90, 100.28,
		1.00, 3.14, 9.87, 31.01, 97.41, 306.02
	};
	double b[] = { -0.01, 0.61, 0.91, 0.99, 0.60, 0.02 };
	double x[6];
	int i;

	gauss_eliminate(a, b, x, 6);

	for (i = 0; i < 6; i++)
		printf("%g\n", x[i]);

	return 0;


Gaussian elimination

Solution:
// Lower Upper Solver
function lusolve(A, b, update) {
	var lu = ludcmp(A, update)
	if (lu === undefined) return // Singular Matrix!
	return lubksb(lu, b, update)
}

// Lower Upper Decomposition
function ludcmp(A, update) {
	// A is a matrix that we want to decompose into Lower and Upper matrices.
	var d = true
	var n = A.length
	var idx = new Array(n) // Output vector with row permutations from partial pivoting
	var vv = new Array(n)  // Scaling information

	for (var i=0; i max) max = temp
		}
		if (max == 0) return // Singular Matrix!
		vv[i] = 1 / max // Scaling
	}

	if (!update) { // make a copy of A
		var Acpy = new Array(n)
		for (var i=0; i= max) {
				max = temp
				jmax = j
			}
		}
		if (i <= jmax) {
			for (var j=0; j -1)
			for (var j=ii; j=0; i--) {
		var sum = b[i]
		for (var j=i+1; j


Gaussian elimination

Solution:
# The 'gauss' function takes two matrices, 'a' and 'b', with 'a' square, and it return the determinant of 'a' and a matrix 'x' such that a*x = b.
# If 'b' is the identity, then 'x' is the inverse of 'a'.

import copy
from fractions import Fraction

def gauss(a, b):
    a = copy.deepcopy(a)
    b = copy.deepcopy(b)
    n = len(a)
    p = len(b[0])
    det = 1
    for i in range(n - 1):
        k = i
        for j in range(i + 1, n):
            if abs(a[j][i]) > abs(a[k][i]):
                k = j
        if k != i:
            a[i], a[k] = a[k], a[i]
            b[i], b[k] = b[k], b[i]
            det = -det

        for j in range(i + 1, n):
            t = a[j][i]/a[i][i]
            for k in range(i + 1, n):
                a[j][k] -= t*a[i][k]
            for k in range(p):
                b[j][k] -= t*b[i][k]

    for i in range(n - 1, -1, -1):
        for j in range(i + 1, n):
            t = a[i][j]
            for k in range(p):
                b[i][k] -= t*b[j][k]
        t = 1/a[i][i]
        det *= a[i][i]
        for j in range(p):
            b[i][j] *= t
    return det, b

def zeromat(p, q):
    return [[0]*q for i in range(p)]

def matmul(a, b):
    n, p = len(a), len(a[0])
    p1, q = len(b), len(b[0])
    if p != p1:
        raise ValueError("Incompatible dimensions")
    c = zeromat(n, q)
    for i in range(n):
        for j in range(q):
                c[i][j] = sum(a[i][k]*b[k][j] for k in range(p))
    return c

def mapmat(f, a):
    return [list(map(f, v)) for v in a]

def ratmat(a):
    return mapmat(Fraction, a)

# As an example, compute the determinant and inverse of 3x3 magic square

a = [[2, 9, 4], [7, 5, 3], [6, 1, 8]]
b = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
det, c = gauss(a, b)

det
-360.0

c
[[-0.10277777777777776, 0.18888888888888888, -0.019444444444444438],
[0.10555555555555554, 0.02222222222222223, -0.061111111111111116],
[0.0638888888888889, -0.14444444444444446, 0.14722222222222223]]

# Check product
matmul(a, c)
[[1.0, 0.0, 0.0], [5.551115123125783e-17, 1.0, 0.0],
[1.1102230246251565e-16, -2.220446049250313e-16, 1.0]]

# Same with fractions, so the result is exact

det, c = gauss(ratmat(a), ratmat(b))

det
Fraction(-360, 1)

c
[[Fraction(-37, 360), Fraction(17, 90), Fraction(-7, 360)],
[Fraction(19, 180), Fraction(1, 45), Fraction(-11, 180)],
[Fraction(23, 360), Fraction(-13, 90), Fraction(53, 360)]]

matmul(a, c)
[[Fraction(1, 1), Fraction(0, 1), Fraction(0, 1)],
[Fraction(0, 1), Fraction(1, 1), Fraction(0, 1)],
[Fraction(0, 1), Fraction(0, 1), Fraction(1, 1)]]


Generate Chess960 starting position

'''Bobby Fischer.  Unlike other variants of the game, Chess960 does not require a different material, but instead relies on a random initial position, with a few constraints:

* as in the standard chess game, all eight white pawns must be placed on the second rank.
* White pieces must stand on the first rank as in the standard game, in random column order but with the two following constraints:
** the bishops must be placed on opposite color squares (i.e. they must be an odd number of spaces apart or there must be an even number of spaces between them)
** the King must be between two rooks (with any number of other pieces between them all)
* Black pawns and pieces must be placed respectively on the seventh and eighth ranks, mirroring the white pawns and pieces, just as in the standard game.  (That is, their positions are not independently randomized.)

With those constraints there are '''960''' possible starting positions, thus the name of the variant.

;Task:
The purpose of this task is to write a program that can randomly generate any one of the 960 Chess960 initial positions. You will show the result as the first rank displayed with Chess symbols in Unicode: ♔♕♖♗♘ or with the letters '''K'''ing '''Q'''ueen '''R'''ook '''B'''ishop k'''N'''ight.

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

char rank[9];

int pos[8];

void swap(int i,int j){
	int temp = pos[i];
	pos[i] = pos[j];
	pos[j] = temp;
}

void generateFirstRank(){
	 int kPos,qPos,bPos1,bPos2,rPos1,rPos2,nPos1,nPos2,i;

	 for(i=0;i<8;i++){
		 rank[i] = 'e';
		 pos[i] = i;
	 }

	 do{
		 kPos = rand()%8;
		 rPos1 = rand()%8;
		 rPos2 = rand()%8;
	 }while((rPos1-kPos<=0 && rPos2-kPos<=0)||(rPos1-kPos>=0 && rPos2-kPos>=0)||(rPos1==rPos2 || kPos==rPos1 || kPos==rPos2));

	 rank[pos[rPos1]] = 'R';
	 rank[pos[kPos]] = 'K';
	 rank[pos[rPos2]] = 'R';

	 swap(rPos1,7);
	 swap(rPos2,6);
	 swap(kPos,5);

	 do{
		 bPos1 = rand()%5;
		 bPos2 = rand()%5;
	 }while(((pos[bPos1]-pos[bPos2])%2==0)||(bPos1==bPos2));

	 rank[pos[bPos1]] = 'B';
	 rank[pos[bPos2]] = 'B';

	 swap(bPos1,4);
	 swap(bPos2,3);

	 do{
		 qPos = rand()%3;
		 nPos1 = rand()%3;
	 }while(qPos==nPos1);

	 rank[pos[qPos]] = 'Q';
	 rank[pos[nPos1]] = 'N';

	 for(i=0;i<8;i++)
		 if(rank[i]=='e'){
			 rank[i] = 'N';
			 break;
		 }
}

void printRank(){
	int i;

	#ifdef _WIN32
		printf("%s\n",rank);
	#else
	{
		setlocale(LC_ALL,"");
		printf("\n");
		for(i=0;i<8;i++){
			if(rank[i]=='K')
				printf("%lc",(wint_t)9812);
			else if(rank[i]=='Q')
				printf("%lc",(wint_t)9813);
			else if(rank[i]=='R')
				printf("%lc",(wint_t)9814);
			else if(rank[i]=='B')
				printf("%lc",(wint_t)9815);
			if(rank[i]=='N')
				printf("%lc",(wint_t)9816);
		}
	}
	#endif
}

int main()
{
	int i;

	srand((unsigned)time(NULL));

	for(i=0;i<9;i++){
		generateFirstRank();
		printRank();
	}

	return 0;
}


Generate Chess960 starting position

Solution:
function ch960startPos() {
  var rank = new Array(8),
      // randomizer (our die)
      d = function(num) { return Math.floor(Math.random() * ++num) },
      emptySquares = function() {
        var arr = [];
        for (var i = 0; i < 8; i++) if (rank[i] == undefined) arr.push(i);
        return arr;
      };
  // place one bishop on any black square
  rank[d(2) * 2] = "♗";
  // place the other bishop on any white square
  rank[d(2) * 2 + 1] = "♗";
  // place the queen on any empty square
  rank[emptySquares()[d(5)]] = "♕";
  // place one knight on any empty square
  rank[emptySquares()[d(4)]] = "♘";
  // place the other knight on any empty square
  rank[emptySquares()[d(3)]] = "♘";
  // place the rooks and the king on the squares left, king in the middle
  for (var x = 1; x <= 3; x++) rank[emptySquares()[0]] = x==2 ? "♔" : "♖";
  return rank;
}

// testing (10 times)
for (var x = 1; x <= 10; x++) console.log(ch960startPos().join(" | "));


Generate Chess960 starting position

Solution:
from random import choice

def random960():
    start = ['R', 'K', 'R']         # Subsequent order unchanged by insertions.
    #
    for piece in ['Q', 'N', 'N']:
        start.insert(choice(range(len(start)+1)), piece)
    #
    bishpos = choice(range(len(start)+1))
    start.insert(bishpos, 'B')
    start.insert(choice(range(bishpos + 1, len(start) + 1, 2)), 'B')
    return start
    return ''.join(start).upper()

print(random960())


Generate random chess position

;Task:
Generate a random chess position in FEN format.

The position does not have to be realistic or even balanced,  but it must comply to the following rules:
:* there is one and only one king of each color  (one black king and one white king);
:* the kings must not be placed on adjacent squares;
:* there can not be any pawn in the promotion square  (no white pawn in the eighth rank, and no black pawn in the first rank);
:* including the kings, up to 32 pieces of either color can be placed.
:* There is no requirement for material balance between sides.
:* The picking of pieces does not have to comply to a regular chess set --- there can be five knights, twenty rooks, whatever ... as long as the total number of pieces do not exceed thirty-two.
:* it is white's turn.
:* It's assumed that both sides have lost castling rights and that there is no possibility for   ''en passant''   (the FEN should thus end in w - - 0 1).

No requirement is made regarding the probability distribution of your method, but your program should be able to span a reasonably representative sample of all possible positions.  For instance, programs that would always generate positions with say five pieces on the board, or with kings on a corner, would not be considered truly random.

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

#define TRUE 1
#define FALSE 0

typedef int bool;

char grid[8][8];

void placeKings() {
    int r1, r2, c1, c2;
    for (;;) {
        r1 = rand() % 8;
        c1 = rand() % 8;
        r2 = rand() % 8;
        c2 = rand() % 8;
        if (r1 != r2 && abs(r1 - r2) > 1 && abs(c1 - c2) > 1) {
            grid[r1][c1] = 'K';
            grid[r2][c2] = 'k';
            return;
        }
    }
}

void placePieces(const char *pieces, bool isPawn) {
    int n, r, c;
    int numToPlace = rand() % strlen(pieces);
    for (n = 0; n < numToPlace; ++n) {
        do {
            r = rand() % 8;
            c = rand() % 8;
        }
        while (grid[r][c] != 0 || (isPawn && (r == 7 || r == 0)));
        grid[r][c] = pieces[n];
    }
}

void toFen() {
    char fen[80], ch;
    int r, c, countEmpty = 0, index = 0;
    for (r = 0; r < 8; ++r) {
        for (c = 0; c < 8; ++c) {
            ch = grid[r][c];
            printf("%2c ", ch == 0 ? '.' : ch);
            if (ch == 0) {
                countEmpty++;
            }
            else {
                if (countEmpty > 0) {
                    fen[index++] = countEmpty + 48;
                    countEmpty = 0;
                }
                fen[index++] = ch;
            }
        }
        if (countEmpty > 0) {
            fen[index++] = countEmpty + 48;
            countEmpty = 0;
        }
        fen[index++]= '/';
        printf("\n");
    }
    strcpy(fen + index, " w - - 0 1");
    printf("%s\n", fen);
}

char *createFen() {
    placeKings();
    placePieces("PPPPPPPP", TRUE);
    placePieces("pppppppp", TRUE);
    placePieces("RNBQBNR", FALSE);
    placePieces("rnbqbnr", FALSE);
    toFen();
}

int main() {
    srand(time(NULL));
    createFen();
    return 0;
}


Generate random chess position

Solution:
Array.prototype.shuffle = function() {
  for (let i = this.length - 1; i > 0; i--) {
    let j = Math.floor(Math.random() * (i + 1));
    [this[i], this[j]] = [this[j], this[i]];
  }
}

function randomFEN() {

  let board = [];
  for (let x = 0; x < 8; x++) board.push('. . . . . . . .'.split(' '));

  function getRandPos() {
    return [Math.floor(Math.random() * 8), Math.floor(Math.random() * 8)];
  }

  function isOccupied(pos) {
    return board[pos[0]][pos[1]] != '.';
  }

  function isAdjacent(pos1, pos2) {
    if (pos1[0] == pos2[0] || pos1[0] == pos2[0]-1 || pos1[0] == pos2[0]+1)
    if (pos1[1] == pos2[1] || pos1[1] == pos2[1]-1 || pos1[1] == pos2[1]+1)
      return true;
    return false;
  }

  // place kings
  let wk, bk;
  do { wk = getRandPos(); bk = getRandPos(); }
  while (isAdjacent(wk, bk));
  board[wk[0]][wk[1]] = 'K';
  board[bk[0]][bk[1]] = 'k';

  // get peaces
  let peaces = [];
  let names = 'PRNBQ';
  function pick() {
    for (x = 1; x < Math.floor(Math.random() * 32); x++)
      peaces.push(names[Math.floor(Math.random() * names.length)]);
  }
  pick();
  names = names.toLowerCase();
  pick();
  peaces.shuffle();

  // place peaces
  while (peaces.length > 0) {
    let p = peaces.shift(), pos;
    // paws: cannot be placed in bottom or top row
    if (p == 'p' || p == 'P')
      do { pos = getRandPos() }
      while (isOccupied(pos) || pos[0] == 0 || pos[0] == 7);
    // everything else
    else do { pos = getRandPos(); } while (isOccupied(pos));
    board[pos[0]][pos[1]] = p;
  }

  // write FEN
  let fen = [];
  for (x = 0; x < board.length; x++) {
    let str ='', buf = 0;
    for (let y = 0; y < board[x].length; y++)
      if (board[x][y] == '.') buf++;
      else {
        if (buf > 0) { str += buf; buf = 0; }
        str += board[x][y];
      }
    if (buf > 0) str += buf;
    fen.push(str);
  }
  fen = fen.join('/') + ' w - - 0 1';
  console.table(board); // for demonstrating purpose
  return fen;
}

// example
console.log(randomFEN());


Generate random chess position

Solution:
import random

board = [[" " for x in range(8)] for y in range(8)]
piece_list = ["R", "N", "B", "Q", "P"]

def place_kings(brd):
	while True:
		rank_white, file_white, rank_black, file_black = random.randint(0,7), random.randint(0,7), random.randint(0,7), random.randint(0,7)
		diff_list = [abs(rank_white - rank_black),  abs(file_white - file_black)]
		if sum(diff_list) > 2 or set(diff_list) == set([0, 2]):
			brd[rank_white][file_white], brd[rank_black][file_black] = "K", "k"
			break

def populate_board(brd, wp, bp):
	for x in range(2):
		if x == 0:
			piece_amount = wp
			pieces = piece_list
		else:
			piece_amount = bp
			pieces = [s.lower() for s in piece_list]
		while piece_amount != 0:
			piece_rank, piece_file = random.randint(0, 7), random.randint(0, 7)
			piece = random.choice(pieces)
			if brd[piece_rank][piece_file] == " " and pawn_on_promotion_square(piece, piece_rank) == False:
				brd[piece_rank][piece_file] = piece
				piece_amount -= 1

def fen_from_board(brd):
	fen = ""
	for x in brd:
		n = 0
		for y in x:
			if y == " ":
				n += 1
			else:
				if n != 0:
					fen += str(n)
				fen += y
				n = 0
		if n != 0:
			fen += str(n)
		fen += "/" if fen.count("/") < 7 else ""
	fen += " w - - 0 1\n"
	return fen

def pawn_on_promotion_square(pc, pr):
	if pc == "P" and pr == 0:
		return True
	elif pc == "p" and pr == 7:
		return True
	return False

def start():
	piece_amount_white, piece_amount_black = random.randint(0, 15), random.randint(0, 15)
	place_kings(board)
	populate_board(board, piece_amount_white, piece_amount_black)
	print(fen_from_board(board))
	for x in board:
		print(x)

#entry point
start()


Generator/Exponential

[[Category:Non parametric generators]]
[[Category:Stateful transactions]]

A generator is an executable entity (like a function or procedure) that contains code that yields a sequence of values, one at a time, so that each time you call the generator, the next value in the sequence is provided.

Generators are often built on top of coroutines or objects so that the internal state of the object is handled “naturally”.

Generators are often used in situations where a sequence is potentially infinite, and where it is possible to construct the next value of the sequence with only minimal state.

;Task:
* Create a function that returns a generation of the m'th powers of the positive integers starting from zero, in order, and without obvious or simple upper limit. (Any upper limit to the generator should not be stated in the source but should be down to factors such as the languages natural integer size limit or computational time/size).
* Use it to create a generator of:
:::*   Squares.
:::*   Cubes.
* Create a new generator that filters all cubes from the generator of squares.
* Drop the first 20 values from this last generator of filtered results, and then show the next 10 values.

Note that this task ''requires'' the use of generators in the calculation of the result.

;Also see:
* Generator

Solution:
#include 	/* int64_t, PRId64 */
#include 	/* exit() */
#include 	/* printf() */

#include 	/* co_{active,create,delete,switch}() */

/* A generator that yields values of type int64_t. */
struct gen64 {
	cothread_t giver;	/* this cothread calls yield64() */
	cothread_t taker;	/* this cothread calls next64() */
	int64_t given;
	void (*free)(struct gen64 *);
	void *garbage;
};

/* Yields a value. */
inline void
yield64(struct gen64 *gen, int64_t value)
{
	gen->given = value;
	co_switch(gen->taker);
}

/* Returns the next value that the generator yields. */
inline int64_t
next64(struct gen64 *gen)
{
	gen->taker = co_active();
	co_switch(gen->giver);
	return gen->given;
}

static void
gen64_free(struct gen64 *gen)
{
	co_delete(gen->giver);
}

struct gen64 *entry64;

/*
 * Creates a cothread for the generator. The first call to next64(gen)
 * will enter the cothread; the entry function must copy the pointer
 * from the global variable struct gen64 *entry64.
 *
 * Use gen->free(gen) to free the cothread.
 */
inline void
gen64_init(struct gen64 *gen, void (*entry)(void))
{
	if ((gen->giver = co_create(4096, entry)) == NULL) {
		/* Perhaps malloc() failed */
		fputs("co_create: Cannot create cothread\n", stderr);
		exit(1);
	}
	gen->free = gen64_free;
	entry64 = gen;
}

/*
 * Generates the powers 0**m, 1**m, 2**m, ....
 */
void
powers(struct gen64 *gen, int64_t m)
{
	int64_t base, exponent, n, result;

	for (n = 0;; n++) {
		/*
		 * This computes result = base**exponent, where
		 * exponent is a nonnegative integer. The result
		 * is the product of repeated squares of base.
		 */
		base = n;
		exponent = m;
		for (result = 1; exponent != 0; exponent >>= 1) {
			if (exponent & 1) result *= base;
			base *= base;
		}
		yield64(gen, result);
	}
	/* NOTREACHED */
}

/* stuff for squares_without_cubes() */
#define ENTRY(name, code) static void name(void) { code; }
ENTRY(enter_squares, powers(entry64, 2))
ENTRY(enter_cubes, powers(entry64, 3))

struct swc {
	struct gen64 cubes;
	struct gen64 squares;
	void (*old_free)(struct gen64 *);
};

static void
swc_free(struct gen64 *gen)
{
	struct swc *f = gen->garbage;
	f->cubes.free(&f->cubes);
	f->squares.free(&f->squares);
	f->old_free(gen);
}

/*
 * Generates the squares 0**2, 1**2, 2**2, ..., but removes the squares
 * that equal the cubes 0**3, 1**3, 2**3, ....
 */
void
squares_without_cubes(struct gen64 *gen)
{
	struct swc f;
	int64_t c, s;

	gen64_init(&f.cubes, enter_cubes);
	c = next64(&f.cubes);

	gen64_init(&f.squares, enter_squares);
	s = next64(&f.squares);

	/* Allow other cothread to free this generator. */
	f.old_free = gen->free;
	gen->garbage = &f
	gen->free = swc_free;

	for (;;) {
		while (c < s)
			c = next64(&f.cubes);
		if (c != s)
			yield64(gen, s);
		s = next64(&f.squares);
	}
	/* NOTREACHED */
}

ENTRY(enter_squares_without_cubes, squares_without_cubes(entry64))

/*
 * Look at the sequence of numbers that are squares but not cubes.
 * Drop the first 20 numbers, then print the next 10 numbers.
 */
int
main()
{
	struct gen64 gen;
	int i;

	gen64_init(&gen, enter_squares_without_cubes);

	for (i = 0; i < 20; i++)
		next64(&gen);
	for (i = 0; i < 9; i++)
		printf("%" PRId64 ", ", next64(&gen));
	printf("%" PRId64 "\n", next64(&gen));

	gen.free(&gen); /* Free memory. */
	return 0;
}


Generator/Exponential

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

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

        // powers :: Gen [Int]
        const powers = n =>
            fmapGen(
                x => Math.pow(x, n),
                enumFrom(0)
            );

        // xs :: [Int]
        const xs = take(10, drop(20,
            differenceGen(
                powers(2),
                powers(3)
            )
        ));

        console.log(xs);
        // -> [529,576,625,676,784,841,900,961,1024,1089]
    };

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

    // Just :: a -> Maybe a
    const Just = x => ({
        type: 'Maybe',
        Nothing: false,
        Just: x
    });

    // Nothing :: Maybe a
    const Nothing = () => ({
        type: 'Maybe',
        Nothing: true,
    });

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

    // differenceGen :: Gen [a] -> Gen [a] -> Gen [a]
    function* differenceGen(ga, gb) {
        // All values of generator stream a except any
        // already seen in generator stream b.
        const
            stream = zipGen(ga, gb),
            sb = new Set([]);
        let xy = take(1, stream);
        while (0 < xy.length) {
            const [x, y] = Array.from(xy[0]);
            sb.add(y);
            if (!sb.has(x)) yield x;
            xy = take(1, stream);
        }
    };

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

    // enumFrom :: Enum a => a -> [a]
    function* enumFrom(x) {
        let v = x;
        while (true) {
            yield v;
            v = 1 + v;
        }
    }

    // fmapGen <$> :: (a -> b) -> Gen [a] -> Gen [b]
    function* fmapGen(f, gen) {
        let v = take(1, gen);
        while (0 < v.length) {
            yield(f(v[0]))
            v = take(1, gen)
        }
    }

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

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

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

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

    // uncons :: [a] -> Maybe (a, [a])
    const uncons = xs => {
        const lng = length(xs);
        return (0 < lng) ? (
            lng < Infinity ? (
                Just(Tuple(xs[0], xs.slice(1))) // Finite list
            ) : (() => {
                const nxt = take(1, xs);
                return 0 < nxt.length ? (
                    Just(Tuple(nxt[0], xs))
                ) : Nothing();
            })() // Lazy generator
        ) : Nothing();
    };

    // zipGen :: Gen [a] -> Gen [b] -> Gen [(a, b)]
    const zipGen = (ga, gb) => {
        function* go(ma, mb) {
            let
                a = ma,
                b = mb;
            while (!a.Nothing && !b.Nothing) {
                let
                    ta = a.Just,
                    tb = b.Just
                yield(Tuple(fst(ta), fst(tb)));
                a = uncons(snd(ta));
                b = uncons(snd(tb));
            }
        }
        return go(uncons(ga), uncons(gb));
    };

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


Generator/Exponential

Solution: In Python, any function that contains a yield statement becomes a generator. The standard libraries itertools module provides the following functions used in the solution: [http://docs.python.org/library/itertools.html#itertools.count count], that will count up from zero; and [http://docs.python.org/library/itertools.html#itertools.islice islice], which will take a slice from an iterator/generator.


Generator/Exponential

Solution:
from itertools import islice, count

def powers(m):
    for n in count():
        yield n ** m

def filtered(s1, s2):
    v, f = next(s1), next(s2)
    while True:
        if v > f:
            f = next(s2)
            continue
        elif v < f:
            yield v
        v = next(s1)

squares, cubes = powers(2), powers(3)
f = filtered(squares, cubes)
print(list(islice(f, 20, 30)))


Get system command output

;Task
Execute a system command and get its output into the program. The output may be stored in any kind of collection (array, list, etc.).

;Related task
*  Execute a system command

Solution:
#include
#include
#include

int main(int argc, char **argv)
{
    if (argc < 2) return 1;

    FILE *fd;
    fd = popen(argv[1], "r");
    if (!fd) return 1;

    char   buffer[256];
    size_t chread;
    /* String to store entire command contents in */
    size_t comalloc = 256;
    size_t comlen   = 0;
    char  *comout   = malloc(comalloc);

    /* Use fread so binary data is dealt with correctly */
    while ((chread = fread(buffer, 1, sizeof(buffer), fd)) != 0) {
        if (comlen + chread >= comalloc) {
            comalloc *= 2;
            comout = realloc(comout, comalloc);
        }
        memmove(comout + comlen, buffer, chread);
        comlen += chread;
    }

    /* We can now work with the output as we please. Just print
     * out to confirm output is as expected */
    fwrite(comout, 1, comlen, stdout);
    free(comout);
    pclose(fd);
    return 0;
}


Get system command output

Solution:
>>> import subprocess
>>> returned_text = subprocess.check_output("dir", shell=True, universal_newlines=True)
>>> type(returned_text)

>>> print(returned_text)
 Volume in drive C is Windows
 Volume Serial Number is 44X7-73CE

 Directory of C:\Python33

04/07/2013  06:40              .
04/07/2013  06:40              ..
27/05/2013  07:10              DLLs
27/05/2013  07:10              Doc
27/05/2013  07:10              include
27/05/2013  07:10              Lib
27/05/2013  07:10              libs
16/05/2013  00:15            33,326 LICENSE.txt
15/05/2013  22:49           214,554 NEWS.txt
16/05/2013  00:03            26,624 python.exe
16/05/2013  00:03            27,136 pythonw.exe
15/05/2013  22:49             6,701 README.txt
27/05/2013  07:10              tcl
27/05/2013  07:10              Tools
16/05/2013  00:02            43,008 w9xpopen.exe
               6 File(s)        351,349 bytes
               9 Dir(s)  46,326,947,840 bytes free

>>> # Ref: https://docs.python.org/3/library/subprocess.html


Giuga numbers

;Definition
A '''Giuga number''' is a composite number '''n''' which is such that each of its distinct prime factors
'''f''' divide (n/f - 1) exactly.

All known Giuga numbers are even though it is not known for certain that there are no odd examples.

;Example
30 is a Giuga number because its distinct prime factors are 2, 3 and 5 and:
* 30/2 - 1 = 14 is divisible by 2
* 30/3 - 1 = 9 is divisible by 3
* 30/5 - 1 = 5 is divisible by 5

;Task
Determine and show here the first four Giuga numbers.

;Stretch
Determine the fifth Giuga number and any more you have the patience for.

;References

* Wikipedia: Giuga number
* OEIS:A007850 - Giuga numbers

Solution:
#!/usr/bin/python

from math import sqrt

def isGiuga(m):
    n = m
    f = 2
    l = sqrt(n)
    while True:
        if n % f == 0:
            if ((m / f) - 1) % f != 0:
                return False
            n /= f
            if f > n:
                return True
        else:
            f += 1
            if f > l:
                return False

if __name__ == '__main__':
    n = 3
    c = 0
    print("The first 4 Giuga numbers are: ")
    while c < 4:
        if isGiuga(n):
            c += 1
            print(n)
        n += 1


Globally replace text in several files

;Task:
Replace every occurring instance of a piece of text in a group of text files with another one.

For this task we want to replace the text   "'''Goodbye London!'''"   with   "'''Hello New York!'''"   for a list of files.

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

char * find_match(const char *buf, const char * buf_end, const char *pat, size_t len)
{
	ptrdiff_t i;
	char *start = buf;
	while (start + len < buf_end) {
		for (i = 0; i < len; i++)
			if (start[i] != pat[i]) break;

		if (i == len) return (char *)start;
		start++;
	}
	return 0;
}

int replace(const char *from, const char *to, const char *fname)
{
#define bail(msg) { warn(msg" '%s'", fname); goto done; }
	struct stat st;
	int ret = 0;
	char *buf = 0, *start, *end;
	size_t len = strlen(from), nlen = strlen(to);
	int fd = open(fname, O_RDWR);

	if (fd == -1) bail("Can't open");
	if (fstat(fd, &st) == -1) bail("Can't stat");
	if (!(buf = malloc(st.st_size))) bail("Can't alloc");
	if (read(fd, buf, st.st_size) != st.st_size) bail("Bad read");

	start = buf;
	end = find_match(start, buf + st.st_size, from, len);
	if (!end) goto done; /* no match found, don't change file */

	ftruncate(fd, 0);
	lseek(fd, 0, 0);
	do {
		write(fd, start, end - start);	/* write content before match */
		write(fd, to, nlen);		/* write replacement of match */
		start = end + len;		/* skip to end of match */
						/* find match again */
		end = find_match(start, buf + st.st_size, from, len);
	} while (end);

	/* write leftover after last match */
	if (start < buf + st.st_size)
		write(fd, start, buf + st.st_size - start);

done:
	if (fd != -1) close(fd);
	if (buf) free(buf);
	return ret;
}

int main()
{
	const char *from = "Goodbye, London!";
	const char *to   = "Hello, New York!";
	const char * files[] = { "test1.txt", "test2.txt", "test3.txt" };
	int i;

	for (i = 0; i < sizeof(files)/sizeof(char*); i++)
		replace(from, to, files[i]);

	return 0;
}


Globally replace text in several files

Solution:
import fileinput

for line in fileinput.input(inplace=True):
    print(line.replace('Goodbye London!', 'Hello New York!'), end='')


Gotchas

;Definition
In programming, a '''gotcha''' is a valid construct in a system, program or programming language that works as documented but is counter-intuitive and almost invites mistakes because it is both easy to invoke and unexpected or unreasonable in its outcome.

;Task
Give an example or examples of common gotchas in your programming language and what, if anything, can be done to defend against it or them without using special tools.

Solution:
if(a=b){} //assigns to "a" the value of "b". Then, if "a" is nonzero, the code in the curly braces is run.

if(a==b){} //runs the code in the curly braces if and only if the value of "a" equals the value of "b".


Graph colouring

A Graph is a collection of nodes
(or vertices), connected by edges (or not).
Nodes directly connected by edges are called neighbours.

In our representation of graphs, nodes are numbered and edges are represented
by the two node numbers connected by the edge separated by a dash.
Edges define the nodes being connected. Only unconnected nodes ''need'' a separate
description.

For example,
0-1 1-2 2-0 3
Describes the following graph. Note that node 3 has no neighbours

;Example graph:

+---+
| 3 |
+---+

  +-------------------+
  |                   |
+---+     +---+     +---+
| 0 | --- | 1 | --- | 2 |
+---+     +---+     +---+

A useful internal datastructure for a graph and for later graph algorithms is
as a mapping between each node and the set/list of its neighbours.

In the above example:
0 maps-to 1 and 2
1 maps to 2 and 0
2 maps-to 1 and 0
3 maps-to

;Graph colouring task:
Colour the vertices of a given graph so that no edge is between verticies of
the same colour.

* Integers may be used to denote different colours.
* Algorithm should do better than just assigning each vertex a separate colour. The idea is to minimise the number of colours used, although no algorithm short of exhaustive search for the minimum is known at present, (and exhaustive search is '''not''' a requirement).
* Show for each edge, the colours assigned on each vertex.
* Show the total number of nodes, edges, and colours used for each graph.

;Use the following graphs:
;Ex1:

        0-1 1-2 2-0 3

+---+
| 3 |
+---+

  +-------------------+
  |                   |
+---+     +---+     +---+
| 0 | --- | 1 | --- | 2 |
+---+     +---+     +---+

;Ex2:
The wp articles left-side graph

    1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7

  +----------------------------------+
  |                                  |
  |                      +---+       |
  |    +-----------------| 3 | ------+----+
  |    |                 +---+       |    |
  |    |                   |         |    |
  |    |                   |         |    |
  |    |                   |         |    |
  |  +---+     +---+     +---+     +---+  |
  |  | 8 | --- | 1 | --- | 6 | --- | 4 |  |
  |  +---+     +---+     +---+     +---+  |
  |    |         |                   |    |
  |    |         |                   |    |
  |    |         |                   |    |
  |    |       +---+     +---+     +---+  |
  +----+------ | 7 | --- | 2 | --- | 5 | -+
       |       +---+     +---+     +---+
       |                   |
       +-------------------+

;Ex3:
The wp articles right-side graph which is the same graph as Ex2, but with
different node orderings and namings.

    1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6

  +----------------------------------+
  |                                  |
  |                      +---+       |
  |    +-----------------| 5 | ------+----+
  |    |                 +---+       |    |
  |    |                   |         |    |
  |    |                   |         |    |
  |    |                   |         |    |
  |  +---+     +---+     +---+     +---+  |
  |  | 8 | --- | 1 | --- | 4 | --- | 7 |  |
  |  +---+     +---+     +---+     +---+  |
  |    |         |                   |    |
  |    |         |                   |    |
  |    |         |                   |    |
  |    |       +---+     +---+     +---+  |
  +----+------ | 6 | --- | 3 | --- | 2 | -+
       |       +---+     +---+     +---+
       |                   |
       +-------------------+

;Ex4:
This is the same graph, node naming, and edge order as Ex2 except some of the edges x-y are flipped to y-x.
This might alter the node order used in the greedy algorithm leading to differing numbers of colours.

    1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7

                      +-------------------------------------------------+
                      |                                                 |
                      |                                                 |
  +-------------------+---------+                                       |
  |                   |         |                                       |
+---+     +---+     +---+     +---+     +---+     +---+     +---+     +---+
| 4 | --- | 5 | --- | 2 | --- | 7 | --- | 1 | --- | 6 | --- | 3 | --- | 8 |
+---+     +---+     +---+     +---+     +---+     +---+     +---+     +---+
  |         |                             |         |         |         |
  +---------+-----------------------------+---------+         |         |
            |                             |                   |         |
            |                             |                   |         |
            +-----------------------------+-------------------+         |
                                          |                             |
                                          |                             |
                                          +-----------------------------+

;References:
* Greedy coloring Wikipedia.
* [https://www.slideshare.net/PriyankJain26/graph-coloring-48222920 Graph Coloring : Greedy Algorithm & Welsh Powell Algorithm] by  Priyank Jain.

Solution:
import re
from collections import defaultdict
from itertools import count

connection_re = r"""
    (?: (?P\d+) - (?P\d+) | (?P\d+) (?!\s*-))
    """

class Graph:

    def __init__(self, name, connections):
        self.name = name
        self.connections = connections
        g = self.graph = defaultdict(list)  # maps vertex to direct connections

        matches = re.finditer(connection_re, connections,
                              re.MULTILINE | re.VERBOSE)
        for match in matches:
            n1, n2, n = match.groups()
            if n:
                g[n] += []
            else:
                g[n1].append(n2)    # Each the neighbour of the other
                g[n2].append(n1)

    def greedy_colour(self, order=None):
        "Greedy colourisation algo."
        if order is None:
            order = self.graph      # Choose something
        colour = self.colour = {}
        neighbours = self.graph
        for node in order:
            used_neighbour_colours = (colour[nbr] for nbr in neighbours[node]
                                      if nbr in colour)
            colour[node] = first_avail_int(used_neighbour_colours)
        self.pp_colours()
        return colour

    def pp_colours(self):
        print(f"\n{self.name}")
        c = self.colour
        e = canonical_edges = set()
        for n1, neighbours in sorted(self.graph.items()):
            if neighbours:
                for n2 in neighbours:
                    edge = tuple(sorted([n1, n2]))
                    if edge not in canonical_edges:
                        print(f"       {n1}-{n2}: Colour: {c[n1]}, {c[n2]}")
                        canonical_edges.add(edge)
            else:
                print(f"         {n1}: Colour: {c[n1]}")
        lc = len(set(c.values()))
        print(f"    #Nodes: {len(c)}\n    #Edges: {len(e)}\n  #Colours: {lc}")

def first_avail_int(data):
    "return lowest int 0... not in data"
    d = set(data)
    for i in count():
        if i not in d:
            return i

if __name__ == '__main__':
    for name, connections in [
            ('Ex1', "0-1 1-2 2-0 3"),
            ('Ex2', "1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7"),
            ('Ex3', "1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6"),
            ('Ex4', "1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7"),
            ]:
        g = Graph(name, connections)
        g.greedy_colour()


Gray code

Create functions to encode a number to and decode a number from Gray code.

Display the normal binary representations, Gray code representations, and decoded Gray code values for all 5-bit binary numbers (0-31 inclusive, leading 0's not necessary).

There are many possible Gray codes. The following encodes what is called "binary reflected Gray code."

Encoding (MSB is bit 0, b is binary, g is Gray code):

if b[i-1] = 1
   g[i] = not b[i]
else
   g[i] = b[i]

Or:

g = b xor (b logically right shifted 1 time)

Decoding (MSB is bit 0, b is binary, g is Gray code):

b[0] = g[0]

for other bits:
b[i] = g[i] xor b[i-1]

;Reference
* [http://www.wisc-online.com/Objects/ViewObject.aspx?ID=IAU8307 Converting Between Gray and Binary Codes]. It includes step-by-step animations.

Solution:
#include

/* Simple bool formatter, only good on range 0..31 */
void fmtbool(int n, char *buf) {
    char *b = buf + 5;
    *b=0;
    do {
	*--b = '0' + (n & 1);
	n >>= 1;
    } while (b != buf);
}

int main(int argc, char **argv) {
    int i,g,b;
    char bi[6],bg[6],bb[6];

    for (i=0 ; i<32 ; i++) {
	g = gray_encode(i);
	b = gray_decode(g);
	fmtbool(i,bi); fmtbool(g,bg); fmtbool(b,bb);
	printf("%2d : %5s => %5s => %5s : %2d\n", i, bi, bg, bb, b);
    }
    return 0;
}


Gray code

Solution:
def gray_encode(n):
    return n ^ n >> 1

def gray_decode(n):
    m = n >> 1
    while m:
        n ^= m
        m >>= 1
    return n

if __name__ == '__main__':
    print("DEC,   BIN =>  GRAY => DEC")
    for i in range(32):
        gray = gray_encode(i)
        dec = gray_decode(gray)
        print(f" {i:>2d}, {i:>05b} => {gray:>05b} => {dec:>2d}")


Greatest subsequential sum

[[Category:Arithmetic operations]]

;Task:
Given a sequence of integers, find a continuous subsequence which maximizes the sum of its elements, that is, the elements of no other single subsequence add up to a value larger than this one.

An empty subsequence is considered to have the sum of   '''0''';   thus if all elements are negative, the result must be the empty sequence.

Solution:
#include "stdio.h"

typedef struct Range {
    int start, end, sum;
} Range;

Range maxSubseq(const int sequence[], const int len) {
    int maxSum = 0, thisSum = 0, i = 0;
    int start = 0, end = -1, j;

    for (j = 0; j < len; j++) {
        thisSum += sequence[j];
        if (thisSum < 0) {
            i = j + 1;
            thisSum = 0;
        } else if (thisSum > maxSum) {
            maxSum = thisSum;
            start = i;
            end   = j;
        }
    }

    Range r;
    if (start <= end && start >= 0 && end >= 0) {
        r.start = start;
        r.end = end + 1;
        r.sum = maxSum;
    } else {
        r.start = 0;
        r.end = 0;
        r.sum = 0;
    }
    return r;
}

int main(int argc, char **argv) {
    int a[] = {-1 , -2 , 3 , 5 , 6 , -2 , -1 , 4 , -4 , 2 , -1};
    int alength = sizeof(a)/sizeof(a[0]);

    Range r = maxSubseq(a, alength);
    printf("Max sum = %d\n", r.sum);
    int i;
    for (i = r.start; i < r.end; i++)
        printf("%d ", a[i]);
    printf("\n");

    return 0;
}


Greatest subsequential sum

Solution:
(() => {

    // maxSubseq :: [Int] -> (Int, [Int])
    const maxSubseq = xs =>
        snd(xs.reduce((tpl, x) => {
            const [m1, m2] = Array.from(fst(tpl)),
                high = max(
                    Tuple(0, []),
                    Tuple(m1 + x, m2.concat(x))
                );
            return Tuple(high, max(snd(tpl), high));
        }, Tuple(Tuple(0, []), Tuple(0, []))));

    // TEST -----------------------------------------------
    // main :: IO ()
    const main = () => {
        const mx = maxSubseq([-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1]);
        showLog(snd(mx), fst(mx))
    }
    // [3,5,6,-2,-1,4] -> 15

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

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

    // gt :: Ord a => a -> a -> Bool
    const gt = (x, y) =>
        'Tuple' === x.type ? (
            x[0] > y[0]
        ) : (x > y);

    // max :: Ord a => a -> a -> a
    const max = (a, b) => gt(b, a) ? b : a;

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

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

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

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


Greatest subsequential sum

Solution:
f = maxsumit
assert f([]) == []
assert f([-1]) == []
assert f([0])  == []
assert f([1])       == [1]
assert f([1, 0])    == [1]
assert f([0, 1])    == [0, 1]
assert f([0, 1, 0]) == [0, 1]
assert f([2])         == [2]
assert f([2, -1])     == [2]
assert f([-1, 2])     == [2]
assert f([-1, 2, -1]) == [2]
assert f([2, -1, 3])         == [2, -1, 3]
assert f([2, -1, 3, -1])     == [2, -1, 3]
assert f([-1, 2, -1, 3])     == [2, -1, 3]
assert f([-1, 2, -1, 3, -1]) == [2, -1, 3]
assert f([-1, 1, 2, -5, -6]) == [1,2]