Validate International Securities Identification Number

An International Securities Identification Number (ISIN) is a unique international identifier for a financial security such as a stock or bond.

;Task:
Write a function or program that takes a string as input, and checks whether it is a valid ISIN.

It is only valid if it has the correct format,   ''and''   the embedded checksum is correct.

Demonstrate that your code passes the test-cases listed below.

;Details:
The format of an ISIN is as follows:

+------------- a 2-character ISO country code (A-Z)
| +----------- a 9-character security code (A-Z, 0-9)
| |        +-- a checksum digit (0-9)
AU0000XVGZA3

For this task, you may assume that any 2-character alphabetic sequence is a valid country code.

The checksum can be validated as follows:
# '''Replace letters with digits''', by converting each character from base 36 to base 10, e.g. AU0000XVGZA3 -1030000033311635103.
# '''Perform the Luhn test on this base-10 number.'''There is a separate task for this test: ''[[Luhn test of credit card numbers]]''.You don't have to replicate the implementation of this test here   ---   you can just call the existing function from that task.   (Add a comment stating if you did this.)

;Test cases:
:::: {| class="wikitable"
! ISIN
! Validity
! Comment
|-
| US0378331005  || valid ||
|-
| US0373831005  || not valid || The transposition typo is caught by the checksum constraint.
|-
| U50378331005  || not valid || The substitution typo is caught by the format constraint.
|-
| US03378331005 || not valid || The duplication typo is caught by the format constraint.
|-
| AU0000XVGZA3  || valid ||
|-
| AU0000VXGZA3  || valid || Unfortunately, not ''all'' transposition typos are caught by the checksum constraint.
|-
| FR0000988040  || valid ||
|}

(The comments are just informational.   Your function should simply return a Boolean result.   See [[#Raku]] for a reference solution.)

Related task:
* [[Luhn test of credit card numbers]]

;Also see:
* Interactive online ISIN validator
* Wikipedia article: International Securities Identification Number

Solution:
def check_isin(a):
    if len(a) != 12 or not all(c.isalpha() for c in a[:2]) or not all(c.isalnum() for c in a[2:]):
        return False
    s = "".join(str(int(c, 36)) for c in a)
    return 0 == (sum(sum(divmod(2 * (ord(c) - 48), 10)) for c in s[-2::-2]) +
                 sum(ord(c) - 48 for c in s[::-2])) % 10

# A more readable version
def check_isin_alt(a):
    if len(a) != 12:
        return False
    s = []
    for i, c in enumerate(a):
        if c.isdigit():
            if i < 2:
                return False
            s.append(ord(c) - 48)
        elif c.isupper():
            if i == 11:
                return False
            s += divmod(ord(c) - 55, 10)
        else:
            return False
    v = sum(s[::-2])
    for k in s[-2::-2]:
        k = 2 * k
        v += k - 9 if k > 9 else k
    return v % 10 == 0

[check_isin(s) for s in ["US0378331005", "US0373831005", "U50378331005", "US03378331005",
                         "AU0000XVGZA3", "AU0000VXGZA3", "FR0000988040"]]

# [True, False, False, False, True, True, True]


Van Eck sequence

The sequence is generated by following this pseudo-code:

A:  The first term is zero.
    Repeatedly apply:
        If the last term is *new* to the sequence so far then:
B:          The next term is zero.
        Otherwise:
C:          The next term is how far back this last term occured previously.

;Example:
Using A:
:0
Using B:
:0 0
Using C:
:0 0 1
Using B:
:0 0 1 0
Using C:  (zero last occurred two steps back - before the one)
:0 0 1 0 2
Using B:
:0 0 1 0 2 0
Using C:  (two last occurred two steps back - before the zero)
:0 0 1 0 2 0 2 2
Using C:  (two last occurred one step back)
:0 0 1 0 2 0 2 2 1
Using C:  (one last appeared six steps back)
:0 0 1 0 2 0 2 2 1 6
...

;Task:
# Create a function/procedure/method/subroutine/... to generate the Van Eck sequence of numbers.
# Use it to display here, on this page:
:# The first ten terms of the sequence.
:# Terms 991 - to - 1000 of the sequence.

;References:
* Don't Know (the Van Eck Sequence) - Numberphile video.
* Wikipedia Article: Van Eck's Sequence.
*  OEIS sequence: A181391.

Solution:
def van_eck():
    n, seen, val = 0, {}, 0
    while True:
        yield val
        last = {val: n}
        val = n - seen.get(val, n)
        seen.update(last)
        n += 1
#%%
if __name__ == '__main__':
    print("Van Eck: first 10 terms:  ", list(islice(van_eck(), 10)))
    print("Van Eck: terms 991 - 1000:", list(islice(van_eck(), 1000))[-10:])


Van Eck sequence

Solution:
'''Van Eck sequence'''

from functools import reduce
from itertools import repeat

# vanEck :: Int -> [Int]
def vanEck(n):
    '''First n terms of the van Eck sequence.'''

    return churchNumeral(n)(
        lambda xs: cons(
            maybe(0)(succ)(
                elemIndex(xs[0])(xs[1:])
            )
        )(xs) if xs else [0]
    )([])[::-1]

# TEST ----------------------------------------------------
def main():
    '''Terms of the Van Eck sequence'''
    print(
        main.__doc__ + ':\n\n' +
        'First 10: '.rjust(18, ' ') + repr(vanEck(10)) + '\n' +
        '991 - 1000: '.rjust(18, ' ') + repr(vanEck(1000)[990:])
    )

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

# Just :: a -> Maybe a
def Just(x):
    '''Constructor for an inhabited Maybe (option type) value.
       Wrapper containing the result of a computation.
    '''
    return {'type': 'Maybe', 'Nothing': False, 'Just': x}

# Nothing :: Maybe a
def Nothing():
    '''Constructor for an empty Maybe (option type) value.
       Empty wrapper returned where a computation is not possible.
    '''
    return {'type': 'Maybe', 'Nothing': True}

# churchNumeral :: Int -> (a -> a) -> a -> a
def churchNumeral(n):
    '''n applications of a function
    '''
    return lambda f: lambda x: reduce(
        lambda a, g: g(a), repeat(f, n), x
    )

# cons :: a -> [a] -> [a]
def cons(x):
    '''Construction of a list from a head and a tail.
    '''
    return lambda xs: [x] + xs

# elemIndex :: Eq a => a -> [a] -> Maybe Int
def elemIndex(x):
    '''Just the index of the first element in xs
       which is equal to x,
       or Nothing if there is no such element.
    '''
    def go(xs):
        try:
            return Just(xs.index(x))
        except ValueError:
            return Nothing()
    return go

# maybe :: b -> (a -> b) -> Maybe a -> b
def maybe(v):
    '''Either the default value v, if m is Nothing,
       or the application of f to x,
       where m is Just(x).
    '''
    return lambda f: lambda m: v if None is m or m.get('Nothing') else (
        f(m.get('Just'))
    )

# succ :: Enum a => a -> a
def succ(x):
    '''The successor of a value.
       For numeric types, (1 +).
    '''
    return 1 + x

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


Van der Corput sequence

When counting integers in binary, if you put a (binary) point to the right of the count then the column immediately to the left denotes a digit with a multiplier of 2^0; the digit in the next column to the left has a multiplier of 2^1; and so on.

So in the following table:
  0.
  1.
 10.
 11.
 ...
the binary number "10" is 1 \times 2^1 + 0 \times 2^0.

You can also have binary digits to the right of the "point", just as in the decimal number system. In that case, the digit in the place immediately to the right of the point has a weight of 2^{-1}, or 1/2.
The weight for the second column to the right of the point is 2^{-2} or 1/4. And so on.

If you take the integer binary count of the first table, and ''reflect'' the digits about the binary point, you end up with '''the van der Corput sequence of numbers in base 2'''.

  .0
  .1
  .01
  .11
  ...

The third member of the sequence, binary 0.01, is therefore 0 \times 2^{-1} + 1 \times 2^{-2} or 1/4.

 Monte Carlo simulations.
This sequence is also a superset of the numbers representable by the "fraction" field of an old IEEE floating point standard. In that standard, the "fraction" field represented the fractional part of a binary number beginning with "1." e.g. 1.101001101.

'''Hint'''

A ''hint'' at a way to generate members of the sequence is to modify a routine used to change the base of an integer:
>>> def base10change(n, base):
	digits = []
	while n:
		n,remainder = divmod(n, base)
		digits.insert(0, remainder)
	return digits

>>> base10change(11, 2)
[1, 0, 1, 1]
the above showing that 11 in decimal is 1\times 2^3 + 0\times 2^2 + 1\times 2^1 + 1\times 2^0.
Reflected this would become .1101 or 1\times 2^{-1} + 1\times 2^{-2} + 0\times 2^{-3} + 1\times 2^{-4}

;Task description:
* Create a function/method/routine that given ''n'', generates the ''n'''th term of the van der Corput sequence in base 2.
* Use the function to compute ''and display'' the first ten members of the sequence. (The first member of the sequence is for ''n''=0).

* As a stretch goal/extra credit, compute and show members of the sequence for bases other than 2.

;See also:
* The Basic Low Discrepancy Sequences
* [[Non-decimal radices/Convert]]
* Van der Corput sequence

Solution:
>>> [vdc(i) for i in range(10)]
[0, 0.5, 0.25, 0.75, 0.125, 0.625, 0.375, 0.875, 0.0625, 0.5625]
>>> [vdc(i, 3) for i in range(10)]
[0, 0.3333333333333333, 0.6666666666666666, 0.1111111111111111, 0.4444444444444444, 0.7777777777777777, 0.2222222222222222, 0.5555555555555556, 0.8888888888888888, 0.037037037037037035]
>>>


Variable declaration reset

A decidely non-challenging task to highlight a potential difference between programming languages.

Using a straightforward longhand loop as in the JavaScript and Phix examples below, show the locations of elements which are identical to the immediately preceding element in {1,2,2,3,4,4,5}. The (non-blank) results may be 2,5 for zero-based or 3,6 if one-based.
The purpose is to determine whether variable declaration (in block scope) resets the contents on every iteration.
There is no particular judgement of right or wrong here, just a plain-speaking statement of subtle differences.
Should your first attempt bomb with "unassigned variable" exceptions, feel free to code it as (say)
  // int prev // crashes with unassigned variable
     int prev = -1 // predictably no output
If your programming language does not support block scope (eg assembly) it should be omitted from this task.

Solution:
s = [1, 2, 2, 3, 4, 4, 5]

for i in range(len(s)):
    curr = s[i]
    if i > 0 and curr == prev:
        print(i)
    prev = curr


Vector products

A vector is defined as having three dimensions as being represented by an ordered collection of three numbers:   (X, Y, Z).

If you imagine a graph with the   '''x'''   and   '''y'''   axis being at right angles to each other and having a third,   '''z'''   axis coming out of the page, then a triplet of numbers,   (X, Y, Z)   would represent a point in the region,   and a vector from the origin to the point.

Given the vectors:
         A = (a1,  a2,  a3)
 B = (b1,  b2,  b3)
 C = (c1,  c2,  c3)
then the following common vector products are defined:
* '''The dot product'''       (a scalar quantity)
::::  A * B = a1b1   +   a2b2   +    a3b3
* '''The cross product'''       (a vector quantity)
::::  A x B = (a2b3   -   a3b2,     a3b1   -   a1b3,     a1b2   -   a2b1)
* '''The scalar triple product'''       (a scalar quantity)
::::  A * (B x C)
* '''The vector triple product'''       (a vector quantity)
::::  A x (B x C)

;Task:
Given the three vectors:
         a = ( 3,    4,    5)
         b = ( 4,    3,    5)
         c = (-5,  -12,  -13)
# Create a named function/subroutine/method to compute the dot product of two vectors.
# Create a function to compute the cross product of two vectors.
# Optionally create a function to compute the scalar triple product of three vectors.
# Optionally create a function to compute the vector triple product of three vectors.
# Compute and display: a * b
# Compute and display: a x b
# Compute and display: a * (b x c), the scalar triple product.
# Compute and display: a x (b x c), the vector triple product.

;References:
*   A starting page on Wolfram MathWorld is   {{Wolfram|Vector|Multiplication}}.
*   Wikipedia   dot product.
*   Wikipedia   cross product.
*   Wikipedia   triple product.

;Related tasks:
*   [[Dot product]]
*   [[Quaternion type]]

Solution:
def crossp(a, b):
    '''Cross product of two 3D vectors'''
    assert len(a) == len(b) == 3, 'For 3D vectors only'
    a1, a2, a3 = a
    b1, b2, b3 = b
    return (a2*b3 - a3*b2, a3*b1 - a1*b3, a1*b2 - a2*b1)

def dotp(a,b):
    '''Dot product of two eqi-dimensioned vectors'''
    assert len(a) == len(b), 'Vector sizes must match'
    return sum(aterm * bterm for aterm,bterm in zip(a, b))

def scalartriplep(a, b, c):
    '''Scalar triple product of three vectors: "a . (b x c)"'''
    return dotp(a, crossp(b, c))

def vectortriplep(a, b, c):
    '''Vector triple product of three vectors: "a x (b x c)"'''
    return crossp(a, crossp(b, c))

if __name__ == '__main__':
    a, b, c = (3, 4, 5), (4, 3, 5), (-5, -12, -13)
    print("a = %r;  b = %r;  c = %r" % (a, b, c))
    print("a . b = %r" % dotp(a,b))
    print("a x b = %r"  % (crossp(a,b),))
    print("a . (b x c) = %r" % scalartriplep(a, b, c))
    print("a x (b x c) = %r" % (vectortriplep(a, b, c),))


Verhoeff algorithm

Description
The Verhoeff algorithm is a checksum formula for error detection developed by the Dutch mathematician Jacobus Verhoeff and first published in 1969. It was the first decimal check digit algorithm which detects all single-digit errors, and all transposition errors involving two adjacent digits, which was at the time thought impossible with such a code.

As the workings of the algorithm are clearly described in the linked Wikipedia article they will not be repeated here.

;Task:
Write routines, methods, procedures etc. in your language to generate a Verhoeff checksum digit for non-negative integers of any length and to validate the result. A combined routine is also acceptable.

The more mathematically minded may prefer to generate the 3 tables required from the description provided rather than to hard-code them.

Write your routines in such a way that they can optionally display digit by digit calculations as in the Wikipedia example.

Use your routines to calculate check digits for the integers: '''236''', '''12345''' and '''123456789012''' and then validate them. Also attempt to validate the same integers if the check digits in all cases were '''9''' rather than what they actually are.

Display digit by digit calculations for the first two integers but not for the third.

;Related task:
*   [[Damm algorithm]]

Solution:
MULTIPLICATION_TABLE = [
    (0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
    (1, 2, 3, 4, 0, 6, 7, 8, 9, 5),
    (2, 3, 4, 0, 1, 7, 8, 9, 5, 6),
    (3, 4, 0, 1, 2, 8, 9, 5, 6, 7),
    (4, 0, 1, 2, 3, 9, 5, 6, 7, 8),
    (5, 9, 8, 7, 6, 0, 4, 3, 2, 1),
    (6, 5, 9, 8, 7, 1, 0, 4, 3, 2),
    (7, 6, 5, 9, 8, 2, 1, 0, 4, 3),
    (8, 7, 6, 5, 9, 3, 2, 1, 0, 4),
    (9, 8, 7, 6, 5, 4, 3, 2, 1, 0),
]

INV = (0, 4, 3, 2, 1, 5, 6, 7, 8, 9)

PERMUTATION_TABLE = [
    (0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
    (1, 5, 7, 6, 2, 8, 3, 0, 9, 4),
    (5, 8, 0, 3, 7, 9, 6, 1, 4, 2),
    (8, 9, 1, 6, 0, 4, 3, 5, 2, 7),
    (9, 4, 5, 3, 1, 2, 6, 8, 7, 0),
    (4, 2, 8, 6, 5, 7, 3, 9, 0, 1),
    (2, 7, 9, 3, 8, 0, 6, 4, 1, 5),
    (7, 0, 4, 6, 9, 1, 3, 2, 5, 8),
]

def verhoeffchecksum(n, validate=True, terse=True, verbose=False):
    """
    Calculate the Verhoeff checksum over `n`.
    Terse mode or with single argument: return True if valid (last digit is a correct check digit).
    If checksum mode, return the expected correct checksum digit.
    If validation mode, return True if last digit checks correctly.
    """
    if verbose:
        print(f"\n{'Validation' if validate else 'Check digit'}",\
            f"calculations for {n}:\n\n i  nᵢ  p[i,nᵢ]   c\n------------------")
    # transform number list
    c, dig = 0, list(str(n if validate else 10 * n))
    for i, ni in enumerate(dig[::-1]):
        p = PERMUTATION_TABLE[i % 8][int(ni)]
        c = MULTIPLICATION_TABLE[c][p]
        if verbose:
            print(f"{i:2}  {ni}      {p}    {c}")

    if verbose and not validate:
        print(f"\ninv({c}) = {INV[c]}")
    if not terse:
        print(f"\nThe validation for '{n}' is {'correct' if c == 0 else 'incorrect'}."\
              if validate else f"\nThe check digit for '{n}' is {INV[c]}.")
    return c == 0 if validate else INV[c]

if __name__ == '__main__':

    for n, va, t, ve in [
        (236, False, False, True), (2363, True, False, True), (2369, True, False, True),
        (12345, False, False, True), (123451, True, False, True), (123459, True, False, True),
        (123456789012, False, False, False), (1234567890120, True, False, False),
        (1234567890129, True, False, False)]:
        verhoeffchecksum(n, va, t, ve)


Visualize a tree

A tree structure   (i.e. a rooted, connected acyclic graph)   is often used in programming.

It's often helpful to visually examine such a structure.

There are many ways to represent trees to a reader, such as:
:::*   indented text   (a la unix  tree  command)
:::*   nested HTML tables
:::*   hierarchical GUI widgets
:::*   2D   or   3D   images
:::*   etc.

;Task:
Write a program to produce a visual representation of some tree.

The content of the tree doesn't matter, nor does the output format, the only requirement being that the output is human friendly.

Make do with the vague term "friendly" the best you can.

Solution:
Python 3.2.3 (default, May  3 2012, 15:54:42)
[GCC 4.6.3] on linux2
Type "copyright", "credits" or "license()" for more information.
>>> help('pprint.pprint')
Help on function pprint in pprint:

pprint.pprint = pprint(object, stream=None, indent=1, width=80, depth=None)
    Pretty-print a Python object to a stream [default is sys.stdout].

>>> from pprint import pprint
>>> for tree in [ (1, 2, 3, 4, 5, 6, 7, 8),
	          (1, (( 2, 3 ), (4, (5, ((6, 7), 8))))),
	          ((((1, 2), 3), 4), 5, 6, 7, 8) ]:
	print("\nTree %r can be pprint'd as:" % (tree, ))
	pprint(tree, indent=1, width=1)

Tree (1, 2, 3, 4, 5, 6, 7, 8) can be pprint'd as:
(1,
 2,
 3,
 4,
 5,
 6,
 7,
 8)

Tree (1, ((2, 3), (4, (5, ((6, 7), 8))))) can be pprint'd as:
(1,
 ((2,
   3),
  (4,
   (5,
    ((6,
      7),
     8)))))

Tree ((((1, 2), 3), 4), 5, 6, 7, 8) can be pprint'd as:
((((1,
    2),
   3),
  4),
 5,
 6,
 7,
 8)
>>>


Visualize a tree

Solution:
'''Visualize a tree'''

from itertools import (chain, repeat, starmap)
from operator import (add)

# drawTree :: Tree a -> String
def drawTree(tree):
    '''ASCII diagram of a tree.'''
    return '\n'.join(draw(tree))

# draw :: Tree a -> [String]
def draw(node):
    '''List of the lines of an ASCII
       diagram of a tree.'''
    def shift(first, other, xs):
        return list(starmap(
            add,
            zip(
                chain([first], repeat(other, len(xs) - 1)),
                xs
            )
        ))

    def drawSubTrees(xs):
        return (
            (
                ['│'] + shift(
                    '├─ ', '│  ', draw(xs[0])
                ) + drawSubTrees(xs[1:])
            ) if 1 < len(xs) else ['│'] + shift(
                '└─ ', '   ', draw(xs[0])
            )
        ) if xs else []

    return (str(root(node))).splitlines() + (
        drawSubTrees(nest(node))
    )

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

    # tree :: Tree Int
    tree = Node(1)([
        Node(2)([
            Node(4)([
                Node(7)([])
            ]),
            Node(5)([])
        ]),
        Node(3)([
            Node(6)([
                Node(8)([]),
                Node(9)([])
            ])
        ])
    ])

    print(drawTree(tree))

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

# Node :: a -> [Tree a] -> Tree a
def Node(v):
    '''Contructor for a Tree node which connects a
       value of some kind to a list of zero or
       more child trees.'''
    return lambda xs: {'root': v, 'nest': xs}

# nest :: Tree a -> [Tree a]
def nest(tree):
    '''Accessor function for children of tree node.'''
    return tree['nest'] if 'nest' in tree else None

# root :: Dict -> a
def root(dct):
    '''Accessor function for data of tree node.'''
    return dct['root'] if 'root' in dct else None

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


Vogel's approximation method

Vogel's Approximation Method (VAM) is a technique for finding a good initial feasible solution to an allocation problem.

The powers that be have identified 5 tasks that need to be solved urgently. Being imaginative chaps, they have called them "A", "B", "C", "D", and "E". They estimate that:
* A will require 30 hours of work,
* B will require 20 hours of work,
* C will require 70 hours of work,
* D will require 30 hours of work, and
* E will require 60 hours of work.

They have identified 4 contractors willing to do the work, called "W", "X", "Y", and "Z".
* W has 50 hours available to commit to working,
* X has 60 hours available,
* Y has 50 hours available, and
* Z has 50 hours available.
The cost per hour for each contractor for each task is summarized by the following table:

   A  B  C  D  E
W 16 16 13 22 17
X 14 14 13 19 15
Y 19 19 20 23 50
Z 50 12 50 15 11

The task is to use VAM to allocate contractors to tasks. It scales to large problems, so ideally keep sorts out of the iterative cycle. It works as follows:

:Step 1: Balance the given transportation problem if either (total supply>total demand) or (total supply
        A       B       C       D       E       W       X       Y       Z
1       2       2       0       4       4       3       1       0       1   E-Z(50)

Determine the largest difference (D or E above). In the case of ties I shall choose the one with the lowest price (in this case E because the lowest price for D is Z=15, whereas for E it is Z=11). For your choice determine the minimum cost (chosen E above so Z=11 is chosen now). Allocate as much as possible from Z to E (50 in this case limited by Z's supply).
Adjust the supply and demand accordingly. If demand or supply becomes 0 for a given task or contractor it plays no further part. In this case Z is out of it. If you choose arbitrarily, and chose D see here for the working.

Repeat until all supply and demand is met:

2       2       2       0       3       2       3       1       0       -   C-W(50)
3       5       5       7       4      35       -       1       0       -   E-X(10)
4       5       5       7       4       -       -       1       0       -   C-X(20)
5       5       5       -       4       -       -       0       0       -   A-X(30)
6       -      19       -      23       -       -       -       4       -   D-Y(30)
        -       -       -       -       -       -       -       -       -   B-Y(20)

Finally calculate the cost of your solution. In the example given it is PS3100:

   A  B  C  D  E
W       50
X 30    20    10
Y    20    30
Z             50

The optimal solution determined by GLPK is PS3100:

   A  B  C  D  E
W       50
X 10 20 20    10
Y 20       30
Z             50

;Cf.
* Transportation problem

Solution:
from collections import defaultdict

costs  = {'W': {'A': 16, 'B': 16, 'C': 13, 'D': 22, 'E': 17},
          'X': {'A': 14, 'B': 14, 'C': 13, 'D': 19, 'E': 15},
          'Y': {'A': 19, 'B': 19, 'C': 20, 'D': 23, 'E': 50},
          'Z': {'A': 50, 'B': 12, 'C': 50, 'D': 15, 'E': 11}}
demand = {'A': 30, 'B': 20, 'C': 70, 'D': 30, 'E': 60}
cols = sorted(demand.iterkeys())
supply = {'W': 50, 'X': 60, 'Y': 50, 'Z': 50}
res = dict((k, defaultdict(int)) for k in costs)
g = {}
for x in supply:
    g[x] = sorted(costs[x].iterkeys(), key=lambda g: costs[x][g])
for x in demand:
    g[x] = sorted(costs.iterkeys(), key=lambda g: costs[g][x])

while g:
    d = {}
    for x in demand:
        d[x] = (costs[g[x][1]][x] - costs[g[x][0]][x]) if len(g[x]) > 1 else costs[g[x][0]][x]
    s = {}
    for x in supply:
        s[x] = (costs[x][g[x][1]] - costs[x][g[x][0]]) if len(g[x]) > 1 else costs[x][g[x][0]]
    f = max(d, key=lambda n: d[n])
    t = max(s, key=lambda n: s[n])
    t, f = (f, g[f][0]) if d[f] > s[t] else (g[t][0], t)
    v = min(supply[f], demand[t])
    res[f][t] += v
    demand[t] -= v
    if demand[t] == 0:
        for k, n in supply.iteritems():
            if n != 0:
                g[k].remove(t)
        del g[t]
        del demand[t]
    supply[f] -= v
    if supply[f] == 0:
        for k, n in demand.iteritems():
            if n != 0:
                g[k].remove(f)
        del g[f]
        del supply[f]

for n in cols:
    print "\t", n,
print
cost = 0
for g in sorted(costs):
    print g, "\t",
    for n in cols:
        y = res[g][n]
        if y != 0:
            print y,
        cost += y * costs[g][n]
        print "\t",
    print
print "\n\nTotal Cost = ", cost


Voronoi diagram

A Voronoi diagram is a diagram consisting of a number of sites.

Each Voronoi site ''s''  also has a Voronoi cell consisting of all points closest to ''s''.

;Task:
Demonstrate how to generate and display a Voroni diagram.

See algo [[K-means++ clustering]].

Solution:
from PIL import Image
import random
import math

def generate_voronoi_diagram(width, height, num_cells):
	image = Image.new("RGB", (width, height))
	putpixel = image.putpixel
	imgx, imgy = image.size
	nx = []
	ny = []
	nr = []
	ng = []
	nb = []
	for i in range(num_cells):
		nx.append(random.randrange(imgx))
		ny.append(random.randrange(imgy))
		nr.append(random.randrange(256))
		ng.append(random.randrange(256))
		nb.append(random.randrange(256))
	for y in range(imgy):
		for x in range(imgx):
			dmin = math.hypot(imgx-1, imgy-1)
			j = -1
			for i in range(num_cells):
				d = math.hypot(nx[i]-x, ny[i]-y)
				if d < dmin:
					dmin = d
					j = i
			putpixel((x, y), (nr[j], ng[j], nb[j]))
	image.save("VoronoiDiagram.png", "PNG")
        image.show()

generate_voronoi_diagram(500, 500, 25)


Wagstaff primes

Definition
A ''Wagstaff prime'' is a prime number of the form ''(2^p + 1)/3'' where the exponent ''p'' is an odd prime.

;Example
(2^5 + 1)/3 = 11 is a Wagstaff prime because both 5 and 11 are primes.

;Task
Find and show here the first ''10'' Wagstaff primes and their corresponding exponents ''p''.

;Stretch (requires arbitrary precision integers)
Find and show here the exponents ''p'' corresponding to the next ''14'' Wagstaff primes (not the primes themselves) and any more that you have the patience for.

When testing for primality, you may use a method which determines that a large number is probably prime with reasonable certainty.

;Note
It can be shown (see talk page) that ''(2^p + 1)/3'' is always integral if ''p'' is odd. So there's no need to check for that prior to checking for primality.

;References

* Wikipedia - Wagstaff prime
* OEIS:A000979 - Wagstaff primes

Solution:
""" Rosetta code Wagstaff_primes task """

from sympy import isprime

def wagstaff(N):
    """ find first N Wagstaff primes """
    pri, wcount = 1, 0
    while wcount < N:
        pri += 2
        if isprime(pri):
            wag = (2**pri + 1) // 3
            if isprime(wag):
                wcount += 1
                print(f'{wcount: 3}: {pri: 5} => ',
                      f'{wag:,}' if wcount < 11 else f'[{len(str(wag))} digit number]')

wagstaff(24)


War card game

War Card Game

Simulate the card game War.  Use the Bicycle playing card manufacturer's rules. Show a game as played.  User input is optional.

References:

:* Bicycle card company: War game site

:* Wikipedia: War (card game)

Related tasks:
* [[Playing cards]]
* [[Card shuffles]]
* [[Deal cards for FreeCell]]
* [[Poker hand_analyser]]
* [[Go Fish]]

Solution:
""" https://bicyclecards.com/how-to-play/war/ """

from numpy.random import shuffle

SUITS = ['♣', '♦', '♥', '♠']
FACES = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
DECK = [f + s for f in FACES for s in SUITS]
CARD_TO_RANK = dict((DECK[i], (i + 3) // 4) for i in range(len(DECK)))

class WarCardGame:
    """ card game War """
    def __init__(self):
        deck = DECK.copy()
        shuffle(deck)
        self.deck1, self.deck2 = deck[:26], deck[26:]
        self.pending = []

    def turn(self):
        """ one turn, may recurse on tie """
        if len(self.deck1) == 0 or len(self.deck2) == 0:
            return self.gameover()

        card1, card2 = self.deck1.pop(0), self.deck2.pop(0)
        rank1, rank2 = CARD_TO_RANK[card1], CARD_TO_RANK[card2]
        print("{:10}{:10}".format(card1, card2), end='')
        if rank1 > rank2:
            print('Player 1 takes the cards.')
            self.deck1.extend([card1, card2])
            self.deck1.extend(self.pending)
            self.pending = []
        elif rank1 < rank2:
            print('Player 2 takes the cards.')
            self.deck2.extend([card2, card1])
            self.deck2.extend(self.pending)
            self.pending = []
        else:  #  rank1 == rank2
            print('Tie!')
            if len(self.deck1) == 0 or len(self.deck2) == 0:
                return self.gameover()

            card3, card4 = self.deck1.pop(0), self.deck2.pop(0)
            self.pending.extend([card1, card2, card3, card4])
            print("{:10}{:10}".format("?", "?"), 'Cards are face down.', sep='')
            return self.turn()

        return True

    def gameover(self):
        """ game over who won message """
        if len(self.deck2) == 0:
            if len(self.deck1) == 0:
                print('\nGame ends as a tie.')
            else:
                print('\nPlayer 1 wins the game.')
        else:
            print('\nPlayer 2 wins the game.')

        return False

if __name__ == '__main__':
    WG = WarCardGame()
    while WG.turn():
        continue


Water collected between towers

In a two-dimensional world, we begin with any bar-chart (or row of close-packed 'towers', each of unit width), and then it rains,
completely filling all convex enclosures in the chart with water.

9               ##           9               ##
8               ##           8               ##
7     ##        ##           7     ####
6     ##  ##    ##           6     ######
5 ##  ##  ##  ####           5 ##########
4 ##  ##  ########           4 ############
3 ######  ########           3 ##############
2 ################  ##       2 ##################
1 ####################       1 ####################

In the example above, a bar chart representing the values [5, 3, 7, 2, 6, 4, 5, 9, 1, 2] has filled, collecting 14 units of water.

Write a function, in your language, from a given array of heights, to the number of water units that can be held in this way, by a corresponding bar chart.

Calculate the number of water units that could be collected by bar charts representing each of the following seven series:

   [[1, 5, 3, 7, 2],
    [5, 3, 7, 2, 6, 4, 5, 9, 1, 2],
    [2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1],
    [5, 5, 5, 5],
    [5, 6, 7, 8],
    [8, 7, 7, 6],
    [6, 7, 10, 7, 6]]

See, also:

* Four Solutions to a Trivial Problem - a Google Tech Talk by Guy Steele
* Water collected between towers on Stack Overflow, from which the example above is taken)
* An interesting Haskell solution, using the Tardis monad, by Phil Freeman in a Github gist.

Solution:
def water_collected(tower):
    N = len(tower)
    highest_left = [0] + [max(tower[:n]) for n in range(1,N)]
    highest_right = [max(tower[n:N]) for n in range(1,N)] + [0]
    water_level = [max(min(highest_left[n], highest_right[n]) - tower[n], 0)
        for n in range(N)]
    print("highest_left:  ", highest_left)
    print("highest_right: ", highest_right)
    print("water_level:   ", water_level)
    print("tower_level:   ", tower)
    print("total_water:   ", sum(water_level))
    print("")
    return sum(water_level)

towers = [[1, 5, 3, 7, 2],
    [5, 3, 7, 2, 6, 4, 5, 9, 1, 2],
    [2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1],
    [5, 5, 5, 5],
    [5, 6, 7, 8],
    [8, 7, 7, 6],
    [6, 7, 10, 7, 6]]

[water_collected(tower) for tower in towers]


Weird numbers

In number theory, a perfect either).

In other words, the sum of the proper divisors of the number (divisors including 1 but not itself) is greater than the number itself (the number is ''abundant''), but no subset of those divisors sums to the number itself (the number is not ''semiperfect'').

For example:

* '''12''' is ''not'' a weird number.
** It is abundant; its proper divisors '''1, 2, 3, 4, 6''' sum to '''16''' (which ''is'' > 12),
** but it ''is'' semiperfect, e.g.:     '''6 + 4 + 2 == 12'''.
* '''70''' ''is'' a weird number.
** It is abundant; its proper divisors '''1, 2, 5, 7, 10, 14, 35''' sum to '''74''' (which ''is'' > 70),
** and there is no subset of proper divisors that sum to '''70'''.

;Task:
Find and display, here on this page, the first '''25''' weird numbers.

;Related tasks:
:* Abundant, deficient and perfect number classifications
:* Proper divisors

;See also:
:* OEIS: A006037 weird numbers
:* Wikipedia: weird number
:* MathWorld: weird number

Solution:
'''Weird numbers'''

from itertools import chain, count, islice, repeat
from functools import reduce
from math import sqrt
from time import time

# weirds :: Gen [Int]
def weirds():
    '''Non-finite stream of weird numbers.
       (Abundant, but not semi-perfect)
       OEIS: A006037
    '''
    def go(n):
        ds = descPropDivs(n)
        d = sum(ds) - n
        return [n] if 0 < d and not hasSum(d, ds) else []
    return concatMap(go)(count(1))

# hasSum :: Int -> [Int] -> Bool
def hasSum(n, xs):
    '''Does any subset of xs sum to n ?
       (Assuming xs to be sorted in descending
       order of magnitude)'''
    def go(n, xs):
        if xs:
            h, t = xs[0], xs[1:]
            if n < h:  # Head too big. Forget it. Tail ?
                return go(n, t)
            else:
                # The head IS the target ?
                # Or the tail contains a sum for the
                # DIFFERENCE between the head and the target ?
                # Or the tail contains some OTHER sum for the target ?
                return n == h or go(n - h, t) or go(n, t)
        else:
            return False
    return go(n, xs)

# descPropDivs :: Int -> [Int]
def descPropDivs(n):
    '''Descending positive divisors of n,
       excluding n itself.'''
    root = sqrt(n)
    intRoot = int(root)
    blnSqr = root == intRoot
    lows = [x for x in range(1, 1 + intRoot) if 0 == n % x]
    return [
        n // x for x in (
            lows[1:-1] if blnSqr else lows[1:]
        )
    ] + list(reversed(lows))

# --------------------------TEST---------------------------

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

    start = time()
    n = 50
    xs = take(n)(weirds())

    print(
        (tabulated('First ' + str(n) + ' weird numbers:\n')(
            lambda i: str(1 + i)
        )(str)(5)(
            index(xs)
        )(range(0, n)))
    )
    print(
        '\nApprox computation time: ' +
        str(int(1000 * (time() - start))) + ' ms'
    )

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

# chunksOf :: Int -> [a] -> [[a]]
def chunksOf(n):
    '''A series of lists of length n,
       subdividing the contents of xs.
       Where the length of xs is not evenly divible,
       the final list will be shorter than n.'''
    return lambda xs: reduce(
        lambda a, i: a + [xs[i:n + i]],
        range(0, len(xs), n), []
    ) if 0 < n else []

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

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

# index (!!) :: [a] -> Int -> a
def index(xs):
    '''Item at given (zero-based) index.'''
    return lambda n: None if 0 > n else (
        xs[n] if (
            hasattr(xs, "__getitem__")
        ) else next(islice(xs, n, None))
    )

# paddedMatrix :: a -> [[a]] -> [[a]]
def paddedMatrix(v):
    ''''A list of rows padded to equal length
        (where needed) with instances of the value v.'''
    def go(rows):
        return paddedRows(
            len(max(rows, key=len))
        )(v)(rows)
    return lambda rows: go(rows) if rows else []

# paddedRows :: Int -> a -> [[a]] -[[a]]
def paddedRows(n):
    '''A list of rows padded (but never truncated)
       to length n with copies of value v.'''
    def go(v, xs):
        def pad(x):
            d = n - len(x)
            return (x + list(repeat(v, d))) if 0 < d else x
        return list(map(pad, xs))
    return lambda v: lambda xs: go(v, xs) if xs else []

# showColumns :: Int -> [String] -> String
def showColumns(n):
    '''A column-wrapped string
       derived from a list of rows.'''
    def go(xs):
        def fit(col):
            w = len(max(col, key=len))

            def pad(x):
                return x.ljust(4 + w, ' ')
            return ''.join(map(pad, col))

        q, r = divmod(len(xs), n)
        return unlines(map(
            fit,
            transpose(paddedMatrix('')(
                chunksOf(q + int(bool(r)))(
                    xs
                )
            ))
        ))
    return lambda xs: go(xs)

# succ :: Enum a => a -> a
def succ(x):
    '''The successor of a value. For numeric types, (1 +).'''
    return 1 + x if isinstance(x, int) else (
        chr(1 + ord(x))
    )

# tabulated :: String -> (a -> String) ->
#                        (b -> String) ->
#                        Int ->
#                        (a -> b) -> [a] -> String
def tabulated(s):
    '''Heading -> x display function -> fx display function ->
          number of columns -> f -> value list -> tabular string.'''
    def go(xShow, fxShow, intCols, f, xs):
        w = max(map(compose(len)(xShow), xs))
        return s + '\n' + showColumns(intCols)([
            xShow(x).rjust(w, ' ') + ' -> ' + fxShow(f(x)) for x in xs
        ])
    return lambda xShow: lambda fxShow: lambda nCols: (
        lambda f: lambda xs: go(
            xShow, fxShow, nCols, f, xs
        )
    )

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

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

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

# until :: (a -> Bool) -> (a -> a) -> a -> a
def until(p):
    '''The result of repeatedly applying f until p holds.
       The initial seed value is x.'''
    def go(f, x):
        v = x
        while not p(v):
            v = f(v)
        return v
    return lambda f: lambda x: go(f, x)

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


Word frequency

Given a text file and an integer   '''n''',   print/display the   '''n'''   most
common words in the file   (and the number of their occurrences)   in decreasing frequency.

For the purposes of this task:
*   A word is a sequence of one or more contiguous letters.
*   You are free to define what a   ''letter''   is.
*   Underscores, accented letters, apostrophes, hyphens, and other special characters can be handled at your discretion.
*   You may treat a compound word like   '''well-dressed'''   as either one word or two.
*   The word   '''it's'''   could also be one or two words as you see fit.
*   You may also choose not to support non US-ASCII characters.
*   Assume words will not span multiple lines.
*   Don't worry about normalization of word spelling differences.
*   Treat   '''color'''   and   '''colour'''   as two distinct words.
*   Uppercase letters are considered equivalent to their lowercase counterparts.
*   Words of equal frequency can be listed in any order.
*   Feel free to explicitly state the thoughts behind the program decisions.

Show example output using Les Miserables from Project Gutenberg as the text file input and display the top   '''10'''   most used words.

;History:
This task was originally taken from programming pearls from Communications of the ACM June 1986 Volume 29 Number 6
where this problem is solved by Donald Knuth using literate programming and then critiqued by Doug McIlroy,
demonstrating solving the problem in a 6 line Unix shell script (provided as an example below).

;References:
*McIlroy's program

Solution:
import collections
import re
import string
import sys

def main():
  counter = collections.Counter(re.findall(r"\w+",open(sys.argv[1]).read().lower()))
  print counter.most_common(int(sys.argv[2]))

if __name__ == "__main__":
  main()


Word frequency

Solution:
"""
Word count task from Rosetta Code
http://www.rosettacode.org/wiki/Word_count#Python
"""
from itertools import (groupby,
                       starmap)
from operator import itemgetter
from pathlib import Path
from typing import (Iterable,
                    List,
                    Tuple)

FILEPATH = Path('lesMiserables.txt')
COUNT = 10

def main():
    words_and_counts = most_frequent_words(FILEPATH)
    print(*words_and_counts[:COUNT], sep='\n')

def most_frequent_words(filepath: Path,
                        *,
                        encoding: str = 'utf-8') -> List[Tuple[str, int]]:
    """
    A list of word-frequency pairs sorted by their occurrences.
    The words are read from the given file.
    """
    def word_and_frequency(word: str,
                           words_group: Iterable[str]) -> Tuple[str, int]:
        return word, capacity(words_group)

    file_contents = filepath.read_text(encoding=encoding)
    words = file_contents.lower().split()
    grouped_words = groupby(sorted(words))
    words_and_frequencies = starmap(word_and_frequency, grouped_words)
    return sorted(words_and_frequencies, key=itemgetter(1), reverse=True)

def capacity(iterable: Iterable) -> int:
    """Returns a number of elements in an iterable"""
    return sum(1 for _ in iterable)

if __name__ == '__main__':
    main()


Word ladder

Yet another shortest path problem. Given two words of equal length the task is to transpose the first into the second.

Only one letter may be changed at a time and the change must result in a word in unixdict, the minimum number of intermediate words should be used.

Demonstrate the following:

A boy can be made into a man: boy -> bay -> ban -> man

With a little more difficulty a girl can be made into a lady: girl -> gill -> gall -> gale -> gaze -> laze -> lazy -> lady

A john can be made into a jane: john -> cohn -> conn -> cone -> cane -> jane

A child can not be turned into an adult.

Optional transpositions of your choice.

Solution:
import os,sys,zlib,urllib.request

def h ( str,x=9 ):
    for c in str :
        x = ( x*33 + ord( c )) & 0xffffffffff
    return x

def cache ( func,*param ):
    n = 'cache_%x.bin'%abs( h( repr( param )))
    try    : return eval( zlib.decompress( open( n,'rb' ).read()))
    except : pass
    s = func( *param )
    open( n,'wb' ).write( zlib.compress( bytes( repr( s ),'ascii' )))
    return s

dico_url  = 'https://raw.githubusercontent.com/quinnj/Rosetta-Julia/master/unixdict.txt'
read_url  = lambda url   : urllib.request.urlopen( url ).read()
load_dico = lambda url   : tuple( cache( read_url,url ).split( b'\n'))
isnext    = lambda w1,w2 : len( w1 ) == len( w2 ) and len( list( filter( lambda l : l[0]!=l[1] , zip( w1,w2 )))) == 1

def build_map ( words ):
    map = [(w.decode('ascii'),[]) for w in words]
    for i1,(w1,n1) in enumerate( map ):
        for i2,(w2,n2) in enumerate( map[i1+1:],i1+1 ):
            if isnext( w1,w2 ):
                n1.append( i2 )
                n2.append( i1 )
    return map

def find_path ( words,w1,w2 ):
    i = [w[0] for w in words].index( w1 )
    front,done,res  = [i],{i:-1},[]
    while front :
        i = front.pop(0)
        word,next = words[i]
        for n in next :
            if n in done : continue
            done[n] = i
            if words[n][0] == w2 :
                while n >= 0 :
                    res = [words[n][0]] + res
                    n = done[n]
                return ' '.join( res )
            front.append( n )
    return '%s can not be turned into %s'%( w1,w2 )

for w in ('boy man','girl lady','john jane','alien drool','child adult'):
    print( find_path( cache( build_map,load_dico( dico_url )),*w.split()))


Word search

A word search puzzle typically consists of a grid of letters in which words are hidden.

There are many varieties of word search puzzles. For the task at hand we will use a rectangular grid in which the words may be placed horizontally, vertically, or diagonally. The words may also be spelled backwards.

The words may overlap but are not allowed to zigzag, or wrap around.

;Task
Create a 10 by 10 word search and fill it using words from the unixdict. Use only words that are longer than 2, and contain no non-alphabetic characters.

The cells not used by the hidden words should contain the message: ''Rosetta Code'', read from left to right, top to bottom. These letters should be somewhat evenly distributed over the grid, not clumped together. The message should be in upper case, the hidden words in lower case. All cells should either contain letters from the hidden words or from the message.

Pack a minimum of 25 words into the grid.

Print the resulting grid and the solutions.

;Example

     0  1  2  3  4  5  6  7  8  9

0    n  a  y  r  y  R  e  l  m  f
1    y  O  r  e  t  s  g  n  a  g
2    t  n  e  d  i  S  k  y  h  E
3    n  o  t  n  c  p  c  w  t  T
4    a  l  s  u  u  n  T  m  a  x
5    r  o  k  p  a  r  i  s  h  h
6    a  A  c  f  p  a  e  a  c  C
7    u  b  u  t  t  t  O  l  u  n
8    g  y  h  w  a  D  h  p  m  u
9    m  i  r  p  E  h  o  g  a  n

parish     (3,5)(8,5)   gangster   (9,1)(2,1)
paucity    (4,6)(4,0)   guaranty   (0,8)(0,1)
prim       (3,9)(0,9)   huckster   (2,8)(2,1)
plasm      (7,8)(7,4)   fancy      (3,6)(7,2)
hogan      (5,9)(9,9)   nolo       (1,2)(1,5)
under      (3,4)(3,0)   chatham    (8,6)(8,0)
ate        (4,8)(6,6)   nun        (9,7)(9,9)
butt       (1,7)(4,7)   hawk       (9,5)(6,2)
why        (3,8)(1,8)   ryan       (3,0)(0,0)
fay        (9,0)(7,2)   much       (8,8)(8,5)
tar        (5,7)(5,5)   elm        (6,0)(8,0)
max        (7,4)(9,4)   pup        (5,3)(3,5)
mph        (8,8)(6,8)

Solution:
import re
from random import shuffle, randint

dirs = [[1, 0], [0, 1], [1, 1], [1, -1], [-1, 0], [0, -1], [-1, -1], [-1, 1]]
n_rows = 10
n_cols = 10
grid_size = n_rows * n_cols
min_words = 25

class Grid:
    def __init__(self):
        self.num_attempts = 0
        self.cells = [['' for _ in range(n_cols)] for _ in range(n_rows)]
        self.solutions = []

def read_words(filename):
    max_len = max(n_rows, n_cols)

    words = []
    with open(filename, "r") as file:
        for line in file:
            s = line.strip().lower()
            if re.match(r'^[a-z]{3,' + re.escape(str(max_len)) + r'}$', s) is not None:
                words.append(s)

    return words

def place_message(grid, msg):
    msg = re.sub(r'[^A-Z]', "", msg.upper())

    message_len = len(msg)
    if 0 < message_len < grid_size:
        gap_size = grid_size // message_len

        for i in range(0, message_len):
            pos = i * gap_size + randint(0, gap_size)
            grid.cells[pos // n_cols][pos % n_cols] = msg[i]

        return message_len

    return 0

def try_location(grid, word, direction, pos):
    r = pos // n_cols
    c = pos % n_cols
    length = len(word)

    # check bounds
    if (dirs[direction][0] == 1 and (length + c) > n_cols) or \
       (dirs[direction][0] == -1 and (length - 1) > c) or \
       (dirs[direction][1] == 1 and (length + r) > n_rows) or \
       (dirs[direction][1] == -1 and (length - 1) > r):
        return 0

    rr = r
    cc = c
    i = 0
    overlaps = 0

    # check cells
    while i < length:
        if grid.cells[rr][cc] != '' and grid.cells[rr][cc] != word[i]:
            return 0
        cc += dirs[direction][0]
        rr += dirs[direction][1]
        i += 1

    rr = r
    cc = c
    i = 0
    # place
    while i < length:
        if grid.cells[rr][cc] == word[i]:
            overlaps += 1
        else:
            grid.cells[rr][cc] = word[i]

        if i < length - 1:
            cc += dirs[direction][0]
            rr += dirs[direction][1]

        i += 1

    letters_placed = length - overlaps
    if letters_placed > 0:
        grid.solutions.append("{0:<10} ({1},{2})({3},{4})".format(word, c, r, cc, rr))

    return letters_placed

def try_place_word(grid, word):
    rand_dir = randint(0, len(dirs))
    rand_pos = randint(0, grid_size)

    for direction in range(0, len(dirs)):
        direction = (direction + rand_dir) % len(dirs)

        for pos in range(0, grid_size):
            pos = (pos + rand_pos) % grid_size

            letters_placed = try_location(grid, word, direction, pos)
            if letters_placed > 0:
                return letters_placed

    return 0

def create_word_search(words):
    grid = None
    num_attempts = 0

    while num_attempts < 100:
        num_attempts += 1
        shuffle(words)

        grid = Grid()
        message_len = place_message(grid, "Rosetta Code")
        target = grid_size - message_len

        cells_filled = 0
        for word in words:
            cells_filled += try_place_word(grid, word)
            if cells_filled == target:
                if len(grid.solutions) >= min_words:
                    grid.num_attempts = num_attempts
                    return grid
                else:
                    break # grid is full but we didn't pack enough words, start over

    return grid

def print_result(grid):
    if grid is None or grid.num_attempts == 0:
        print("No grid to display")
        return

    size = len(grid.solutions)

    print("Attempts: {0}".format(grid.num_attempts))
    print("Number of words: {0}".format(size))

    print("\n     0  1  2  3  4  5  6  7  8  9\n")
    for r in range(0, n_rows):
        print("{0}   ".format(r), end='')
        for c in range(0, n_cols):
            print(" %c " % grid.cells[r][c], end='')
        print()
    print()

    for i in range(0, size - 1, 2):
        print("{0}   {1}".format(grid.solutions[i], grid.solutions[i+1]))

    if size % 2 == 1:
        print(grid.solutions[size - 1])

if __name__ == "__main__":
    print_result(create_word_search(read_words("unixdict.txt")))


Word wrap

Even today, with proportional fonts and complex layouts, there are still cases where you need to wrap text at a specified column.

;Basic task:
The basic task is to wrap a paragraph of text in a simple way in your language.

If there is a way to do this that is built-in, trivial, or provided in a standard library, show that.  Otherwise implement the minimum length greedy algorithm from Wikipedia.

Show your routine working on a sample of text at two different wrap columns.

;Extra credit:
Wrap text using a more sophisticated algorithm such as the Knuth and Plass TeX algorithm.
If your language provides this, you get easy extra credit,
but you ''must reference documentation'' indicating that the algorithm
is something better than a simple minimum length algorithm.

If you have both basic and extra credit solutions, show an example where
the two algorithms give different results.

Solution:
>>> import textwrap
>>> help(textwrap.fill)
Help on function fill in module textwrap:

fill(text, width=70, **kwargs)
    Fill a single paragraph of text, returning a new string.

    Reformat the single paragraph in 'text' to fit in lines of no more
    than 'width' columns, and return a new string containing the entire
    wrapped paragraph.  As with wrap(), tabs are expanded and other
    whitespace characters converted to space.  See TextWrapper class for
    available keyword args to customize wrapping behaviour.

>>> txt = '''\
Reformat the single paragraph in 'text' to fit in lines of no more
than 'width' columns, and return a new string containing the entire
wrapped paragraph.  As with wrap(), tabs are expanded and other
whitespace characters converted to space.  See TextWrapper class for
available keyword args to customize wrapping behaviour.'''
>>> print(textwrap.fill(txt, width=75))
Reformat the single paragraph in 'text' to fit in lines of no more than
'width' columns, and return a new string containing the entire wrapped
paragraph.  As with wrap(), tabs are expanded and other whitespace
characters converted to space.  See TextWrapper class for available keyword
args to customize wrapping behaviour.
>>> print(textwrap.fill(txt, width=45))
Reformat the single paragraph in 'text' to
fit in lines of no more than 'width' columns,
and return a new string containing the entire
wrapped paragraph.  As with wrap(), tabs are
expanded and other whitespace characters
converted to space.  See TextWrapper class
for available keyword args to customize
wrapping behaviour.
>>> print(textwrap.fill(txt, width=85))
Reformat the single paragraph in 'text' to fit in lines of no more than 'width'
columns, and return a new string containing the entire wrapped paragraph.  As with
wrap(), tabs are expanded and other whitespace characters converted to space.  See
TextWrapper class for available keyword args to customize wrapping behaviour.
>>>


World Cup group stage

It's World Cup season (or at least it was when this page was created)!

The World Cup is an international football/soccer tournament that happens every 4 years.   Countries put their international teams together in the years between tournaments and qualify for the tournament based on their performance in other international games.   Once a team has qualified they are put into a group with 3 other teams.

For the first part of the World Cup tournament the teams play in "group stage" games where each of the four teams in a group plays all three other teams once.   The results of these games determine which teams will move on to the "knockout stage" which is a standard single-elimination tournament.   The two teams from each group with the most standings points move on to the knockout stage.

Each game can result in a win for one team and a loss for the other team or it can result in a draw/tie for each team.
:::*   A win is worth three points.
:::*   A draw/tie is worth one point.
:::*   A loss is worth zero points.

;Task:
:*   Generate all possible outcome combinations for the six group stage games.   With three possible outcomes for each game there should be 36 = 729 of them.
:*   Calculate the standings points for each team with each combination of outcomes.
:*   Show a histogram (graphical,   ASCII art, or straight counts--whichever is easiest/most fun) of the standings points for all four teams over all possible outcomes.

Don't worry about tiebreakers as they can get complicated.   We are basically looking to answer the question "if a team gets x standings points, where can they expect to end up in the group standings?".

''Hint: there should be no possible way to end up in second place with less than two points as well as no way to end up in first with less than three.   Oddly enough, there is no way to get 8 points at all.''

Solution:
from itertools import product, combinations, izip

scoring = [0, 1, 3]
histo = [[0] * 10 for _ in xrange(4)]

for results in product(range(3), repeat=6):
    s = [0] * 4
    for r, g in izip(results, combinations(range(4), 2)):
        s[g[0]] += scoring[r]
        s[g[1]] += scoring[2 - r]

    for h, v in izip(histo, sorted(s)):
        h[v] += 1

for x in reversed(histo):
    print x


Write float arrays to a text file

Write two equal-sized numerical arrays 'x' and 'y' to
a two-column text file named 'filename'.

The first column of the file contains values from an 'x'-array with a
given 'xprecision', the second -- values from 'y'-array with 'yprecision'.

For example, considering:
    x = {1, 2, 3, 1e11};
    y = {1, 1.4142135623730951, 1.7320508075688772, 316227.76601683791};
                                                           /* sqrt(x) */
    xprecision = 3;
    yprecision = 5;

The file should look like:
    1    1
    2    1.4142
    3    1.7321
    1e+011   3.1623e+005

This task is intended as a subtask for [[Measure relative performance of sorting algorithms implementations]].

Solution:
>>> import math
>>> x = [1, 2, 3, 1e11]
>>> y = map(math.sqrt, x)
>>> y
[1.0, 1.4142135623730951, 1.7320508075688772, 316227.76601683791]
>>> writedat("sqrt.dat", x, y)
>>> # check
...
>>> for line in open('sqrt.dat'):
...   print line,
...
1       1
2       1.4142
3       1.7321
1e+011  3.1623e+005


Write float arrays to a text file

Solution:
def writedat(filename, x, y, xprecision=3, yprecision=5):
    with open(filename,'w') as f:
        for a, b in zip(x, y):
            print("%.*g\t%.*g" % (xprecision, a, yprecision, b), file=f)
            #or, using the new-style formatting:
            #print("{1:.{0}g}\t{3:.{2}g}".format(xprecision, a, yprecision, b), file=f)


Write language name in 3D ASCII

Write/display a language's name in '''3D''' ASCII.

(We can leave the definition of "3D ASCII" fuzzy,
so long as the result is interesting or amusing,
not a cheap hack to satisfy the task.)

;Related tasks:
* draw a sphere
* draw a cuboid
* draw a rotating cube
* draw a Deathstar

Solution:
py = '''\
 ####   #   #  #####  #   #   ###   #   #
 #   #   # #     #    #   #  #   #  ##  #
 ####     #      #    #####  #   #  # # #
 #        #      #    #   #  #   #  #  ##
 #        #      #    #   #   ###   #   #'''

lines = py.replace('#', '<<<').replace(' ','X') \
        .replace('X', '   ').replace('\n', ' Y') \
        .replace('< ', '<>').split('Y')

for i, l in enumerate(lines):
    print('  ' * (len(lines) - i) + l)


Yellowstone sequence

The '''Yellowstone sequence''', also called the '''Yellowstone permutation''', is defined as:

For n <= 3,

    a(n) = n

For n >= 4,

    a(n) = the smallest number not already in sequence such that a(n) is relatively prime to a(n-1) and
           is not relatively prime to a(n-2).

The sequence is a permutation of the natural numbers, and gets its name from what its authors felt was a spiking, geyser like appearance of a plot of the sequence.

;Example:
a(4) is 4 because 4 is the smallest number following 1, 2, 3 in the sequence that is relatively prime to the entry before it (3), and is not relatively prime to the number two entries before it (2).

;Task
: Find and show as output the first  '''30'''  Yellowstone numbers.

;Extra
:  Demonstrate how to plot, with x = n and y coordinate a(n), the first 100 Yellowstone numbers.

;Related tasks:
:*   Greatest common divisor.
:*   Plot coordinate pairs.

;See also:
:*   The OEIS entry:   A098550 The Yellowstone permutation.
:*   Applegate et al, 2015: The Yellowstone Permutation [https://arxiv.org/abs/1501.01669].

Solution:
'''Yellowstone permutation OEIS A098550'''

from itertools import chain, count, islice
from operator import itemgetter
from math import gcd

from matplotlib import pyplot

# yellowstone :: [Int]
def yellowstone():
    '''A non-finite stream of terms from
       the Yellowstone permutation.
       OEIS A098550.
    '''
    # relativelyPrime :: Int -> Int -> Bool
    def relativelyPrime(a):
        return lambda b: 1 == gcd(a, b)

    # nextWindow :: (Int, Int, [Int]) -> (Int, Int, [Int])
    def nextWindow(triple):
        p2, p1, rest = triple
        [rp2, rp1] = map(relativelyPrime, [p2, p1])

        # match :: [Int] -> (Int, [Int])
        def match(xxs):
            x, xs = uncons(xxs)['Just']
            return (x, xs) if rp1(x) and not rp2(x) else (
                second(cons(x))(
                    match(xs)
                )
            )
        n, residue = match(rest)
        return (p1, n, residue)

    return chain(
        range(1, 3),
        map(
            itemgetter(1),
            iterate(nextWindow)(
                (2, 3, count(4))
            )
        )
    )

# TEST ----------------------------------------------------
# main :: IO ()
def main():
    '''Terms of the Yellowstone permutation.'''

    print(showList(
        take(30)(yellowstone())
    ))
    pyplot.plot(
        take(100)(yellowstone())
    )
    pyplot.xlabel(main.__doc__)
    pyplot.show()

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

# Just :: a -> Maybe a
def Just(x):
    '''Constructor for an inhabited Maybe (option type) value.
       Wrapper containing the result of a computation.
    '''
    return {'type': 'Maybe', 'Nothing': False, 'Just': x}

# Nothing :: Maybe a
def Nothing():
    '''Constructor for an empty Maybe (option type) value.
       Empty wrapper returned where a computation is not possible.
    '''
    return {'type': 'Maybe', 'Nothing': True}

# cons :: a -> [a] -> [a]
def cons(x):
    '''Construction of a list from x as head,
       and xs as tail.
    '''
    return lambda xs: [x] + xs if (
        isinstance(xs, list)
    ) else x + xs if (
        isinstance(xs, str)
    ) else chain([x], xs)

# iterate :: (a -> a) -> a -> Gen [a]
def iterate(f):
    '''An infinite list of repeated
       applications of f to x.
    '''
    def go(x):
        v = x
        while True:
            yield v
            v = f(v)
    return go

# second :: (a -> b) -> ((c, a) -> (c, b))
def second(f):
    '''A simple function lifted to a function over a tuple,
       with f applied only to the second of two values.
    '''
    return lambda xy: (xy[0], f(xy[1]))

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

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

# uncons :: [a] -> Maybe (a, [a])
def uncons(xs):
    '''The deconstruction of a non-empty list
       (or generator stream) into two parts:
       a head value, and the remaining values.
    '''
    if isinstance(xs, list):
        return Just((xs[0], xs[1:])) if xs else Nothing()
    else:
        nxt = take(1)(xs)
        return Just((nxt[0], xs)) if nxt else Nothing()

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


Zeckendorf number representation

Just as numbers can be represented in a positional notation as sums of multiples of the powers of ten (decimal) or two (binary); all the positive integers can be represented as the sum of one or zero times the distinct members of the Fibonacci series.

Recall that the first six distinct Fibonacci numbers are:  1, 2, 3, 5, 8, 13.

The decimal number eleven can be written as 0*13 + 1*8 + 0*5 + 1*3 + 0*2 + 0*1 or 010100 in positional notation where the columns represent multiplication by a particular member of the sequence. Leading zeroes are dropped so that 11 decimal becomes 10100.

10100 is not the only way to make 11 from the Fibonacci numbers however;  0*13 + 1*8 + 0*5 + 0*3 + 1*2 + 1*1 or 010011 would also represent decimal 11. For a true Zeckendorf number there is the added restriction that ''no two consecutive Fibonacci numbers can be used'' which leads to the former unique solution.

;Task:
Generate and show here a table of the Zeckendorf number representations of the decimal numbers zero to twenty, in order.

The intention in this task to find the Zeckendorf form of an arbitrary integer.  The Zeckendorf form can be iterated by some bit twiddling rather than calculating each value separately but leave that to another separate task.

;Also see:
*   OEIS A014417   for the the sequence of required results.
*   Brown's Criterion - Numberphile

;Related task:
*   [[Fibonacci sequence]]

Solution:
def fib():
    memo = [1, 2]
    while True:
        memo.append(sum(memo))
        yield memo.pop(0)

def sequence_down_from_n(n, seq_generator):
    seq = []
    for s in seq_generator():
        seq.append(s)
        if s >= n: break
    return seq[::-1]

def zeckendorf(n):
    if n == 0: return [0]
    seq = sequence_down_from_n(n, fib)
    digits, nleft = [], n
    for s in seq:
        if s <= nleft:
            digits.append(1)
            nleft -= s
        else:
            digits.append(0)
    assert nleft == 0, 'Check all of n is accounted for'
    assert sum(x*y for x,y in zip(digits, seq)) == n, 'Assert digits are correct'
    while digits[0] == 0:
        # Remove any zeroes padding L.H.S.
        digits.pop(0)
    return digits

n = 20
print('Fibonacci digit multipliers: %r' % sequence_down_from_n(n, fib))
for i in range(n + 1):
    print('%3i: %8s' % (i, ''.join(str(d) for d in zeckendorf(i))))


Zero to the zero power

Some computer programming languages are not exactly consistent   (with other computer programming languages)
when   ''raising zero to the zeroth power'':     00

;Task:
Show the results of raising   zero   to the   zeroth   power.

If your computer language objects to      '''0**0'''      or      '''0^0'''      at compile time,   you may also try something like:
            x = 0
            y = 0
            z = x**y
            say  'z='  z

'''Show the result here.'''
And of course use any symbols or notation that is supported in your computer programming language for exponentiation.

;See also:
* The Wiki entry: Zero to the power of zero.
* The Wiki entry: Zero to the power of zero: History.
* The MathWorld(tm) entry: exponent laws.
** Also, in the above MathWorld(tm) entry, see formula ('''9'''): x^0=1.
* The OEIS entry: The special case of zero to the zeroth power

Solution:
from decimal import Decimal
from fractions import Fraction
from itertools import product

zeroes = [0, 0.0, 0j, Decimal(0), Fraction(0, 1), -0.0, -0.0j, Decimal(-0.0)]
for i, j in product(zeroes, repeat=2):
    try:
        ans = i**j
    except:
        ans = '<Exception raised>'
    print(f'{i!r:>15} ** {j!r:<15} = {ans!r}')


Zhang-Suen thinning algorithm

Solution:
# -*- coding: utf-8 -*-

# Example from [http://nayefreza.wordpress.com/2013/05/11/zhang-suen-thinning-algorithm-java-implementation/ this blog post].
beforeTxt = '''\
1100111
1100111
1100111
1100111
1100110
1100110
1100110
1100110
1100110
1100110
1100110
1100110
1111110
0000000\
'''

# Thanks to [http://www.network-science.de/ascii/ this site] and vim for these next two examples
smallrc01 = '''\
00000000000000000000000000000000
01111111110000000111111110000000
01110001111000001111001111000000
01110000111000001110000111000000
01110001111000001110000000000000
01111111110000001110000000000000
01110111100000001110000111000000
01110011110011101111001111011100
01110001111011100111111110011100
00000000000000000000000000000000\
'''

rc01 = '''\
00000000000000000000000000000000000000000000000000000000000
01111111111111111100000000000000000001111111111111000000000
01111111111111111110000000000000001111111111111111000000000
01111111111111111111000000000000111111111111111111000000000
01111111100000111111100000000001111111111111111111000000000
00011111100000111111100000000011111110000000111111000000000
00011111100000111111100000000111111100000000000000000000000
00011111111111111111000000000111111100000000000000000000000
00011111111111111110000000000111111100000000000000000000000
00011111111111111111000000000111111100000000000000000000000
00011111100000111111100000000111111100000000000000000000000
00011111100000111111100000000111111100000000000000000000000
00011111100000111111100000000011111110000000111111000000000
01111111100000111111100000000001111111111111111111000000000
01111111100000111111101111110000111111111111111111011111100
01111111100000111111101111110000001111111111111111011111100
01111111100000111111101111110000000001111111111111011111100
00000000000000000000000000000000000000000000000000000000000\
'''

def intarray(binstring):
    '''Change a 2D matrix of 01 chars into a list of lists of ints'''
    return [[1 if ch == '1' else 0 for ch in line]
            for line in binstring.strip().split()]

def chararray(intmatrix):
    '''Change a 2d list of lists of 1/0 ints into lines of 1/0 chars'''
    return '\n'.join(''.join(str(p) for p in row) for row in intmatrix)

def toTxt(intmatrix):
    '''Change a 2d list of lists of 1/0 ints into lines of '#' and '.' chars'''
    return '\n'.join(''.join(('#' if p else '.') for p in row) for row in intmatrix)

def neighbours(x, y, image):
    '''Return 8-neighbours of point p1 of picture, in order'''
    i = image
    x1, y1, x_1, y_1 = x+1, y-1, x-1, y+1
    #print ((x,y))
    return [i[y1][x],  i[y1][x1],   i[y][x1],  i[y_1][x1],  # P2,P3,P4,P5
            i[y_1][x], i[y_1][x_1], i[y][x_1], i[y1][x_1]]  # P6,P7,P8,P9

def transitions(neighbours):
    n = neighbours + neighbours[0:1]    # P2, ... P9, P2
    return sum((n1, n2) == (0, 1) for n1, n2 in zip(n, n[1:]))

def zhangSuen(image):
    changing1 = changing2 = [(-1, -1)]
    while changing1 or changing2:
        # Step 1
        changing1 = []
        for y in range(1, len(image) - 1):
            for x in range(1, len(image[0]) - 1):
                P2,P3,P4,P5,P6,P7,P8,P9 = n = neighbours(x, y, image)
                if (image[y][x] == 1 and    # (Condition 0)
                    P4 * P6 * P8 == 0 and   # Condition 4
                    P2 * P4 * P6 == 0 and   # Condition 3
                    transitions(n) == 1 and # Condition 2
                    2 <= sum(n) <= 6):      # Condition 1
                    changing1.append((x,y))
        for x, y in changing1: image[y][x] = 0
        # Step 2
        changing2 = []
        for y in range(1, len(image) - 1):
            for x in range(1, len(image[0]) - 1):
                P2,P3,P4,P5,P6,P7,P8,P9 = n = neighbours(x, y, image)
                if (image[y][x] == 1 and    # (Condition 0)
                    P2 * P6 * P8 == 0 and   # Condition 4
                    P2 * P4 * P8 == 0 and   # Condition 3
                    transitions(n) == 1 and # Condition 2
                    2 <= sum(n) <= 6):      # Condition 1
                    changing2.append((x,y))
        for x, y in changing2: image[y][x] = 0
        #print changing1
        #print changing2
    return image

if __name__ == '__main__':
    for picture in (beforeTxt, smallrc01, rc01):
        image = intarray(picture)
        print('\nFrom:\n%s' % toTxt(image))
        after = zhangSuen(image)
        print('\nTo thinned:\n%s' % toTxt(after))