Terminal control/Unicode output

[[Category:Terminal control]]
[[Category:Unicode]]
The task is to check that the terminal supports Unicode output, before outputting a Unicode character. If the terminal supports Unicode, then the terminal should output a Unicode delta (U+25b3). If the terminal does not support Unicode, then an appropriate error should be raised.

Note that it is permissible to use system configuration data to determine terminal capabilities if the system provides such a facility.

Solution:
#include
#include

int
main ()
{
  int i;
  char *str = getenv ("LANG");

  for (i = 0; str[i + 2] != 00; i++)
    {
      if ((str[i] == 'u' && str[i + 1] == 't' && str[i + 2] == 'f')
          || (str[i] == 'U' && str[i + 1] == 'T' && str[i + 2] == 'F'))
        {
          printf
            ("Unicode is supported on this terminal and U+25B3 is : \u25b3");
          i = -1;
          break;
        }
    }

  if (i != -1)
    printf ("Unicode is not supported on this terminal.");

  return 0;
}


Terminal control/Unicode output

Solution:
import sys

if "UTF-8" in sys.stdout.encoding:
    print("△")
else:
    raise Exception("Terminal can't handle UTF-8")


Test integerness

Mathematically,
* the rational numbers '''Q''',
* which are included in the real numbers '''R''',
* which can be generalized to the complex numbers '''C'''.

This means that each of those larger sets, and the data types used to represent them, include some integers.

Given a rational, real, or complex number of any type, test whether it is mathematically an integer.

Your code should handle all numeric data types commonly used in your programming language.

Discuss any limitations of your code.

For the purposes of this task, integerness means that a number could theoretically be represented as an integer at no loss of precision ''(given an infinitely wide integer type)''.
In other words:

{| class="wikitable"
|-
! Set
! Common representation
! C++ type
! Considered an integer...
|-
| rational numbers '''Q'''
| fraction
| std::ratio
| ...if its denominator is 1 (in reduced form)
|-
| rowspan=2 | real numbers '''Z'''''(approximated)''
| fixed-point
|
| ...if it has no non-zero digits after the decimal point
|-
| floating-point
| float, double
| ...if the number of significant decimal places of its mantissa isn't greater than its exponent
|-
| complex numbers '''C'''
| pair of real numbers
| std::complex
| ...if its real part is considered an integer and its imaginary part is zero
|}

Optionally, make your code accept a tolerance parameter for fuzzy testing. The tolerance is the maximum amount by which the number may differ from the nearest integer, to still be considered an integer.

This is useful in practice, because when dealing with approximate numeric types (such as floating point), there may already be round-off errors from previous calculations. For example, a float value of 0.9999999998 might actually be intended to represent the integer 1.

{| class="wikitable"
|-
! colspan=2 | Input
! colspan=2 | Output
! rowspan=2 | Comment
|-
! Type
! Value
! exact
! tolerance = 0.00001
|-
| rowspan=3 | decimal
| 25.000000
| colspan=2 | true
|
|-
| 24.999999
| false
| true
|
|-
| 25.000100
| colspan=2 | false
|
|-
| rowspan=4 | floating-point
| -2.1e120
| colspan=2 | true
| This one is tricky, because in most languages it is too large to fit into a native integer type.It is, nonetheless, mathematically an integer, and your code should identify it as such.
|-
| -5e-2
| colspan=2 | false
|
|-
| NaN
| colspan=2 | false
|
|-
| Inf
| colspan=2 | false
| This one is debatable. If your code considers it an integer, that's okay too.
|-
| rowspan=2 | complex
| 5.0+0.0i
| colspan=2 | true
|
|-
| 5-5i
| colspan=2 | false
|
|}

(The types and notations shown in these tables are merely examples – you should use the native data types and number literals of your programming language and standard library. Use a different set of test-cases, if this one doesn't demonstrate all relevant behavior.)

Solution:
#include
#include
#include

/* Testing macros */
#define FMTSPEC(arg) _Generic((arg), \
    float: "%f", double: "%f", \
    long double: "%Lf", unsigned int: "%u", \
    unsigned long: "%lu", unsigned long long: "%llu", \
    int: "%d", long: "%ld", long long: "%lld", \
    default: "(invalid type (%p)")

#define CMPPARTS(x, y) ((long double complex)((long double)(x) + \
            I * (long double)(y)))

#define TEST_CMPL(i, j)\
    printf(FMTSPEC(i), i), printf(" + "), printf(FMTSPEC(j), j), \
    printf("i = %s\n", (isint(CMPPARTS(i, j)) ? "true" : "false"))

#define TEST_REAL(i)\
    printf(FMTSPEC(i), i), printf(" = %s\n", (isint(i) ? "true" : "false"))

/* Main code */
static inline int isint(long double complex n)
{
    return cimagl(n) == 0 && nearbyintl(creall(n)) == creall(n);
}

int main(void)
{
    TEST_REAL(0);
    TEST_REAL(-0);
    TEST_REAL(-2);
    TEST_REAL(-2.00000000000001);
    TEST_REAL(5);
    TEST_REAL(7.3333333333333);
    TEST_REAL(3.141592653589);
    TEST_REAL(-9.223372036854776e18);
    TEST_REAL(5e-324);
    TEST_REAL(NAN);
    TEST_CMPL(6, 0);
    TEST_CMPL(0, 1);
    TEST_CMPL(0, 0);
    TEST_CMPL(3.4, 0);

    /* Demonstrating that we can use the same function for complex values
     * constructed in the standard way */
    double complex test1 = 5 + 0*I,
                   test2 = 3.4f,
                   test3 = 3,
                   test4 = 0 + 1.2*I;

    printf("Test 1 (5+i) = %s\n", isint(test1) ? "true" : "false");
    printf("Test 2 (3.4+0i) = %s\n", isint(test2) ? "true" : "false");
    printf("Test 3 (3+0i) = %s\n", isint(test3) ? "true" : "false");
    printf("Test 4 (0+1.2i) = %s\n", isint(test4) ? "true" : "false");
}


Test integerness

Solution:
>>> def isint(f):
    return complex(f).imag == 0 and complex(f).real.is_integer()

>>> [isint(f) for f in (1.0, 2, (3.0+0.0j), 4.1, (3+4j), (5.6+0j))]
[True, True, True, False, False, False]

>>> # Test cases
...
>>> isint(25.000000)
True
>>> isint(24.999999)
False
>>> isint(25.000100)
False
>>> isint(-2.1e120)
True
>>> isint(-5e-2)
False
>>> isint(float('nan'))
False
>>> isint(float('inf'))
False
>>> isint(5.0+0.0j)
True
>>> isint(5-5j)
False


Textonyms

When entering text on a phone's digital pad it is possible that a particular combination of digits corresponds to more than one word. Such are called textonyms.

Assuming the digit keys are mapped to letters as follows:
     2 -> ABC
     3 -> DEF
     4 -> GHI
     5 -> JKL
     6 -> MNO
     7 -> PQRS
     8 -> TUV
     9 -> WXYZ

;Task:
Write a program that finds textonyms in a list of words such as
[[Textonyms/wordlist]]   or
[http://www.puzzlers.org/pub/wordlists/unixdict.txt unixdict.txt].

The task should produce a report:

 There are #{0} words in #{1} which can be represented by the digit key mapping.
 They require #{2} digit combinations to represent them.
 #{3} digit combinations represent Textonyms.

Where:
 #{0} is the number of words in the list which can be represented by the digit key mapping.
 #{1} is the URL of the wordlist being used.
 #{2} is the number of digit combinations required to represent the words in #{0}.
 #{3} is the number of #{2} which represent more than one word.

At your discretion show a couple of examples of your solution displaying Textonyms.

E.G.:

  2748424767 -> "Briticisms", "criticisms"

;Extra credit:
Use a word list and keypad mapping other than English.

Solution:
#include
#include
#include
#include

char text_char(char c) {
    switch (c) {
    case 'a': case 'b': case 'c':
        return '2';
    case 'd': case 'e': case 'f':
        return '3';
    case 'g': case 'h': case 'i':
        return '4';
    case 'j': case 'k': case 'l':
        return '5';
    case 'm': case 'n': case 'o':
        return '6';
    case 'p': case 'q': case 'r': case 's':
        return '7';
    case 't': case 'u': case 'v':
        return '8';
    case 'w': case 'x': case 'y': case 'z':
        return '9';
    default:
        return 0;
    }
}

bool text_string(const GString* word, GString* text) {
    g_string_set_size(text, word->len);
    for (size_t i = 0; i < word->len; ++i) {
        char c = text_char(g_ascii_tolower(word->str[i]));
        if (c == 0)
            return false;
        text->str[i] = c;
    }
    return true;
}

typedef struct textonym_tag {
    const char* text;
    size_t length;
    GPtrArray* words;
} textonym_t;

int compare_by_text_length(const void* p1, const void* p2) {
    const textonym_t* t1 = p1;
    const textonym_t* t2 = p2;
    if (t1->length > t2->length)
        return -1;
    if (t1->length < t2->length)
        return 1;
    return strcmp(t1->text, t2->text);
}

int compare_by_word_count(const void* p1, const void* p2) {
    const textonym_t* t1 = p1;
    const textonym_t* t2 = p2;
    if (t1->words->len > t2->words->len)
        return -1;
    if (t1->words->len < t2->words->len)
        return 1;
    return strcmp(t1->text, t2->text);
}

void print_words(GPtrArray* words) {
    for (guint i = 0, n = words->len; i < n; ++i) {
        if (i > 0)
            printf(", ");
        printf("%s", g_ptr_array_index(words, i));
    }
    printf("\n");
}

void print_top_words(GArray* textonyms, guint top) {
    for (guint i = 0; i < top; ++i) {
        const textonym_t* t = &g_array_index(textonyms, textonym_t, i);
        printf("%s = ", t->text);
        print_words(t->words);
    }
}

void free_strings(gpointer ptr) {
    g_ptr_array_free(ptr, TRUE);
}

bool find_textonyms(const char* filename, GError** error_ptr) {
    GError* error = NULL;
    GIOChannel* channel = g_io_channel_new_file(filename, "r", &error);
    if (channel == NULL) {
        g_propagate_error(error_ptr, error);
        return false;
    }
    GHashTable* ht = g_hash_table_new_full(g_str_hash, g_str_equal,
                                           g_free, free_strings);
    GString* word = g_string_sized_new(64);
    GString* text = g_string_sized_new(64);
    guint count = 0;
    gsize term_pos;
    while (g_io_channel_read_line_string(channel, word, &term_pos,
                                         &error) == G_IO_STATUS_NORMAL) {
        g_string_truncate(word, term_pos);
        if (!text_string(word, text))
            continue;
        GPtrArray* words = g_hash_table_lookup(ht, text->str);
        if (words == NULL) {
            words = g_ptr_array_new_full(1, g_free);
            g_hash_table_insert(ht, g_strdup(text->str), words);
        }
        g_ptr_array_add(words, g_strdup(word->str));
        ++count;
    }
    g_io_channel_unref(channel);
    g_string_free(word, TRUE);
    g_string_free(text, TRUE);
    if (error != NULL) {
        g_propagate_error(error_ptr, error);
        g_hash_table_destroy(ht);
        return false;
    }

    GArray* words = g_array_new(FALSE, FALSE, sizeof(textonym_t));
    GHashTableIter iter;
    gpointer key, value;
    g_hash_table_iter_init(&iter, ht);
    while (g_hash_table_iter_next(&iter, &key, &value)) {
        GPtrArray* v = value;
        if (v->len > 1) {
            textonym_t textonym;
            textonym.text = key;
            textonym.length = strlen(key);
            textonym.words = v;
            g_array_append_val(words, textonym);
        }
    }

    printf("There are %u words in '%s' which can be represented by the digit key mapping.\n",
           count, filename);
    guint size = g_hash_table_size(ht);
    printf("They require %u digit combinations to represent them.\n", size);
    guint textonyms = words->len;
    printf("%u digit combinations represent Textonyms.\n", textonyms);

    guint top = 5;
    if (textonyms < top)
        top = textonyms;

    printf("\nTop %u by number of words:\n", top);
    g_array_sort(words, compare_by_word_count);
    print_top_words(words, top);

    printf("\nTop %u by length:\n", top);
    g_array_sort(words, compare_by_text_length);
    print_top_words(words, top);

    g_array_free(words, TRUE);
    g_hash_table_destroy(ht);
    return true;
}

int main(int argc, char** argv) {
    if (argc != 2) {
        fprintf(stderr, "usage: %s word-list\n", argv[0]);
        return EXIT_FAILURE;
    }
    GError* error = NULL;
    if (!find_textonyms(argv[1], &error)) {
        if (error != NULL) {
            fprintf(stderr, "%s: %s\n", argv[1], error->message);
            g_error_free(error);
        }
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}


Textonyms

Solution:
from collections import defaultdict
import urllib.request

CH2NUM = {ch: str(num) for num, chars in enumerate('abc def ghi jkl mno pqrs tuv wxyz'.split(), 2) for ch in chars}
URL = 'http://www.puzzlers.org/pub/wordlists/unixdict.txt'

def getwords(url):
 return urllib.request.urlopen(url).read().decode("utf-8").lower().split()

def mapnum2words(words):
    number2words = defaultdict(list)
    reject = 0
    for word in words:
        try:
            number2words[''.join(CH2NUM[ch] for ch in word)].append(word)
        except KeyError:
            # Reject words with non a-z e.g. '10th'
            reject += 1
    return dict(number2words), reject

def interactiveconversions():
    global inp, ch, num
    while True:
        inp = input("\nType a number or a word to get the translation and textonyms: ").strip().lower()
        if inp:
            if all(ch in '23456789' for ch in inp):
                if inp in num2words:
                    print("  Number {0} has the following textonyms in the dictionary: {1}".format(inp, ', '.join(
                        num2words[inp])))
                else:
                    print("  Number {0} has no textonyms in the dictionary.".format(inp))
            elif all(ch in CH2NUM for ch in inp):
                num = ''.join(CH2NUM[ch] for ch in inp)
                print("  Word {0} is{1} in the dictionary and is number {2} with textonyms: {3}".format(
                    inp, ('' if inp in wordset else "n't"), num, ', '.join(num2words[num])))
            else:
                print("  I don't understand %r" % inp)
        else:
            print("Thank you")
            break

if __name__ == '__main__':
    words = getwords(URL)
    print("Read %i words from %r" % (len(words), URL))
    wordset = set(words)
    num2words, reject = mapnum2words(words)
    morethan1word = sum(1 for w in num2words if len(num2words[w]) > 1)
    maxwordpernum = max(len(values) for values in num2words.values())
    print("""
There are {0} words in {1} which can be represented by the Textonyms mapping.
They require {2} digit combinations to represent them.
{3} digit combinations represent Textonyms.\
""".format(len(words) - reject, URL, len(num2words), morethan1word))

    print("\nThe numbers mapping to the most words map to %i words each:" % maxwordpernum)
    maxwpn = sorted((key, val) for key, val in num2words.items() if len(val) == maxwordpernum)
    for num, wrds in maxwpn:
        print("  %s maps to: %s" % (num, ', '.join(wrds)))

    interactiveconversions()


The Name Game

Write a program that accepts a name as input and outputs the lyrics to the Shirley Ellis song "The Name Game".

The regular verse

Unless your name begins with a vowel (A, E, I, O, U), 'B', 'F' or 'M' you don't have to care about special rules.
The verse for the name 'Gary' would be like this:

    Gary, Gary, bo-bary
    Banana-fana fo-fary
    Fee-fi-mo-mary
    Gary!

At the end of every line, the name gets repeated without the first letter: Gary becomes ary
If we take (X) as the full name (Gary) and (Y) as the name without the first letter (ary) the verse would look like this:

    (X), (X), bo-b(Y)
    Banana-fana fo-f(Y)
    Fee-fi-mo-m(Y)
    (X)!

Vowel as first letter of the name

If you have a vowel as the first letter of your name (e.g. Earl) you do not truncate the name.
The verse looks like this:

    Earl, Earl, bo-bearl
    Banana-fana fo-fearl
    Fee-fi-mo-mearl
    Earl!

'B', 'F' or 'M' as first letter of the name

In case of a 'B', an 'F' or an 'M' (e.g. Billy, Felix, Mary) there is a special rule.
The line which would 'rebuild' the name (e.g. bo-billy) is sung without the first letter of the name.
The verse for the name Billy looks like this:

    Billy, Billy, bo-illy
    Banana-fana fo-filly
    Fee-fi-mo-milly
    Billy!

For the name 'Felix', this would be right:

    Felix, Felix, bo-belix
    Banana-fana fo-elix
    Fee-fi-mo-melix
    Felix!

Solution:
#include
#include

void print_verse(const char *name) {
    char *x, *y;
    int b = 1, f = 1, m = 1, i = 1;

    /* ensure name is in title-case */
    x = strdup(name);
    x[0] = toupper(x[0]);
    for (; x[i]; ++i) x[i] = tolower(x[i]);

    if (strchr("AEIOU", x[0])) {
        y = strdup(x);
        y[0] = tolower(y[0]);
    }
    else {
        y = x + 1;
    }

    switch(x[0]) {
        case 'B': b = 0; break;
        case 'F': f = 0; break;
        case 'M': m = 0; break;
        default : break;
    }

    printf("%s, %s, bo-%s%s\n", x, x, (b) ? "b" : "", y);
    printf("Banana-fana fo-%s%s\n", (f) ? "f" : "", y);
    printf("Fee-fi-mo-%s%s\n", (m) ? "m" : "", y);
    printf("%s!\n\n", x);
}

int main() {
    int i;
    const char *names[6] = {"gARY", "Earl", "Billy", "Felix", "Mary", "sHIRley"};
    for (i = 0; i < 6; ++i) print_verse(names[i]);
    return 0;
}


The Name Game

Solution:
function singNameGame(name) {

  // normalize name
  name = name.toLowerCase();
  name = name[0].toUpperCase() + name.slice(1);

  // ... and sometimes y
  // let's pray this works
  let firstVowelPos = (function() {
    let vowels =
      'aeiouàáâãäåæèéêëìíîïòóôõöøùúûüāăąēĕėęěĩīĭįıĳōŏőœũūŭůűų'
    .split('');
    function isVowel(char) {
      return vowels.indexOf(char) >= 0;
    }
    if (isVowel(name[0].toLowerCase())) return 0;
    if (name[0] == 'Y' && !isVowel(name[1])) return 0;
    if (name[0] == 'Y' && isVowel(name[1])) return 1;
    vowels = vowels.concat(vowels, 'yÿý'.split(''));
    for (let i = 1; i < name.length; i++)
      if (isVowel(name[i])) return i;
  })();

  let init  = name[0].toLowerCase(),
      trunk = name.slice(firstVowelPos).toLowerCase(),
      b = trunk, f = trunk, m = trunk;

  switch (init) {
    case 'b': f = 'f' + trunk; m = 'm' + trunk; break;
    case 'f': b = 'b' + trunk; m = 'm' + trunk; break;
    case 'm': b = 'b' + trunk; f = 'f' + trunk; break;
    default: b = 'b' + trunk; f = 'f' + trunk; m = 'm' + trunk;
  }

  return `
    ${name}, ${name}, bo-${b}
    Banana-fana fo-${f}
    Fee-fi-fo-mo-${m}
    ${name}!
  `
}

// testing
let names =
  'Gary Earl Billy Felix Mary Christine Brian Yvonne Yannick'.split(' ');
for (let i = 0; i < names.length; i++)
  document.write(singNameGame(names[i]));


The Name Game

Solution:
def print_verse(n):
    l = ['b', 'f', 'm']
    s = n[1:]
    if str.lower(n[0]) in l:
        l[l.index(str.lower(n[0]))] = ''
    elif n[0] in ['A', 'E', 'I', 'O', 'U']:
        s = str.lower(n)
    print('{0}, {0}, bo-{2}{1}\nBanana-fana fo-{3}{1}\nFee-fi-mo-{4}{1}\n{0}!\n'.format(n, s, *l))

# Assume that the names are in title-case and they're more than one character long
for n in ['Gary', 'Earl', 'Billy', 'Felix', 'Mary']:
    print_verse(n)


The Twelve Days of Christmas

;Task:
Write a program that outputs the lyrics of the Christmas carol ''The Twelve Days of Christmas''.
The lyrics can be found [http://www.lyricsmode.com/lyrics/c/christmas_carols/the_twelve_days_of_christmas.html here].

(You must reproduce the words in the correct order, but case, format, and punctuation are left to your discretion.)

Solution:
#include

int main()
{
    int i,j;

    char days[12][10] =
    {
        "First",
        "Second",
        "Third",
        "Fourth",
        "Fifth",
        "Sixth",
        "Seventh",
        "Eighth",
        "Ninth",
        "Tenth",
        "Eleventh",
        "Twelfth"
    };

    char gifts[12][33] =
    {
        "Twelve drummers drumming",
        "Eleven pipers piping",
        "Ten lords a-leaping",
        "Nine ladies dancing",
        "Eight maids a-milking",
        "Seven swans a-swimming",
        "Six geese a-laying",
        "Five golden rings",
        "Four calling birds",
        "Three french hens",
        "Two turtle doves",
        "And a partridge in a pear tree."
    };

    for(i=0;i<12;i++)
    {
        printf("\n\nOn the %s day of Christmas\nMy true love gave to me:",days[i]);

        for(j=i;j>=0;j--)
        {
            (i==0)?printf("\nA partridge in a pear tree."):printf("\n%s%c",gifts[11-j],(j!=0)?',':' ');
        }
    }

    return 0;
}


The Twelve Days of Christmas

Solution:
JSON.stringify(
  (function (
    strPrepn,
    strHoliday,
    strUnit,
    strRole,
    strProcess,
    strRecipient
  ) {
    var lstOrdinal =
      'first second third fourth fifth sixth\
           seventh eighth ninth tenth eleventh twelfth'
      .split(/\s+/),
      lngUnits = lstOrdinal.length,

      lstGoods =
      'A partridge in a pear tree.\
           Two turtle doves\
           Three french hens\
           Four calling birds\
           Five golden rings\
           Six geese a-laying\
           Seven swans a-swimming\
           Eight maids a-milking\
           Nine ladies dancing\
           Ten lords a-leaping\
           Eleven pipers piping\
           Twelve drummers drumming'
      .split(/\s{2,}/),

      lstReversed = (function () {
        var lst = lstGoods.slice(0);
        return (lst.reverse(), lst);
      })(),

      strProvenance = [strRole, strProcess, strRecipient + ':'].join(' '),

      strPenultimate = lstReversed[lngUnits - 2] + ' and',
      strFinal = lstGoods[0];

    return lstOrdinal.reduce(
      function (sofar, day, i) {
        return sofar.concat(
          [
            [
              [ // abstraction of line 1
                strPrepn,
                'the',
                lstOrdinal[i],
                strUnit,
                'of',
                strHoliday
              ].join(' '),
              strProvenance
            ].concat( // reversed descent through memory
              (i > 1 ? [lstGoods[i]] : []).concat(
                lstReversed.slice(
                  lngUnits - i,
                  lngUnits - 2
                )
              ).concat( // penultimate line ends with 'and'
                [
                  strPenultimate,
                  strFinal
                ].slice(i ? 0 : 1)
              )
            )
          ]
        );
      }, []
    );
  })(
    'On', 'Christmas', 'day', 'my true love', 'gave to', 'me'
  ), null, 2
);


The Twelve Days of Christmas

Solution:
gifts = '''\
A partridge in a pear tree.
Two turtle doves
Three french hens
Four calling birds
Five golden rings
Six geese a-laying
Seven swans a-swimming
Eight maids a-milking
Nine ladies dancing
Ten lords a-leaping
Eleven pipers piping
Twelve drummers drumming'''.split('\n')

days = '''first second third fourth fifth
          sixth seventh eighth ninth tenth
          eleventh twelfth'''.split()

for n, day in enumerate(days, 1):
    g = gifts[:n][::-1]
    print(('\nOn the %s day of Christmas\nMy true love gave to me:\n' % day) +
          '\n'.join(g[:-1]) +
          (' and\n' + g[-1] if n > 1 else g[-1].capitalize()))


Thue-Morse

;Task:
Create a [http://en.wikipedia.org/wiki/Thue%E2%80%93Morse_sequence Thue-Morse sequence].

;See also
*   YouTube entry: [https://www.youtube.com/watch?v=prh72BLNjIk The Fairest Sharing Sequence Ever]
*   YouTube entry: [https://www.youtube.com/watch?v=Tt5TTid6YXk Math and OCD - My story with the Thue-Morse sequence]
*   Task: [[Fairshare between two and more]]

Solution:
#include
#include
#include

int main(int argc, char *argv[]){
	char sequence[256+1] = "0";
	char inverse[256+1] = "1";
	char buffer[256+1];
	int i;

	for(i = 0; i < 8; i++){
		strcpy(buffer, sequence);
		strcat(sequence, inverse);
		strcat(inverse, buffer);
	}

	puts(sequence);
	return 0;
}


Thue-Morse

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

    // thueMorsePrefixes :: () -> [[Int]]
    const thueMorsePrefixes = () =>
        iterate(
            ap(append)(
                map(x => 1 - x)
            )
        )([0]);

    // ----------------------- TEST -----------------------
    const main = () =>
        // Fifth iteration.
        // 2 ^ 5 = 32 terms of the Thue-Morse sequence.
        showList(
            index(thueMorsePrefixes())(
                5
            )
        );

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

    // ap :: (a -> b -> c) -> (a -> b) -> a -> c
    const ap = f =>
        // Applicative instance for functions.
        // f(x) applied to g(x).
        g => x => f(x)(
            g(x)
        );

    // append (++) :: [a] -> [a] -> [a]
    // append (++) :: String -> String -> String
    const append = xs =>
        // A list or string composed by
        // the concatenation of two others.
        ys => xs.concat(ys);

    // index (!!) :: Generator (Int, a) -> Int -> Maybe a
    const index = xs =>
        i => (take(i)(xs), xs.next().value);

    // iterate :: (a -> a) -> a -> Gen [a]
    const iterate = f =>
        function*(x) {
            let v = x;
            while (true) {
                yield(v);
                v = f(v);
            }
        };

    // map :: (a -> b) -> [a] -> [b]
    const map = f =>
        // The list obtained by applying f
        // to each element of xs.
        // (The image of xs under f).
        xs => xs.map(f);

    // showList :: [a] -> String
    const showList = xs =>
        '[' + xs.map(x => x.toString())
        .join(',')
        .replace(/[\"]/g, '') + ']';

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = n =>
        // The first n elements of a list,
        // string of characters, or stream.
        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];
        }));

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


Thue-Morse

Solution:
m='0'
print(m)
for i in range(0,6):
     m0=m
     m=m.replace('0','a')
     m=m.replace('1','0')
     m=m.replace('a','1')
     m=m0+m
     print(m)


Tonelli-Shanks algorithm

In computational number theory, the Tonelli–Shanks algorithm is a technique for solving for '''x''' in a congruence of the form:

:: x2 ≡ n (mod p)

where '''n''' is an integer which is a quadratic residue (mod p), '''p''' is an odd prime, and '''x,n ∈ Fp''' where Fp = {0, 1, ..., p - 1}.

It is used in [https://en.wikipedia.org/wiki/Rabin_cryptosystem cryptography] techniques.

To apply the algorithm, we need the Legendre symbol:

The Legendre symbol '''(a | p)''' denotes the value of a(p-1)/2 (mod p).
* '''(a | p) ≡ 1'''    if '''a''' is a square (mod p)
* '''(a | p) ≡ -1'''    if '''a''' is not a square (mod p)
* '''(a | p) ≡ 0'''    if '''a''' ≡ 0 (mod p)

;Algorithm pseudo-code:

All ≡ are taken to mean (mod p) unless stated otherwise.

* Input: '''p''' an odd prime, and an integer '''n''' .
* Step 0: Check that '''n''' is indeed a square: (n | p) must be ≡ 1 .
* Step 1: By factoring out powers of 2 from p - 1, find '''q''' and '''s''' such that p - 1 = q2s with '''q''' odd .
** If p ≡ 3 (mod 4) (i.e. s = 1), output the two solutions r ≡ ± n(p+1)/4 .
* Step 2: Select a non-square '''z''' such that (z | p) ≡ -1 and set c ≡  zq .
* Step 3: Set r ≡ n(q+1)/2, t ≡ nq, m = s .
* Step 4: Loop the following:
** If t ≡ 1, output '''r''' and '''p - r''' .
** Otherwise find, by repeated squaring, the lowest '''i''', 0 < i < m , such that t2i ≡ 1 .
** Let b ≡ c2(m - i - 1), and set r ≡ rb, t ≡ tb2, c ≡ b2 and m = i .

;Task:
Implement the above algorithm.

Find solutions (if any) for
* n = 10 p = 13
* n = 56 p = 101
* n = 1030 p = 10009
* n = 1032 p = 10009
* n = 44402 p = 100049

;Extra credit:
* n  =    665820697     p  =   1000000009
* n  =   881398088036     p   =  1000000000039
* n  =  41660815127637347468140745042827704103445750172002   p  = 10^50 + 577

;See also:
* [[Modular exponentiation]]
* [[Cipolla's algorithm]]

Solution:
#include
#include
#include

uint64_t modpow(uint64_t a, uint64_t b, uint64_t n) {
    uint64_t x = 1, y = a;
    while (b > 0) {
        if (b % 2 == 1) {
            x = (x * y) % n; // multiplying with base
        }
        y = (y * y) % n; // squaring the base
        b /= 2;
    }
    return x % n;
}

struct Solution {
    uint64_t root1, root2;
    bool exists;
};

struct Solution makeSolution(uint64_t root1, uint64_t root2, bool exists) {
    struct Solution sol;
    sol.root1 = root1;
    sol.root2 = root2;
    sol.exists = exists;
    return sol;
}

struct Solution ts(uint64_t n, uint64_t p) {
    uint64_t q = p - 1;
    uint64_t ss = 0;
    uint64_t z = 2;
    uint64_t c, r, t, m;

    if (modpow(n, (p - 1) / 2, p) != 1) {
        return makeSolution(0, 0, false);
    }

    while ((q & 1) == 0) {
        ss += 1;
        q >>= 1;
    }

    if (ss == 1) {
        uint64_t r1 = modpow(n, (p + 1) / 4, p);
        return makeSolution(r1, p - r1, true);
    }

    while (modpow(z, (p - 1) / 2, p) != p - 1) {
        z++;
    }

    c = modpow(z, q, p);
    r = modpow(n, (q + 1) / 2, p);
    t = modpow(n, q, p);
    m = ss;

    while (true) {
        uint64_t i = 0, zz = t;
        uint64_t b = c, e;
        if (t == 1) {
            return makeSolution(r, p - r, true);
        }
        while (zz != 1 && i < (m - 1)) {
            zz = zz * zz % p;
            i++;
        }
        e = m - i - 1;
        while (e > 0) {
            b = b * b % p;
            e--;
        }
        r = r * b % p;
        c = b * b % p;
        t = t * c % p;
        m = i;
    }
}

void test(uint64_t n, uint64_t p) {
    struct Solution sol = ts(n, p);
    printf("n = %llu\n", n);
    printf("p = %llu\n", p);
    if (sol.exists) {
        printf("root1 = %llu\n", sol.root1);
        printf("root2 = %llu\n", sol.root2);
    } else {
        printf("No solution exists\n");
    }
    printf("\n");
}

int main() {
    test(10, 13);
    test(56, 101);
    test(1030, 10009);
    test(1032, 10009);
    test(44402, 100049);

    return 0;
}


Tonelli-Shanks algorithm

Solution:
def legendre(a, p):
    return pow(a, (p - 1) // 2, p)

def tonelli(n, p):
    assert legendre(n, p) == 1, "not a square (mod p)"
    q = p - 1
    s = 0
    while q % 2 == 0:
        q //= 2
        s += 1
    if s == 1:
        return pow(n, (p + 1) // 4, p)
    for z in range(2, p):
        if p - 1 == legendre(z, p):
            break
    c = pow(z, q, p)
    r = pow(n, (q + 1) // 2, p)
    t = pow(n, q, p)
    m = s
    t2 = 0
    while (t - 1) % p != 0:
        t2 = (t * t) % p
        for i in range(1, m):
            if (t2 - 1) % p == 0:
                break
            t2 = (t2 * t2) % p
        b = pow(c, 1 << (m - i - 1), p)
        r = (r * b) % p
        c = (b * b) % p
        t = (t * c) % p
        m = i
    return r

if __name__ == '__main__':
    ttest = [(10, 13), (56, 101), (1030, 10009), (44402, 100049),
	     (665820697, 1000000009), (881398088036, 1000000000039),
             (41660815127637347468140745042827704103445750172002, 10**50 + 577)]
    for n, p in ttest:
        r = tonelli(n, p)
        assert (r * r - n) % p == 0
        print("n = %d p = %d" % (n, p))
        print("\t  roots : %d %d" % (r, p - r))


Top rank per group

;Task:
Find the top   ''N''   salaries in each department,   where   ''N''   is provided as a parameter.

Use this data as a formatted internal data structure (adapt it to your language-native idioms, rather than parse at runtime), or identify your external data source:

Employee Name,Employee ID,Salary,Department
Tyler Bennett,E10297,32000,D101
John Rappl,E21437,47000,D050
George Woltman,E00127,53500,D101
Adam Smith,E63535,18000,D202
Claire Buckman,E39876,27800,D202
David McClellan,E04242,41500,D101
Rich Holcomb,E01234,49500,D202
Nathan Adams,E41298,21900,D050
Richard Potter,E43128,15900,D101
David Motsinger,E27002,19250,D202
Tim Sampair,E03033,27000,D101
Kim Arlich,E10001,57000,D190
Timothy Grove,E16398,29900,D190

Solution:
#include
#include
#include

typedef struct {
    const char *name, *id, *dept;
    int sal;
} person;

person ppl[] = {
    {"Tyler Bennett",   "E10297", "D101", 32000},
    {"John Rappl",      "E21437", "D050", 47000},
    {"George Woltman",  "E00127", "D101", 53500},
    {"Adam Smith",      "E63535", "D202", 18000},
    {"Claire Buckman",  "E39876", "D202", 27800},
    {"David McClellan", "E04242", "D101", 41500},
    {"Rich Holcomb",    "E01234", "D202", 49500},
    {"Nathan Adams",    "E41298", "D050", 21900},
    {"Richard Potter",  "E43128", "D101", 15900},
    {"David Motsinger", "E27002", "D202", 19250},
    {"Tim Sampair",     "E03033", "D101", 27000},
    {"Kim Arlich",      "E10001", "D190", 57000},
    {"Timothy Grove",   "E16398", "D190", 29900},
};

int pcmp(const void *a, const void *b)
{
    const person *aa = a, *bb = b;
    int x = strcmp(aa->dept, bb->dept);
    if (x) return x;
    return aa->sal > bb->sal ? -1 : aa->sal < bb->sal;
}

#define N sizeof(ppl)/sizeof(person)
void top(int n)
{
    int i, rank;
    qsort(ppl, N, sizeof(person), pcmp);

    for (i = rank = 0; i < N; i++) {
        if (i && strcmp(ppl[i].dept, ppl[i - 1].dept)) {
            rank = 0;
            printf("\n");
        }

        if (rank++ < n)
            printf("%s %d: %s\n", ppl[i].dept, ppl[i].sal, ppl[i].name);
    }
}

int main()
{
    top(2);
    return 0;


Top rank per group

Solution:
var data = [
    {name: "Tyler Bennett",   id: "E10297", salary: 32000, dept: "D101"},
    {name: "John Rappl",      id: "E21437", salary: 47000, dept: "D050"},
    {name: "George Woltman",  id: "E00127", salary: 53500, dept: "D101"},
    {name: "Adam Smith",      id: "E63535", salary: 18000, dept: "D202"},
    {name: "Claire Buckman",  id: "E39876", salary: 27800, dept: "D202"},
    {name: "David McClellan", id: "E04242", salary: 41500, dept: "D101"},
    {name: "Rich Holcomb",    id: "E01234", salary: 49500, dept: "D202"},
    {name: "Nathan Adams",    id: "E41298", salary: 21900, dept: "D050"},
    {name: "Richard Potter",  id: "E43128", salary: 15900, dept: "D101"},
    {name: "David Motsinger", id: "E27002", salary: 19250, dept: "D202"},
    {name: "Tim Sampair",     id: "E03033", salary: 27000, dept: "D101"},
    {name: "Kim Arlich",      id: "E10001", salary: 57000, dept: "D190"},
    {name: "Timothy Grove",   id: "E16398", salary: 29900, dept: "D190"},
];

function top_rank(n) {
    var by_dept = group_by_dept(data);
    for (var dept in by_dept) {
        output(dept);
        for (var i = 0; i < n && i < by_dept[dept].length; i++) {
            var emp = by_dept[dept][i];
            output(emp.name + ", id=" + emp.id + ", salary=" + emp.salary);
        }
        output("");
    }
}

// group by dept, and sort by salary
function group_by_dept(data) {
    var by_dept = {};
    for (var idx in data)  {
        var dept = data[idx].dept;
        if ( ! has_property(by_dept, dept)) {
            by_dept[dept] = new Array();
        }
        by_dept[dept].push(data[idx]);
    }
    for (var dept in by_dept) {
        // numeric sort
        by_dept[dept].sort(function (a,b){return b.salary - a.salary});
    }
    return by_dept;
}

function has_property(obj, propname) {
    return typeof(obj[propname]) != "undefined";
}

function output(str) {
    try {
        WScript.Echo(str);  // WSH
    } catch(err) {
        print(str);  // Rhino
    }
}

top_rank(3);


Top rank per group

Solution:
from collections import defaultdict
from heapq import nlargest

data = [('Employee Name', 'Employee ID', 'Salary', 'Department'),
        ('Tyler Bennett', 'E10297', 32000, 'D101'),
        ('John Rappl', 'E21437', 47000, 'D050'),
        ('George Woltman', 'E00127', 53500, 'D101'),
        ('Adam Smith', 'E63535', 18000, 'D202'),
        ('Claire Buckman', 'E39876', 27800, 'D202'),
        ('David McClellan', 'E04242', 41500, 'D101'),
        ('Rich Holcomb', 'E01234', 49500, 'D202'),
        ('Nathan Adams', 'E41298', 21900, 'D050'),
        ('Richard Potter', 'E43128', 15900, 'D101'),
        ('David Motsinger', 'E27002', 19250, 'D202'),
        ('Tim Sampair', 'E03033', 27000, 'D101'),
        ('Kim Arlich', 'E10001', 57000, 'D190'),
        ('Timothy Grove', 'E16398', 29900, 'D190')]

departments = defaultdict(list)
for rec in data[1:]:
    departments[rec[-1]].append(rec)

N = 3
format = " %-15s " * len(data[0])
for department, recs in sorted(departments.items()):
    print ("Department %s" % department)
    print (format % data[0])
    for rec in nlargest(N, recs, key=lambda rec: rec[-2]):
        print (format % rec)


Topic variable

Several programming languages offer syntax shortcuts to deal with the notion of "current" or "topic" variable.

A topic variable is a special variable with a very short name which can also often be omitted.

Demonstrate the utilization and behaviour of the topic variable within the language and explain or demonstrate how the topic variable behaves under different levels of nesting or scope, if this applies, within the language.

For instance you can (but you don't have to) show how the topic variable can be used by assigning the number 3 to it and then computing its square and square root.

Solution:
>>> 3
3
>>> _*_, _**0.5
(9, 1.7320508075688772)
>>>


Topswops

Topswops is a card game created by John Conway in the 1970's.

Assume you have a particular permutation of a set of   n   cards numbered   1..n   on both of their faces, for example the arrangement of four cards given by   [2, 4, 1, 3]   where the leftmost card is on top.

A round is composed of reversing the first   m   cards where   m   is the value of the topmost card.

Rounds are repeated until the topmost card is the number   1   and the number of swaps is recorded.

For our example the swaps produce:

    [2, 4, 1, 3]    # Initial shuffle
    [4, 2, 1, 3]
    [3, 1, 2, 4]
    [2, 1, 3, 4]
    [1, 2, 3, 4]

For a total of four swaps from the initial ordering to produce the terminating case where   1   is on top.

For a particular number    n    of cards,    topswops(n)    is the maximum swaps needed for any starting permutation of the   n   cards.

;Task:
The task is to generate and show here a table of    n    vs    topswops(n)    for    n    in the range   1..10   inclusive.

;Note:
Topswops   is also known as   [http://www.haskell.org/haskellwiki/Shootout/Fannkuch Fannkuch]   from the German word   ''Pfannkuchen''    meaning   [http://youtu.be/3biN6nQYqZY pancake].

;Related tasks:
*   [[Number reversal game]]
*   [[Sorting algorithms/Pancake sort]]

Solution:
#define _GNU_SOURCE
#include
#include
#include
#include

#define MAX_CPUS 8 // increase this if you got more CPUs/cores

typedef struct { char v[16]; } deck;

int n, best[16];

// Update a shared variable by spinlock.  Since this program really only
// enters locks dozens of times, a pthread_mutex_lock() would work
// equally fine, but RC already has plenty of examples for that.
#define SWAP_OR_RETRY(var, old, new)					\
	if (!__sync_bool_compare_and_swap(&(var), old, new)) {		\
		volatile int spin = 64;					\
		while (spin--);						\
		continue; }

void tryswaps(deck *a, int f, int s, int d) {
#define A a->v
#define B b->v

	while (best[n] < d) {
		int t = best[n];
		SWAP_OR_RETRY(best[n], t, d);
	}

#define TEST(x)									\
	case x: if ((A[15-x] == 15-x || (A[15-x] == -1 && !(f & 1<<(15-x))))	\
			&& (A[15-x] == -1 || d + best[15-x] >= best[n]))	\
			break;							\
		if (d + best[15-x] <= best[n]) return;				\
		s = 14 - x

	switch (15 - s) {
		TEST(0);  TEST(1);  TEST(2);  TEST(3);  TEST(4);
		TEST(5);  TEST(6);  TEST(7);  TEST(8);  TEST(9);
		TEST(10); TEST(11); TEST(12); TEST(13); TEST(14);
		return;
	}
#undef TEST

	deck *b = a + 1;
	*b = *a;
	d++;

#define FLIP(x)							\
	if (A[x] == x || ((A[x] == -1) && !(f & (1<= n) return 0;

		SWAP_OR_RETRY(first_swap, at, at + 1);

		memset(job->x, -1, sizeof(deck));
		job->x[0].v[at] = 0;
		job->x[0].v[0] = at;
		tryswaps(job->x, 1 | (1 << at), n - 1, 1);
	}
}

int main(void) {
	int n_cpus = num_cpus();

	for (int i = 0; i < MAX_CPUS; i++)
		jobs[i].id = i;

	pthread_t tid[MAX_CPUS];

	for (n = 2; n <= 14; n++) {
		int top = n_cpus;
		if (top > n) top = n;

		first_swap = 1;
		for (int i = 0; i < top; i++)
			pthread_create(tid + i, 0, thread_start, jobs + i);

		for (int i = 0; i < top; i++)
			pthread_join(tid[i], 0);

		printf("%2d: %2d\n", n, best[n]);
	}

	return 0;
}


Topswops

Solution:
try:
    import psyco
    psyco.full()
except ImportError:
    pass

best = [0] * 16

def try_swaps(deck, f, s, d, n):
    if d > best[n]:
        best[n] = d

    i = 0
    k = 1 << s
    while s:
        k >>= 1
        s -= 1
        if deck[s] == -1 or deck[s] == s:
            break
        i |= k
        if (i & f) == i and d + best[s] <= best[n]:
            return d
    s += 1

    deck2 = list(deck)
    k = 1
    for i2 in xrange(1, s):
        k <<= 1
        if deck2[i2] == -1:
            if f & k: continue
        elif deck2[i2] != i2:
            continue

        deck[i2] = i2
        deck2[:i2 + 1] = reversed(deck[:i2 + 1])
        try_swaps(deck2, f | k, s, 1 + d, n)

def topswops(n):
    best[n] = 0
    deck0 = [-1] * 16
    deck0[0] = 0
    try_swaps(deck0, 1, n, 0, n)
    return best[n]

for i in xrange(1, 13):
    print "%2d: %d" % (i, topswops(i))


Total circles area

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

typedef double Fp;
typedef struct { Fp x, y, r; } Circle;

Circle circles[] = {
    { 1.6417233788,  1.6121789534, 0.0848270516},
    {-1.4944608174,  1.2077959613, 1.1039549836},
    { 0.6110294452, -0.6907087527, 0.9089162485},
    { 0.3844862411,  0.2923344616, 0.2375743054},
    {-0.2495892950, -0.3832854473, 1.0845181219},
    { 1.7813504266,  1.6178237031, 0.8162655711},
    {-0.1985249206, -0.8343333301, 0.0538864941},
    {-1.7011985145, -0.1263820964, 0.4776976918},
    {-0.4319462812,  1.4104420482, 0.7886291537},
    { 0.2178372997, -0.9499557344, 0.0357871187},
    {-0.6294854565, -1.3078893852, 0.7653357688},
    { 1.7952608455,  0.6281269104, 0.2727652452},
    { 1.4168575317,  1.0683357171, 1.1016025378},
    { 1.4637371396,  0.9463877418, 1.1846214562},
    {-0.5263668798,  1.7315156631, 1.4428514068},
    {-1.2197352481,  0.9144146579, 1.0727263474},
    {-0.1389358881,  0.1092805780, 0.7350208828},
    { 1.5293954595,  0.0030278255, 1.2472867347},
    {-0.5258728625,  1.3782633069, 1.3495508831},
    {-0.1403562064,  0.2437382535, 1.3804956588},
    { 0.8055826339, -0.0482092025, 0.3327165165},
    {-0.6311979224,  0.7184578971, 0.2491045282},
    { 1.4685857879, -0.8347049536, 1.3670667538},
    {-0.6855727502,  1.6465021616, 1.0593087096},
    { 0.0152957411,  0.0638919221, 0.9771215985}};

const size_t n_circles = sizeof(circles) / sizeof(Circle);

static inline Fp min(const Fp a, const Fp b) { return a <= b ? a : b; }

static inline Fp max(const Fp a, const Fp b) { return a >= b ? a : b; }

static inline Fp sq(const Fp a) { return a * a; }

// Return an uniform random value in [a, b).
static inline double uniform(const double a, const double b) {
    const double r01 = rand() / (double)RAND_MAX;
    return a + (b - a) * r01;
}

static inline bool is_inside_circles(const Fp x, const Fp y) {
    for (size_t i = 0; i < n_circles; i++)
        if (sq(x - circles[i].x) + sq(y - circles[i].y) < circles[i].r)
            return true;
    return false;
}

int main() {
    // Initialize the bounding box (bbox) of the circles.
    Fp x_min = INFINITY, x_max = -INFINITY;
    Fp y_min = x_min, y_max = x_max;

    // Compute the bounding box of the circles.
    for (size_t i = 0; i < n_circles; i++) {
        Circle *c = &circles[i];
        x_min = min(x_min, c->x - c->r);
        x_max = max(x_max, c->x + c->r);
        y_min = min(y_min, c->y - c->r);
        y_max = max(y_max, c->y + c->r);

        c->r *= c->r; // Square the radii to speed up testing.
    }

    const Fp bbox_area = (x_max - x_min) * (y_max - y_min);

    // Montecarlo sampling.
    srand(time(0));
    size_t to_try = 1U << 16;
    size_t n_tries = 0;
    size_t n_hits = 0;

    while (true) {
        n_hits += is_inside_circles(uniform(x_min, x_max),
                                    uniform(y_min, y_max));
        n_tries++;

        if (n_tries == to_try) {
            const Fp area = bbox_area * n_hits / n_tries;
            const Fp r = (Fp)n_hits / n_tries;
            const Fp s = area * sqrt(r * (1 - r) / n_tries);
            printf("%.4f +/- %.4f (%zd samples)\n", area, s, n_tries);
            if (s * 3 <= 1e-3) // Stop at 3 sigmas.
                break;
            to_try *= 2;
        }
    }

    return 0;
}


Total circles area

Solution:
from collections import namedtuple

Circle = namedtuple("Circle", "x y r")

circles = [
    Circle( 1.6417233788,  1.6121789534, 0.0848270516),
    Circle(-1.4944608174,  1.2077959613, 1.1039549836),
    Circle( 0.6110294452, -0.6907087527, 0.9089162485),
    Circle( 0.3844862411,  0.2923344616, 0.2375743054),
    Circle(-0.2495892950, -0.3832854473, 1.0845181219),
    Circle( 1.7813504266,  1.6178237031, 0.8162655711),
    Circle(-0.1985249206, -0.8343333301, 0.0538864941),
    Circle(-1.7011985145, -0.1263820964, 0.4776976918),
    Circle(-0.4319462812,  1.4104420482, 0.7886291537),
    Circle( 0.2178372997, -0.9499557344, 0.0357871187),
    Circle(-0.6294854565, -1.3078893852, 0.7653357688),
    Circle( 1.7952608455,  0.6281269104, 0.2727652452),
    Circle( 1.4168575317,  1.0683357171, 1.1016025378),
    Circle( 1.4637371396,  0.9463877418, 1.1846214562),
    Circle(-0.5263668798,  1.7315156631, 1.4428514068),
    Circle(-1.2197352481,  0.9144146579, 1.0727263474),
    Circle(-0.1389358881,  0.1092805780, 0.7350208828),
    Circle( 1.5293954595,  0.0030278255, 1.2472867347),
    Circle(-0.5258728625,  1.3782633069, 1.3495508831),
    Circle(-0.1403562064,  0.2437382535, 1.3804956588),
    Circle( 0.8055826339, -0.0482092025, 0.3327165165),
    Circle(-0.6311979224,  0.7184578971, 0.2491045282),
    Circle( 1.4685857879, -0.8347049536, 1.3670667538),
    Circle(-0.6855727502,  1.6465021616, 1.0593087096),
    Circle( 0.0152957411,  0.0638919221, 0.9771215985)]

def main():
    # compute the bounding box of the circles
    x_min = min(c.x - c.r for c in circles)
    x_max = max(c.x + c.r for c in circles)
    y_min = min(c.y - c.r for c in circles)
    y_max = max(c.y + c.r for c in circles)

    box_side = 500

    dx = (x_max - x_min) / box_side
    dy = (y_max - y_min) / box_side

    count = 0

    for r in xrange(box_side):
        y = y_min + r * dy
        for c in xrange(box_side):
            x = x_min + c * dx
            if any((x-circle.x)**2 + (y-circle.y)**2 <= (circle.r ** 2)
                   for circle in circles):
                count += 1

    print "Approximated area:", count * dx * dy

main()


Trabb Pardo–Knuth algorithm

The TPK algorithm is an early example of a programming chrestomathy.
It was used in Donald Knuth and Luis Trabb Pardo's Stanford tech report [http://bitsavers.org/pdf/stanford/cs_techReports/STAN-CS-76-562_EarlyDevelPgmgLang_Aug76.pdf The Early Development of Programming Languages].
The report traces the early history of work in developing computer languages in the 1940s and 1950s, giving several translations of the algorithm.

From the wikipedia entry:

 '''ask''' for 11 numbers to be read into a sequence ''S''
 '''reverse''' sequence ''S''
 '''for each''' ''item'' '''in''' sequence ''S''
     ''result'' ''':=''' '''call''' a function to do an ''operation''
     '''if''' ''result'' overflows
         '''alert''' user
     '''else'''
         '''print''' ''result''

The task is to implement the algorithm:
# Use the function:     f(x) = |x|^{0.5} + 5x^3
# The overflow condition is an answer of greater than 400.
# The 'user alert' should not stop processing of other items of the sequence.
# Print a prompt before accepting '''eleven''', textual, numeric inputs.
# You may optionally print the item as well as its associated result, but the results must be in reverse order of input.
# The sequence   ''' ''S'' '''   may be 'implied' and so not shown explicitly.
# ''Print and show the program in action from a typical run here''. (If the output is graphical rather than text then either add a screendump or describe textually what is displayed).

Solution:
#include
#include

int
main ()
{
  double inputs[11], check = 400, result;
  int i;

  printf ("\nPlease enter 11 numbers :");

  for (i = 0; i < 11; i++)
    {
      scanf ("%lf", &inputs[i]);
    }

  printf ("\n\n\nEvaluating f(x) = |x|^0.5 + 5x^3 for the given inputs :");

  for (i = 10; i >= 0; i--)
    {
      result = sqrt (fabs (inputs[i])) + 5 * pow (inputs[i], 3);

      printf ("\nf(%lf) = ");

      if (result > check)
        {
          printf ("Overflow!");
        }

      else
        {
          printf ("%lf", result);
        }
    }

  return 0;
}


Trabb Pardo–Knuth algorithm

Solution:
#!/usr/bin/env js

function main() {
    var nums = getNumbers(11);
    nums.reverse();
    for (var i in  nums) {
        pardoKnuth(nums[i], fn, 400);
    }
}

function pardoKnuth(n, f, max) {
    var res = f(n);
    putstr('f(' + String(n) + ')');
    if (res > max) {
        print(' is too large');
    } else {
        print(' = ' + String(res));
    }
}

function fn(x) {
    return Math.pow(Math.abs(x), 0.5) + 5 * Math.pow(x, 3);
}

function getNumbers(n) {
    var nums = [];
    print('Enter', n, 'numbers.');
    for (var i = 1; i <= n; i++) {
        putstr('   ' + i + ': ');
        var num = readline();
        nums.push(Number(num));
    }
    return nums;
}

main();


Trabb Pardo–Knuth algorithm

Solution:
Python 3.2.2 (default, Sep  4 2011, 09:51:08) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> def f(x): return abs(x) ** 0.5 + 5 * x**3

>>> print(', '.join('%s:%s' % (x, v if v<=400 else "TOO LARGE!")
	           for x,v in ((y, f(float(y))) for y in input('\nnumbers: ').strip().split()[:11][::-1])))

11 numbers: 1 2 3 4 5 6 7 8 9 10 11
11:TOO LARGE!, 10:TOO LARGE!, 9:TOO LARGE!, 8:TOO LARGE!, 7:TOO LARGE!, 6:TOO LARGE!, 5:TOO LARGE!, 4:322.0, 3:136.73205080756887, 2:41.41421356237309, 1:6.0
>>>


Trabb Pardo–Knuth algorithm

Solution:
import math

def f(x):
    return math.sqrt(abs(x)) + 5 * x**3

def ask_numbers(n=11):
    print(f'Enter {n} numbers:')
    return (float(input('>')) for _ in range(n))

if __name__ == '__main__':
    for x in ask_numbers().reverse():
        if (result := f(x)) > 400:
            print(f'f({x}): overflow')
        else:
            print(f'f({x}) = {result}')


Tree datastructures

The following shows a tree of data with nesting denoted by visual levels of indentation:
RosettaCode
    rocks
        code
        comparison
        wiki
    mocks
        trolling

A common datastructure for trees is to define node structures having a name and a, (possibly empty), list of child nodes. The nesting of nodes captures the indentation of the tree. Lets call this '''the nest form'''.
# E.g. if child nodes are surrounded by brackets
#      and separated by commas then:
RosettaCode(rocks(code, ...), ...)
# But only an _example_

Another datastructure for trees is to construct from the root an ordered list of the nodes level of indentation and the name of that node. The indentation for the root node is zero; node 'rocks is indented by one level from the left, and so on. Lets call this '''the indent form'''.
0 RosettaCode
1 rocks
2 code
...

;Task:
# Create/use a nest datastructure format and textual representation for arbitrary trees.
# Create/use an indent datastructure format and textual representation for arbitrary trees.
# Create methods/classes/proceedures/routines etc to:
## Change from a nest tree datastructure to an indent one.
## Change from an indent tree datastructure to a nest one
# Use the above to encode the example at the start into the nest format, and show it.
# transform the initial nest format to indent format and show it.
# transform the indent format to final nest format and show it.
# Compare initial and final nest formats which should be the same.

;Note:
* It's all about showing aspects of the contrasting datastructures as they hold the tree.
* Comparing nested datastructures is secondary - saving formatted output as a string then a string compare would suffice for this task, if its easier.

Show all output on this page.

Solution:
from pprint import pprint as pp

def to_indent(node, depth=0, flat=None):
    if flat is None:
        flat = []
    if node:
        flat.append((depth, node[0]))
    for child in node[1]:
        to_indent(child, depth + 1, flat)
    return flat

def to_nest(lst, depth=0, level=None):
    if level is None:
        level = []
    while lst:
        d, name = lst[0]
        if d == depth:
            children = []
            level.append((name, children))
            lst.pop(0)
        elif d > depth:  # down
            to_nest(lst, d, children)
        elif d < depth:  # up
            return
    return level[0] if level else None

if __name__ == '__main__':
    print('Start Nest format:')
    nest = ('RosettaCode', [('rocks', [('code', []), ('comparison', []), ('wiki', [])]),
                            ('mocks', [('trolling', [])])])
    pp(nest, width=25)

    print('\n... To Indent format:')
    as_ind = to_indent(nest)
    pp(as_ind, width=25)

    print('\n... To Nest format:')
    as_nest = to_nest(as_ind)
    pp(as_nest, width=25)

    if nest != as_nest:
        print("Whoops round-trip issues")


Tree from nesting levels

Given a flat list of integers greater than zero, representing object nesting
levels, e.g. [1, 2, 4],
generate a tree formed from nested lists of those nesting level integers where:
* Every int appears, in order, at its depth of nesting.
* If the next level int is greater than the previous then it appears in a sub-list of the list containing the previous item

The generated tree data structure should ideally be in a languages nested list format that can
be used for further calculations rather than something just calculated for printing.

An input of [1, 2, 4] should produce the equivalent of: [1, [2, [[4]]]]
where 1 is at depth1, 2 is two deep and 4 is nested 4 deep.

[1, 2, 4, 2, 2, 1] should produce [1, [2, [[4]], 2, 2], 1].
All the nesting integers are in the same order but at the correct nesting
levels.

Similarly [3, 1, 3, 1] should generate [[[3]], 1, [[3]], 1]

;Task:
Generate and show here the results for the following inputs:
:* []
:* [1, 2, 4]
:* [3, 1, 3, 1]
:* [1, 2, 3, 1]
:* [3, 2, 1, 3]
:* [3, 3, 3, 1, 1, 3, 3, 3]

Solution:
def to_tree(x, index=0, depth=1):
   so_far = []
   while index < len(x):
       this = x[index]
       if this == depth:
           so_far.append(this)
       elif this > depth:
           index, deeper = to_tree(x, index, depth + 1)
           so_far.append(deeper)
       else: # this < depth:
           index -=1
           break
       index += 1
   return (index, so_far) if depth > 1 else so_far

if __name__ ==  "__main__":
    from pprint import pformat

    def pnest(nest:list, width: int=9) -> str:
        text = pformat(nest, width=width).replace('\n', '\n    ')
        print(f" OR {text}\n")

    exercises = [
        [],
        [1, 2, 4],
        [3, 1, 3, 1],
        [1, 2, 3, 1],
        [3, 2, 1, 3],
        [3, 3, 3, 1, 1, 3, 3, 3],
        ]
    for flat in exercises:
        nest = to_tree(flat)
        print(f"{flat} NESTS TO: {nest}")
        pnest(nest)


Tropical algebra overloading

In algebra, a max tropical semiring (also called a max-plus algebra) is the semiring
(ℝ ∪ -Inf, ⊕, ⊗) containing the ring of real numbers ℝ augmented by negative infinity,
the max function (returns the greater of two real numbers), and addition.

In max tropical algebra, x ⊕ y = max(x, y) and x ⊗ y = x + y. The identity for ⊕
is -Inf (the max of any number with -infinity is that number), and the identity for ⊗ is 0.

;Task:

* Define functions or, if the language supports the symbols as operators, operators for ⊕ and ⊗ that fit the above description. If the language does not support ⊕ and ⊗ as operators but allows overloading operators for a new object type, you may instead overload + and * for a new min tropical albrbraic type. If you cannot overload operators in the language used, define ordinary functions for the purpose.

Show that 2 ⊗ -2 is 0, -0.001 ⊕ -Inf is -0.001, 0 ⊗ -Inf is -Inf, 1.5 ⊕ -1 is 1.5, and -0.5 ⊗ 0 is -0.5.

* Define exponentiation as serial ⊗, and in general that a to the power of b is a * b, where a is a real number and b must be a positive integer. Use either ↑ or similar up arrow or the carat ^, as an exponentiation operator if this can be used to overload such "exponentiation" in the language being used. Calculate 5 ↑ 7 using this definition.

* Max tropical algebra is distributive, so that

   a ⊗ (b ⊕ c) equals a ⊗ b ⊕ b ⊗ c,

where ⊗ has precedence over ⊕. Demonstrate that 5 ⊗ (8 ⊕ 7) equals  5 ⊗ 8 ⊕ 5 ⊗ 7.

* If the language used does not support operator overloading, you may use ordinary function names such as tropicalAdd(x, y) and tropicalMul(x, y).

;See also
:;*[[https://en.wikipedia.org/wiki/Tropical_semiring#tropical_algebra Tropical algebra]]
:;*[[https://arxiv.org/pdf/1908.07012.pdf Tropical geometry review article]]
:;*[[https://en.wikipedia.org/wiki/Operator_overloading Operator overloading]]

Solution:
from numpy import Inf

class MaxTropical:
    """
    Class for max tropical algebra.
    x + y is max(x, y) and X * y is x + y
    """
    def __init__(self, x=0):
        self.x = x

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

    def __add__(self, other):
        return MaxTropical(max(self.x, other.x))

    def __mul__(self, other):
        return MaxTropical(self.x + other.x)

    def __pow__(self, other):
        assert other.x // 1 == other.x and other.x > 0, "Invalid Operation"
        return MaxTropical(self.x * other.x)

    def __eq__(self, other):
        return self.x == other.x

if __name__ == "__main__":
    a = MaxTropical(-2)
    b = MaxTropical(-1)
    c = MaxTropical(-0.5)
    d = MaxTropical(-0.001)
    e = MaxTropical(0)
    f = MaxTropical(0.5)
    g = MaxTropical(1)
    h = MaxTropical(1.5)
    i = MaxTropical(2)
    j = MaxTropical(5)
    k = MaxTropical(7)
    l = MaxTropical(8)
    m = MaxTropical(-Inf)

    print("2 * -2 == ", i * a)
    print("-0.001 + -Inf == ", d + m)
    print("0 * -Inf == ", e * m)
    print("1.5 + -1 == ", h + b)
    print("-0.5 * 0 == ", c * e)
    print("5**7 == ", j**k)
    print("5 * (8 + 7)) == ", j * (l + k))
    print("5 * 8 + 5 * 7 == ", j * l + j * k)
    print("5 * (8 + 7) == 5 * 8 + 5 * 7", j * (l + k) == j * l + j * k)


Truncate a file

[[Category:File System Operations]]

;Task:
Truncate a file to a specific length.   This should be implemented as a routine that takes two parameters: the filename and the required file length (in bytes).

Truncation can be achieved using system or library calls intended for such a task, if such methods exist, or by creating a temporary file of a reduced size and renaming it, after first deleting the original file, if no other method is available.   The file may contain non human readable binary data in an unspecified format, so the routine should be "binary safe", leaving the contents of the untruncated part of the file unchanged.

If the specified filename does not exist, or the provided length is not less than the current file length, then the routine should raise an appropriate error condition.

On some systems, the provided file truncation facilities might not change the file or may extend the file, if the specified length is greater than the current length of the file.

This task permits the use of such facilities.   However, such behaviour should be noted, or optionally a warning message relating to an non change or increase in file size may be implemented.

Solution:
===Windows===
Windows uses SetEndOfFile() to change the length of a file. This program can truncate or extend a file. It can detect and print errors.

* If the file does not exist: "The system cannot find the file specified."
* If the length is negative: "An attempt was made to move the file pointer before the beginning of the file."
* If the length is too large: "There is not enough space on the disk."


Truncate a file

Solution:
#include
#include
#include

/* Print "message: last Win32 error" to stderr. */
void
oops(const wchar_t *message)
{
	wchar_t *buf;
	DWORD error;

	buf = NULL;
	error = GetLastError();
	FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
	    FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
	    NULL, error, 0, (wchar_t *)&buf, 0, NULL);

	if (buf) {
		fwprintf(stderr, L"%ls: %ls", message, buf);
		LocalFree(buf);
	} else {
		/* FormatMessageW failed. */
		fwprintf(stderr, L"%ls: unknown error 0x%x\n",
		    message, error);
	}
}

int
dotruncate(wchar_t *fn, LARGE_INTEGER fp)
{
	HANDLE fh;

	fh = CreateFileW(fn, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (fh == INVALID_HANDLE_VALUE) {
		oops(fn);
		return 1;
	}

	if (SetFilePointerEx(fh, fp, NULL, FILE_BEGIN) == 0 ||
	    SetEndOfFile(fh) == 0) {
		oops(fn);
		CloseHandle(fh);
		return 1;
	}

	CloseHandle(fh);
	return 0;
}

/*
 * Truncate or extend a file to the given length.
 */
int
main()
{
	LARGE_INTEGER fp;
	int argc;
	wchar_t **argv, *fn, junk[2];

	/* MinGW never provides wmain(argc, argv). */
	argv = CommandLineToArgvW(GetCommandLineW(), &argc);
	if (argv == NULL) {
		oops(L"CommandLineToArgvW");
		return 1;
	}

	if (argc != 3) {
		fwprintf(stderr, L"usage: %ls filename length\n", argv[0]);
		return 1;
	}

	fn = argv[1];

	/* fp = argv[2] converted to a LARGE_INTEGER. */
	if (swscanf(argv[2], L"%lld%1ls", &fp.QuadPart, &junk) != 1) {
		fwprintf(stderr, L"%ls: not a number\n", argv[2]);
		return 1;
	}

	return dotruncate(fn, fp);
}


Truncate a file

Solution:
def truncate_file(name, length):
    if not os.path.isfile(name):
        return False
    if length >= os.path.getsize(name):
        return False
    with open(name, 'ab') as f:
        f.truncate(length)
    return True


Truth table

A truth table is a display of the inputs to, and the output of a Boolean function organized as a table where each row gives one combination of input values and the corresponding value of the function.

;Task:
# Input a Boolean function from the user as a string then calculate and print a formatted truth table for the given function. (One can assume that the user input is correct).
# Print and show output for Boolean functions of two and three input variables, but any program should not be limited to that many variables in the function.
# Either reverse-polish or infix notation expressions are allowed.

;Related tasks:
*   [[Boolean values]]
*   [[Ternary logic]]

;See also:
*   [http://mathworld.wolfram.com/TruthTable.html Wolfram MathWorld entry on truth tables].
*   [http://www.google.co.uk/search?q=truth+table&hl=en&client=firefox-a&hs=Om7&rls=org.mozilla:en-GB:official&prmd=imvns&tbm=isch&tbo=u&source=univ&sa=X&ei=C0uuTtjuH4Wt8gOF4dmYCw&ved=0CDUQsAQ&biw=941&bih=931&sei=%20Jk-uTuKKD4Sg8QOFkPGcCw some "truth table" examples from Google].

Solution:
#include
#include
#include

#define TRUE 1
#define FALSE 0
#define STACK_SIZE 80
#define BUFFER_SIZE 100

typedef int bool;

typedef struct {
    char name;
    bool val;
} var;

typedef struct {
    int top;
    bool els[STACK_SIZE];
} stack_of_bool;

char expr[BUFFER_SIZE];
int expr_len;
var vars[24];
int vars_len;

/* stack manipulation functions */

bool is_full(stack_of_bool *sp) {
    return sp->top == STACK_SIZE - 1;
}

bool is_empty(stack_of_bool *sp) {
    return sp->top == -1;
}

bool peek(stack_of_bool *sp) {
    if (!is_empty(sp))
        return sp->els[sp->top];
    else {
        printf("Stack is empty.\n");
        exit(1);
    }
}

void push(stack_of_bool *sp, bool val) {
    if (!is_full(sp)) {
        sp->els[++(sp->top)] = val;
    }
    else {
        printf("Stack is full.\n");
        exit(1);
    }
}

bool pop(stack_of_bool *sp) {
    if (!is_empty(sp))
        return sp->els[(sp->top)--];
    else {
        printf("\nStack is empty.\n");
        exit(1);
    }
}

void make_empty(stack_of_bool *sp) {
    sp->top = -1;
}

int elems_count(stack_of_bool *sp) {
    return (sp->top) + 1;
}

bool is_operator(const char c) {
   return c == '&' || c == '|' || c == '!' || c == '^';
}

int vars_index(const char c) {
   int i;
   for (i = 0; i < vars_len; ++i) {
       if (vars[i].name == c) return i;
   }
   return -1;
}

bool eval_expr() {
    int i, vi;
    char e;
    stack_of_bool s;
    stack_of_bool *sp = &s
    make_empty(sp);
    for (i = 0; i < expr_len; ++i) {
        e = expr[i];
        if (e == 'T')
            push(sp, TRUE);
        else if (e == 'F')
            push(sp, FALSE);
        else if((vi = vars_index(e)) >= 0) {
            push(sp, vars[vi].val);
        }
        else switch(e) {
            case '&':
                push(sp, pop(sp) & pop(sp));
                break;
            case '|':
                push(sp, pop(sp) | pop(sp));
                break;
            case '!':
                push(sp, !pop(sp));
                break;
            case '^':
                push(sp, pop(sp) ^ pop(sp));
                break;
            default:
                printf("\nNon-conformant character '%c' in expression.\n", e);
                exit(1);
        }
    }
    if (elems_count(sp) != 1) {
        printf("\nStack should contain exactly one element.\n");
        exit(1);
    }
    return peek(sp);
}

void set_vars(int pos) {
    int i;
    if (pos > vars_len) {
        printf("\nArgument to set_vars can't be greater than the number of variables.\n");
        exit(1);
    }
    else if (pos == vars_len) {
        for (i = 0; i < vars_len; ++i) {
            printf((vars[i].val) ? "T  " : "F  ");
        }
        printf("%c\n", (eval_expr()) ? 'T' : 'F');
    }
    else {
        vars[pos].val = FALSE;
        set_vars(pos + 1);
        vars[pos].val = TRUE;
        set_vars(pos + 1);
    }
}

/* removes whitespace and converts to upper case */
void process_expr() {
    int i, count = 0;
    for (i = 0; expr[i]; ++i) {
        if (!isspace(expr[i])) expr[count++] = toupper(expr[i]);
    }
    expr[count] = '\0';
}

int main() {
    int i, h;
    char e;
    printf("Accepts single-character variables (except for 'T' and 'F',\n");
    printf("which specify explicit true or false values), postfix, with\n");
    printf("&|!^ for and, or, not, xor, respectively; optionally\n");
    printf("seperated by whitespace. Just enter nothing to quit.\n");

    while (TRUE) {
        printf("\nBoolean expression: ");
        fgets(expr, BUFFER_SIZE, stdin);
        fflush(stdin);
        process_expr();
        expr_len = strlen(expr);
        if (expr_len == 0) break;
        vars_len = 0;
        for (i = 0; i < expr_len; ++i) {
            e = expr[i];
            if (!is_operator(e) && e != 'T' && e != 'F' && vars_index(e) == -1) {
                vars[vars_len].name = e;
                vars[vars_len].val = FALSE;
                vars_len++;
            }
        }
        printf("\n");
        if (vars_len == 0) {
            printf("No variables were entered.\n");
        }
        else {
            for (i = 0; i < vars_len; ++i)
                printf("%c  ", vars[i].name);
            printf("%s\n", expr);
            h = vars_len * 3 + expr_len;
            for (i = 0; i < h; ++i) printf("=");
            printf("\n");
            set_vars(0);
        }
    }
    return 0;
}


Truth table

Solution:
from itertools import product

while True:
    bexp = input('\nBoolean expression: ')
    bexp = bexp.strip()
    if not bexp:
        print("\nThank you")
        break
    code = compile(bexp, '', 'eval')
    names = code.co_names
    print('\n' + ' '.join(names), ':', bexp)
    for values in product(range(2), repeat=len(names)):
        env = dict(zip(names, values))
        print(' '.join(str(v) for v in values), ':', eval(code, env))


Two bullet roulette

The following is supposedly a question given to mathematics graduates seeking jobs on Wall Street:

  A revolver handgun has a revolving cylinder with six chambers for bullets.

  It is loaded with the following procedure:

      1. Check the first chamber to the right of the trigger for a bullet.  If a bullet
         is seen, the cylinder is rotated one chamber clockwise and the next chamber
         checked until an empty chamber is found.

      2. A cartridge containing a bullet is placed in the empty chamber.

      3. The cylinder is then rotated one chamber clockwise.

  To randomize the cylinder's position, the cylinder is spun, which causes the cylinder to take
  a random position from 1 to 6 chamber rotations clockwise from its starting position.

  When the trigger is pulled the gun will fire if there is a bullet in position 0, which is just
  counterclockwise from the loading position.

  The gun is unloaded by removing all cartridges from the cylinder.

  According to the legend, a suicidal Russian imperial military officer plays a game of Russian
  roulette by putting two bullets in a six-chamber cylinder and pulls the trigger twice.
  If the gun fires with a trigger pull, this is considered a successful suicide.

  The cylinder is always spun before the first shot, but it may or may not be spun after putting
  in the first bullet and may or may not be spun after taking the first shot.

  Which of the following situations produces the highest probability of suicide?

    A. Spinning the cylinder after loading the first bullet, and spinning again after the first shot.

    B. Spinning the cylinder after loading the first bullet only.

    C. Spinning the cylinder after firing the first shot only.

    D. Not spinning the cylinder either after loading the first bullet or after the first shot.

    E. The probability is the same for all cases.

;Task:
# Run a repeated simulation of each of the above scenario, calculating the percentage of suicide with a randomization of the four spinning, loading and firing order scenarios.
# Show the results as a percentage of deaths for each type of scenario.
# The hand calculated probabilities are 5/9, 7/12, 5/9, and 1/2. A correct program should produce results close enough to those to allow a correct response to the interview question.

;Reference:
Youtube video on the Russian 1895 Nagant revolver [[https://www.youtube.com/watch?v=Dh1mojMaEtM]]

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

static int nextInt(int size) {
    return rand() % size;
}

static bool cylinder[6];

static void rshift() {
    bool t = cylinder[5];
    int i;
    for (i = 4; i >= 0; i--) {
        cylinder[i + 1] = cylinder[i];
    }
    cylinder[0] = t;
}

static void unload() {
    int i;
    for (i = 0; i < 6; i++) {
        cylinder[i] = false;
    }
}

static void load() {
    while (cylinder[0]) {
        rshift();
    }
    cylinder[0] = true;
    rshift();
}

static void spin() {
    int lim = nextInt(6) + 1;
    int i;
    for (i = 1; i < lim; i++) {
        rshift();
    }
}

static bool fire() {
    bool shot = cylinder[0];
    rshift();
    return shot;
}

static int method(const char *s) {
    unload();
    for (; *s != '\0'; s++) {
        switch (*s) {
        case 'L':
            load();
            break;
        case 'S':
            spin();
            break;
        case 'F':
            if (fire()) {
                return 1;
            }
            break;
        }
    }
    return 0;
}

static void append(char *out, const char *txt) {
    if (*out != '\0') {
        strcat(out, ", ");
    }
    strcat(out, txt);
}

static void mstring(const char *s, char *out) {
    for (; *s != '\0'; s++) {
        switch (*s) {
        case 'L':
            append(out, "load");
            break;
        case 'S':
            append(out, "spin");
            break;
        case 'F':
            append(out, "fire");
            break;
        }
    }
}

static void test(char *src) {
    char buffer[41] = "";
    const int tests = 100000;
    int sum = 0;
    int t;
    double pc;

    for (t = 0; t < tests; t++) {
        sum += method(src);
    }

    mstring(src, buffer);
    pc = 100.0 * sum / tests;

    printf("%-40s produces %6.3f%% deaths.\n", buffer, pc);
}

int main() {
    srand(time(0));

    test("LSLSFSF");
    test("LSLSFF");
    test("LLSFSF");
    test("LLSFF");

    return 0;
}


Two bullet roulette

Solution:
let Pistol = function(method) {
  this.fired = false;
  this.cylinder = new Array(6).fill(false);
  this.trigger = 0;
  this.rshift = function() {
    this.trigger = this.trigger == 0 ? 5 : this.trigger-1;
  }
  this.load = function() {
    while (this.cylinder[this.trigger]) this.rshift();
    this.cylinder[this.trigger] = true;
    this.rshift();
  }
  // actually we don't need this here: just for completeness
  this.unload = function() { this.cylinder.fill(false); }

  this.spin = function() { this.trigger = Math.floor(Math.random() * 6); }
  this.fire = function() {
    if (this.cylinder[this.trigger]) this.fired = true;
    this.rshift();
  }
  this.exec = function() {
    if (!method) console.error('No method provided');
    else {
      method = method.toUpperCase();
      for (let x = 0; x < method.length; x++)
        switch (method[x]) {
          case 'F' : this.fire(); break;
          case 'L' : this.load(); break;
          case 'S' : this.spin(); break;
          case 'U' : this.unload(); break;
          default: console.error(`Unknown character in method: ${method[x]}`);
        }
      return this.fired;
    }
  }
}

// simulating
const ITERATIONS = 25e4;
let methods = 'lslsfsf lslsff llsfsf llsff'.split(' '),
    bodyCount;
console.log(`@ ${ITERATIONS.toLocaleString('en')} iterations:`);
console.log();
for (let x = 0; x < methods.length; x++) {
  bodyCount = 0;
  for (let y = 1; y <= ITERATIONS; y++)
    if (new Pistol(methods[x]).exec()) bodyCount++;
  console.log(`${methods[x]}:`);
  console.log(`deaths: ${bodyCount.toLocaleString('en')} (${(bodyCount / ITERATIONS * 100).toPrecision(3)} %) `);
  console.log();
}


Two bullet roulette

Solution:
""" Russian roulette problem """
import numpy as np

class Revolver:
    """ simulates 6-shot revolving cylinger pistol """

    def __init__(self):
        """ start unloaded """
        self.cylinder = np.array([False] * 6)

    def unload(self):
        """ empty all chambers of cylinder """
        self.cylinder[:] = False

    def load(self):
        """ load a chamber (advance til empty if full already), then advance once """
        while self.cylinder[1]:
            self.cylinder[:] = np.roll(self.cylinder, 1)
        self.cylinder[1] = True

    def spin(self):
        """ spin cylinder, randomizing position of chamber to be fired """
        self.cylinder[:] = np.roll(self.cylinder, np.random.randint(1, high=7))

    def fire(self):
        """ pull trigger of revolver, return True if fired, False if did not fire """
        shot = self.cylinder[0]
        self.cylinder[:] = np.roll(self.cylinder, 1)
        return shot

    def LSLSFSF(self):
        """ load, spin, load, spin, fire, spin, fire """
        self.unload()
        self.load()
        self.spin()
        self.load()
        self.spin()
        if self.fire():
            return True
        self.spin()
        if self.fire():
            return True
        return False

    def LSLSFF(self):
        """ load, spin, load, spin, fire, fire """
        self.unload()
        self.load()
        self.spin()
        self.load()
        self.spin()
        if self.fire():
            return True
        if self.fire():
            return True
        return False

    def LLSFSF(self):
        """ load, load, spin, fire, spin, fire """
        self.unload()
        self.load()
        self.load()
        self.spin()
        if self.fire():
            return True
        self.spin()
        if self.fire():
            return True
        return False

    def LLSFF(self):
        """ load, load, spin, fire, fire """
        self.unload()
        self.load()
        self.load()
        self.spin()
        if self.fire():
            return True
        if self.fire():
            return True
        return False

if __name__ == '__main__':

    REV = Revolver()
    TESTCOUNT = 100000
    for (name, method) in [['load, spin, load, spin, fire, spin, fire', REV.LSLSFSF],
                           ['load, spin, load, spin, fire, fire', REV.LSLSFF],
                           ['load, load, spin, fire, spin, fire', REV.LLSFSF],
                           ['load, load, spin, fire, fire', REV.LLSFF]]:

        percentage = 100 * sum([method() for _ in range(TESTCOUNT)]) / TESTCOUNT
        print("Method", name, "produces", percentage, "per cent deaths.")


UPC

;Goal:
Convert UPC bar codes to decimal.

Specifically:

The UPC standard is actually a collection of standards -- physical standards, data format standards, product reference standards...

Here,   in this task,   we will focus on some of the data format standards,   with an imaginary physical+electrical implementation which converts physical UPC bar codes to ASCII   (with spaces and   '''#'''   characters representing the presence or absence of ink).

;Sample input:
Below, we have a representation of ten different UPC-A bar codes read by our imaginary bar code reader:

         # #   # ##  #  ## #   ## ### ## ### ## #### # # # ## ##  #   #  ##  ## ###  # ##  ## ### #  # #
        # # #   ##   ## # #### #   # ## #   ## #   ## # # # ###  # ###  ##  ## ###  # #  ### ###  # # #
         # #    # # #  ###  #   #    # #  #   #    # # # # ## #   ## #   ## #   ##   # # #### ### ## # #
       # # ##  ## ##  ##   #  #   #  # ###  # ##  ## # # #   ## ##  #  ### ## ## #   # #### ## #   # #
         # # ### ## #   ## ## ###  ##  # ##   #   # ## # # ### #  ## ##  #    # ### #  ## ##  #      # #
          # #  #   # ##  ##  #   #   #  # ##  ##  #   # # # # #### #  ##  # #### #### # #  ##  # #### # #
         # #  #  ##  ##  # #   ## ##   # ### ## ##   # # # #  #   #   #  #  ### # #    ###  # #  #   # #
        # # #    # ##  ##   #  # ##  ##  ### #   #  # # # ### ## ## ### ## ### ### ## #  ##  ### ## # #
         # # ### ##   ## # # #### #   ## # #### # #### # # #   #  # ###  #    # ###  # #    # ###  # # #
        # # # #### ##   # #### # #   ## ## ### #### # # # #  ### # ###  ###  # # ###  #    # #  ### # #

Some of these were entered upside down,   and one entry has a timing error.

;Task:
Implement code to find the corresponding decimal representation of each, rejecting the error.

Extra credit for handling the rows entered upside down   (the other option is to reject them).

;Notes:
Each digit is represented by 7 bits:

    0:  0 0 0 1 1 0 1
    1:  0 0 1 1 0 0 1
    2:  0 0 1 0 0 1 1
    3:  0 1 1 1 1 0 1
    4:  0 1 0 0 0 1 1
    5:  0 1 1 0 0 0 1
    6:  0 1 0 1 1 1 1
    7:  0 1 1 1 0 1 1
    8:  0 1 1 0 1 1 1
    9:  0 0 0 1 0 1 1

On the left hand side of the bar code a space represents a '''0''' and a '''#''' represents a '''1'''.
On the right hand side of the bar code, a '''#''' represents a '''0''' and a space represents a '''1'''
Alternatively (for the above):   spaces always represent zeros and '''#''' characters always represent ones, but the representation is logically negated -- '''1'''s and '''0'''s are flipped -- on the right hand side of the bar code.

;The UPC-A bar code structure:
::*   It begins with at least 9 spaces   (which our imaginary bar code reader unfortunately doesn't always reproduce properly),
::*   then has a     ''' # # '''     sequence marking the start of the sequence,
::*   then has the six "left hand" digits,
::*   then has a   ''' # # '''   sequence in the middle,
::*   then has the six "right hand digits",
::*   then has another   ''' # # '''   (end sequence),   and finally,
::*   then ends with nine trailing spaces   (which might be eaten by wiki edits, and in any event, were not quite captured correctly by our imaginary bar code reader).

Finally, the last digit is a checksum digit which may be used to help detect errors.

;Verification:
Multiply each digit in the represented 12 digit sequence by the corresponding number in   (3,1,3,1,3,1,3,1,3,1,3,1)   and add the products.

The sum (mod 10) must be '''0'''   (must have a zero as its last digit)   if the UPC number has been read correctly.

Solution:
#include
#include
#include
#include

typedef char const *const string;

bool consume_sentinal(bool middle, string s, size_t *pos) {
    if (middle) {
        if (s[*pos] == ' ' && s[*pos + 1] == '#' && s[*pos + 2] == ' ' && s[*pos + 3] == '#' && s[*pos + 4] == ' ') {
            *pos += 5;
            return true;
        }
    } else {
        if (s[*pos] == '#' && s[*pos + 1] == ' ' && s[*pos + 2] == '#') {
            *pos += 3;
            return true;
        }
    }
    return false;
}

int consume_digit(bool right, string s, size_t *pos) {
    const char zero = right ? '#' : ' ';
    const char one = right ? ' ' : '#';
    size_t i = *pos;
    int result = -1;

    if (s[i] == zero) {
        if (s[i + 1] == zero) {
            if (s[i + 2] == zero) {
                if (s[i + 3] == one) {
                    if (s[i + 4] == zero) {
                        if (s[i + 5] == one && s[i + 6] == one) {
                            result = 9;
                        }
                    } else if (s[i + 4] == one) {
                        if (s[i + 5] == zero && s[i + 6] == one) {
                            result = 0;
                        }
                    }
                }
            } else if (s[i + 2] == one) {
                if (s[i + 3] == zero) {
                    if (s[i + 4] == zero && s[i + 5] == one && s[i + 6] == one) {
                        result = 2;
                    }
                } else if (s[i + 3] == one) {
                    if (s[i + 4] == zero && s[i + 5] == zero && s[i + 6] == one) {
                        result = 1;
                    }
                }
            }
        } else if (s[i + 1] == one) {
            if (s[i + 2] == zero) {
                if (s[i + 3] == zero) {
                    if (s[i + 4] == zero && s[i + 5] == one && s[i + 6] == one) {
                        result = 4;
                    }
                } else if (s[i + 3] == one) {
                    if (s[i + 4] == one && s[i + 5] == one && s[i + 6] == one) {
                        result = 6;
                    }
                }
            } else if (s[i + 2] == one) {
                if (s[i + 3] == zero) {
                    if (s[i + 4] == zero) {
                        if (s[i + 5] == zero && s[i + 6] == one) {
                            result = 5;
                        }
                    } else if (s[i + 4] == one) {
                        if (s[i + 5] == one && s[i + 6] == one) {
                            result = 8;
                        }
                    }
                } else if (s[i + 3] == one) {
                    if (s[i + 4] == zero) {
                        if (s[i + 5] == one && s[i + 6] == one) {
                            result = 7;
                        }
                    } else if (s[i + 4] == one) {
                        if (s[i + 5] == zero && s[i + 6] == one) {
                            result = 3;
                        }
                    }
                }
            }
        }
    }

    if (result >= 0) {
        *pos += 7;
    }
    return result;
}

bool decode_upc(string src, char *buffer) {
    const int one = 1;
    const int three = 3;

    size_t pos = 0;
    int sum = 0;
    int digit;

    //1) 9 spaces (unreliable)
    while (src[pos] != '#') {
        if (src[pos] == 0) {
            return false;
        }
        pos++;
    }

    //2) Start "# #"
    if (!consume_sentinal(false, src, &pos)) {
        return false;
    }

    //3) 6 left-hand digits (space is zero and hash is one)
    digit = consume_digit(false, src, &pos);
    if (digit < 0) {
        return false;
    }
    sum += three * digit;
    *buffer++ = digit + '0';
    *buffer++ = ' ';

    digit = consume_digit(false, src, &pos);
    if (digit < 0) {
        return false;
    }
    sum += one * digit;
    *buffer++ = digit + '0';
    *buffer++ = ' ';

    digit = consume_digit(false, src, &pos);
    if (digit < 0) {
        return false;
    }
    sum += three * digit;
    *buffer++ = digit + '0';
    *buffer++ = ' ';

    digit = consume_digit(false, src, &pos);
    if (digit < 0) {
        return false;
    }
    sum += one * digit;
    *buffer++ = digit + '0';
    *buffer++ = ' ';

    digit = consume_digit(false, src, &pos);
    if (digit < 0) {
        return false;
    }
    sum += three * digit;
    *buffer++ = digit + '0';
    *buffer++ = ' ';

    digit = consume_digit(false, src, &pos);
    if (digit < 0) {
        return false;
    }
    sum += one * digit;
    *buffer++ = digit + '0';
    *buffer++ = ' ';

    //4) Middle "# #"
    if (!consume_sentinal(true, src, &pos)) {
        return false;
    }

    //5) 6 right-hand digits (hash is zero and space is one)
    digit = consume_digit(true, src, &pos);
    if (digit < 0) {
        return false;
    }
    sum += three * digit;
    *buffer++ = digit + '0';
    *buffer++ = ' ';

    digit = consume_digit(true, src, &pos);
    if (digit < 0) {
        return false;
    }
    sum += one * digit;
    *buffer++ = digit + '0';
    *buffer++ = ' ';

    digit = consume_digit(true, src, &pos);
    if (digit < 0) {
        return false;
    }
    sum += three * digit;
    *buffer++ = digit + '0';
    *buffer++ = ' ';

    digit = consume_digit(true, src, &pos);
    if (digit < 0) {
        return false;
    }
    sum += one * digit;
    *buffer++ = digit + '0';
    *buffer++ = ' ';

    digit = consume_digit(true, src, &pos);
    if (digit < 0) {
        return false;
    }
    sum += three * digit;
    *buffer++ = digit + '0';
    *buffer++ = ' ';

    digit = consume_digit(true, src, &pos);
    if (digit < 0) {
        return false;
    }
    sum += one * digit;
    *buffer++ = digit + '0';
    *buffer++ = ' ';

    //6) Final "# #"
    if (!consume_sentinal(false, src, &pos)) {
        return false;
    }

    //7) 9 spaces (unreliable)
    // skip

    //8) the dot product of the number and (3, 1)+ sequence mod 10 must be zero
    return sum % 10 == 0;
}

void test(string src) {
    char buffer[24];

    if (decode_upc(src, buffer)) {
        buffer[22] = 0;
        printf("%sValid\n", buffer);
    } else {
        size_t len = strlen(src);
        char *rev = malloc(len + 1);
        size_t i;

        if (rev == NULL) {
            exit(1);
        }

        for (i = 0; i < len; i++) {
            rev[i] = src[len - i - 1];
        }

#pragma warning(push)
#pragma warning(disable : 6386)
        // if len + 1 bytes are allocated, and len bytes are writable, there is no buffer overrun
        rev[len] = 0;
#pragma warning(pop)

        if (decode_upc(rev, buffer)) {
            buffer[22] = 0;
            printf("%sValid (upside down)\n", buffer);
        } else {
            printf("Invalid digit(s)\n");
        }

        free(rev);
    }
}

int main() {
    int num = 0;

    printf("%2d: ", ++num);
    test("         # #   # ##  #  ## #   ## ### ## ### ## #### # # # ## ##  #   #  ##  ## ###  # ##  ## ### #  # #       ");

    printf("%2d: ", ++num);
    test("        # # #   ##   ## # #### #   # ## #   ## #   ## # # # ###  # ###  ##  ## ###  # #  ### ###  # # #         ");

    printf("%2d: ", ++num);
    test("         # #    # # #  ###  #   #    # #  #   #    # # # # ## #   ## #   ## #   ##   # # #### ### ## # #         ");

    printf("%2d: ", ++num);
    test("       # # ##  ## ##  ##   #  #   #  # ###  # ##  ## # # #   ## ##  #  ### ## ## #   # #### ## #   # #        ");

    printf("%2d: ", ++num);
    test("         # # ### ## #   ## ## ###  ##  # ##   #   # ## # # ### #  ## ##  #    # ### #  ## ##  #      # #          ");

    printf("%2d: ", ++num);
    test("          # #  #   # ##  ##  #   #   #  # ##  ##  #   # # # # #### #  ##  # #### #### # #  ##  # #### # #         ");

    printf("%2d: ", ++num);
    test("         # #  #  ##  ##  # #   ## ##   # ### ## ##   # # # #  #   #   #  #  ### # #    ###  # #  #   # #        ");

    printf("%2d: ", ++num);
    test("        # # #    # ##  ##   #  # ##  ##  ### #   #  # # # ### ## ## ### ## ### ### ## #  ##  ### ## # #         ");

    printf("%2d: ", ++num);
    test("         # # ### ##   ## # # #### #   ## # #### # #### # # #   #  # ###  #    # ###  # #    # ###  # # #       ");

    printf("%2d: ", ++num);
    test("        # # # #### ##   # #### # #   ## ## ### #### # # # #  ### # ###  ###  # # ###  #    # #  ### # #         ");

    return 0;
}


UPC

Solution:
"""UPC-A barcode reader. Requires Python =>3.6"""
import itertools
import re

RE_BARCODE = re.compile(
    r"^(?P +)"  # quiet zone
    r"(?P# #)"  # start guard
    r"(?P[ #]{42})"  # left digits
    r"(?P # # )"  # middle guard
    r"(?P[ #]{42})"  # right digits
    r"(?P# #)"  # end guard
    r"(?P +)$"  # quiet zone
)

LEFT_DIGITS = {
    (0, 0, 0, 1, 1, 0, 1): 0,
    (0, 0, 1, 1, 0, 0, 1): 1,
    (0, 0, 1, 0, 0, 1, 1): 2,
    (0, 1, 1, 1, 1, 0, 1): 3,
    (0, 1, 0, 0, 0, 1, 1): 4,
    (0, 1, 1, 0, 0, 0, 1): 5,
    (0, 1, 0, 1, 1, 1, 1): 6,
    (0, 1, 1, 1, 0, 1, 1): 7,
    (0, 1, 1, 0, 1, 1, 1): 8,
    (0, 0, 0, 1, 0, 1, 1): 9,
}

RIGHT_DIGITS = {
    (1, 1, 1, 0, 0, 1, 0): 0,
    (1, 1, 0, 0, 1, 1, 0): 1,
    (1, 1, 0, 1, 1, 0, 0): 2,
    (1, 0, 0, 0, 0, 1, 0): 3,
    (1, 0, 1, 1, 1, 0, 0): 4,
    (1, 0, 0, 1, 1, 1, 0): 5,
    (1, 0, 1, 0, 0, 0, 0): 6,
    (1, 0, 0, 0, 1, 0, 0): 7,
    (1, 0, 0, 1, 0, 0, 0): 8,
    (1, 1, 1, 0, 1, 0, 0): 9,
}

MODULES = {
    " ": 0,
    "#": 1,
}

DIGITS_PER_SIDE = 6
MODULES_PER_DIGIT = 7

class ParityError(Exception):
    """Exception raised when a parity error is found."""

class ChecksumError(Exception):
    """Exception raised when check digit does not match."""

def group(iterable, n):
    """Chunk the iterable into groups of size ``n``."""
    args = [iter(iterable)] * n
    return tuple(itertools.zip_longest(*args))

def parse(barcode):
    """Return the 12 digits represented by the given barcode. Raises a
    ParityError if any digit fails the parity check."""
    match = RE_BARCODE.match(barcode)

    # Translate bars and spaces to 1s and 0s so we can do arithmetic
    # with them. Group "modules" into chunks of 7 as we go.
    left = group((MODULES[c] for c in match.group("left")), MODULES_PER_DIGIT)
    right = group((MODULES[c] for c in match.group("right")), MODULES_PER_DIGIT)

    # Parity check
    left, right = check_parity(left, right)

    # Lookup digits
    return tuple(
        itertools.chain(
            (LEFT_DIGITS[d] for d in left),
            (RIGHT_DIGITS[d] for d in right),
        )
    )

def check_parity(left, right):
    """Check left and right parity. Flip left and right if the barcode
    was scanned upside down."""
    # When reading from left to right, each digit on the left should
    # have odd parity, and each digit on the right should have even
    # parity.
    left_parity = sum(sum(d) % 2 for d in left)
    right_parity = sum(sum(d) % 2 for d in right)

    # Use left and right parity to check if the barcode was scanned
    # upside down. Flip it if it was.
    if left_parity == 0 and right_parity == DIGITS_PER_SIDE:
        _left = tuple(tuple(reversed(d)) for d in reversed(right))
        right = tuple(tuple(reversed(d)) for d in reversed(left))
        left = _left
    elif left_parity != DIGITS_PER_SIDE or right_parity != 0:
        # Error condition. Mixed parity.
        error = tuple(
            itertools.chain(
                (LEFT_DIGITS.get(d, "_") for d in left),
                (RIGHT_DIGITS.get(d, "_") for d in right),
            )
        )
        raise ParityError(" ".join(str(d) for d in error))

    return left, right

def checksum(digits):
    """Return the check digit for the given digits. Raises a
    ChecksumError if the check digit does not match."""
    odds = (digits[i] for i in range(0, 11, 2))
    evens = (digits[i] for i in range(1, 10, 2))

    check_digit = (sum(odds) * 3 + sum(evens)) % 10

    if check_digit != 0:
        check_digit = 10 - check_digit

    if digits[-1] != check_digit:
        raise ChecksumError(str(check_digit))

    return check_digit

def main():
    barcodes = [
        "         # #   # ##  #  ## #   ## ### ## ### ## #### # # # ## ##  #   #  ##  ## ###  # ##  ## ### #  # #       ",
        "        # # #   ##   ## # #### #   # ## #   ## #   ## # # # ###  # ###  ##  ## ###  # #  ### ###  # # #         ",
        "         # #    # # #  ###  #   #    # #  #   #    # # # # ## #   ## #   ## #   ##   # # #### ### ## # #         ",
        "       # # ##  ## ##  ##   #  #   #  # ###  # ##  ## # # #   ## ##  #  ### ## ## #   # #### ## #   # #        ",
        "         # # ### ## #   ## ## ###  ##  # ##   #   # ## # # ### #  ## ##  #    # ### #  ## ##  #      # #          ",
        "          # #  #   # ##  ##  #   #   #  # ##  ##  #   # # # # #### #  ##  # #### #### # #  ##  # #### # #         ",
        "         # #  #  ##  ##  # #   ## ##   # ### ## ##   # # # #  #   #   #  #  ### # #    ###  # #  #   # #        ",
        "        # # #    # ##  ##   #  # ##  ##  ### #   #  # # # ### ## ## ### ## ### ### ## #  ##  ### ## # #         ",
        "         # # ### ##   ## # # #### #   ## # #### # #### # # #   #  # ###  #    # ###  # #    # ###  # # #       ",
        "        # # # #### ##   # #### # #   ## ## ### #### # # # #  ### # ###  ###  # # ###  #    # #  ### # #         ",
        "        # # # #### ##   # #### # #   ## ## ### #### # # # #  ### # ###  ###  # # ###  ## ##  #  ### # #         ",
    ]

    for barcode in barcodes:
        try:
            digits = parse(barcode)
        except ParityError as err:
            print(f"{err} parity error!")
            continue

        try:
            check_digit = checksum(digits)
        except ChecksumError as err:
            print(f"{' '.join(str(d) for d in digits)} checksum error! ({err})")
            continue

        print(f"{' '.join(str(d) for d in digits)}")

if __name__ == "__main__":
    main()


URL decoding

[[Category:String manipulation]]

This task   (the reverse of   [[URL encoding]]   and distinct from   [[URL parser]])   is to provide a function
or mechanism to convert an URL-encoded string into its original unencoded form.

;Test cases:
*   The encoded string   "http%3A%2F%2Ffoo%20bar%2F"   should be reverted to the unencoded form   "http://foo bar/".

*   The encoded string   "google.com/search?q=%60Abdu%27l-Bah%C3%A1"   should revert to the unencoded form   "google.com/search?q=`Abdu'l-Bahá".

*   The encoded string   "%25%32%35"   should revert to the unencoded form   "%25" and '''not''' "%".

Solution:
#include
#include

inline int ishex(int x)
{
	return	(x >= '0' && x <= '9')	||
		(x >= 'a' && x <= 'f')	||
		(x >= 'A' && x <= 'F');
}

int decode(const char *s, char *dec)
{
	char *o;
	const char *end = s + strlen(s);
	int c;

	for (o = dec; s <= end; o++) {
		c = *s++;
		if (c == '+') c = ' ';
		else if (c == '%' && (	!ishex(*s++)	||
					!ishex(*s++)	||
					!sscanf(s - 2, "%2x", &c)))
			return -1;

		if (dec) *o = c;
	}

	return o - dec;
}

int main()
{
	const char *url = "http%3A%2F%2ffoo+bar%2fabcd";
	char out[strlen(url) + 1];

	printf("length: %d\n", decode(url, 0));
	puts(decode(url, out) < 0 ? "bad string" : out);

	return 0;
}


URL decoding

Solution:
#Python 2.X
import urllib
print urllib.unquote("http%3A%2F%2Ffoo%20bar%2F")
#Python 3.5+
from urllib.parse import unquote
print(unquote('http%3A%2F%2Ffoo%20bar%2F'))


URL encoding

[[Category:String manipulation]]
[[Category: Encodings]]

;Task:
Provide a function or mechanism to convert a provided string into URL encoding representation.

In URL encoding, special characters, control characters and extended characters
are converted into a percent symbol followed by a two digit hexadecimal code,
So a space character encodes into %20 within the string.

For the purposes of this task, every character except 0-9, A-Z and a-z requires conversion, so the following characters all require conversion by default:

* ASCII control codes (Character ranges 00-1F hex (0-31 decimal) and 7F (127 decimal).
* ASCII symbols (Character ranges 32-47 decimal (20-2F hex))
* ASCII symbols (Character ranges 58-64 decimal (3A-40 hex))
* ASCII symbols (Character ranges 91-96 decimal (5B-60 hex))
* ASCII symbols (Character ranges 123-126 decimal (7B-7E hex))
* Extended characters with character codes of 128 decimal (80 hex) and above.

;Example:
The string "http://foo bar/" would be encoded as "http%3A%2F%2Ffoo%20bar%2F".

;Variations:
* Lowercase escapes are legal, as in "http%3a%2f%2ffoo%20bar%2f".
* Special characters have different encodings for different standards:
** RFC 3986, ''Uniform Resource Identifier (URI): Generic Syntax'', section 2.3, says to preserve "-._~".
** HTML 5, section [http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#url-encoded-form-data 4.10.22.5 URL-encoded form data], says to preserve "-._*", and to encode space " " to "+".
** [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI#description encodeURI] function in Javascript will preserve "-._~" (RFC 3986) and ";,/?:@&=+$!*'()#".

;Options:
It is permissible to use an exception string (containing a set of symbols
that do not need to be converted).
However, this is an optional feature and is not a requirement of this task.

;Related tasks:
*   [[URL decoding]]
*   [[URL parser]]

Solution:
#include
#include

char rfc3986[256] = {0};
char html5[256] = {0};

/* caller responsible for memory */
void encode(const char *s, char *enc, char *tb)
{
	for (; *s; s++) {
		if (tb[*s]) sprintf(enc, "%c", tb[*s]);
		else        sprintf(enc, "%%%02X", *s);
		while (*++enc);
	}
}

int main()
{
	const char url[] = "http://foo bar/";
	char enc[(strlen(url) * 3) + 1];

	int i;
	for (i = 0; i < 256; i++) {
		rfc3986[i] = isalnum(i)||i == '~'||i == '-'||i == '.'||i == '_'
			? i : 0;
		html5[i] = isalnum(i)||i == '*'||i == '-'||i == '.'||i == '_'
			? i : (i == ' ') ? '+' : 0;
	}

	encode(url, enc, rfc3986);
	puts(enc);

	return 0;
}


URL encoding

Solution:
var normal = 'http://foo/bar/';
var encoded = encodeURIComponent(normal);


URL encoding

Solution:
import urllib
s = 'http://foo/bar/'
s = urllib.quote(s)