Greedy algorithm for Egyptian fractions

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

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

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

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

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

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

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

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

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

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

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

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

;Also see:
*   Wolfram MathWorld(tm) entry: Egyptian fraction

Solution:
from fractions import Fraction
from math import ceil

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

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

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


Greedy algorithm for Egyptian fractions

Solution:
'''Egyptian fractions'''

from fractions import Fraction
from functools import reduce
from operator import neg

# eqyptianFraction :: Ratio Int -> Ratio Int
def eqyptianFraction(nd):
    '''The rational number nd as a sum
       of the series of unit fractions
       obtained by application of the
       greedy algorithm.'''
    def go(x):
        n, d = x.numerator, x.denominator
        r = 1 + d // n if n else None
        return Just((0, x) if 1 == n else (
            (fr(n % d, d), fr(n // d, 1)) if n > d else (
                fr(-d % n, d * r), fr(1, r)
            )
        )) if n else Nothing()
    fr = Fraction
    f = unfoldr(go)
    return list(map(neg, f(-nd))) if 0 > nd else f(nd)

# TESTS ---------------------------------------------------

# maxEqyptianFraction :: Int -> (Ratio Int -> a)
#                               -> (Ratio Int, a)
def maxEqyptianFraction(nDigits):
    '''An Egyptian Fraction, representing a
       proper fraction with numerators and
       denominators of up to n digits each,
       which returns a maximal value for the
       supplied function f.'''

    # maxVals :: ([Ratio Int], a) -> (Ratio Int, a)
    #                               -> ([Ratio Int], a)
    def maxima(xsv, ndfx):
        xs, v = xsv
        nd, fx = ndfx
        return ([nd], fx) if fx > v else (
            xs + [nd], v
        ) if fx == v and nd not in xs else xsv

    # go :: (Ratio Int -> a) -> ([Ratio Int], a)
    def go(f):
        iLast = int(nDigits * '9')
        fs, mx = reduce(
            maxima, [
                (nd, f(eqyptianFraction(nd))) for nd in [
                    Fraction(n, d)
                    for n in enumFromTo(1)(iLast)
                    for d in enumFromTo(1 + n)(iLast)
                ]
            ],
            ([], 0)
        )
        return f.__name__ + ' -> [' + ', '.join(
            map(str, fs)
        ) + '] -> ' + str(mx)
    return lambda f: go(f)

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

    ef = eqyptianFraction
    fr = Fraction

    print('Three values as Eqyptian fractions:')
    print('\n'.join([
        str(fr(*nd)) + ' -> ' + ' + '.join(map(str, ef(fr(*nd))))
        for nd in [(43, 48), (5, 121), (2014, 59)]
    ]))

    # maxDenominator :: [Ratio Int] -> Int
    def maxDenominator(ef):
        return max(map(lambda nd: nd.denominator, ef))

    # maxTermCount :: [Ratio Int] -> Int
    def maxTermCount(ef):
        return len(ef)

    for i in [1, 2, 3]:
        print(
            '\nMaxima for proper fractions with up to ' + (
                str(i) + ' digit(s):'
            )
        )
        for f in [maxTermCount, maxDenominator]:
            print(maxEqyptianFraction(i)(f))

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

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

# Nothing :: Maybe a
def Nothing():
    '''Constructor for an empty Maybe (option type) value.'''
    return {'type': 'Maybe', 'Nothing': True}

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

# unfoldr :: (b -> Maybe (b, a)) -> b -> [a]
def unfoldr(f):
    '''Dual to reduce or foldr.
       Where catamorphism reduces a list to a summary value,
       the anamorphic unfoldr builds a list from a seed value.
       As long as f returns Just(a, b), a is prepended to the list,
       and the residual b is used as the argument for the next
       application of f.
       When f returns Nothing, the completed list is returned.'''
    def go(xr):
        mb = f(xr[0])
        if mb.get('Nothing'):
            return []
        else:
            y, r = mb.get('Just')
            return [r] + go((y, r))

    return lambda x: go((x, x))

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


Hailstone sequence

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

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

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

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

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

;See also:
*   xkcd (humourous).
*   The Notorious Collatz conjecture Terence Tao, UCLA (Presentation, pdf).
*   The Simplest Math Problem No One Can Solve Veritasium (video, sponsored).

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

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


Hailstone sequence

Solution:
'''Hailstone sequences'''

from itertools import (islice, takewhile)

# hailstone :: Int -> [Int]
def hailstone(x):
    '''Hailstone sequence starting with x.'''
    def p(n):
        return 1 != n
    return list(takewhile(p, iterate(collatz)(x))) + [1]

# collatz :: Int -> Int
def collatz(n):
    '''Next integer in the hailstone sequence.'''
    return 3 * n + 1 if 1 & n else n // 2

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

    n = 27
    xs = hailstone(n)
    print(unlines([
        f'The hailstone sequence for {n} has {len(xs)} elements,',
        f'starting with {take(4)(xs)},',
        f'and ending with {drop(len(xs) - 4)(xs)}.\n'
    ]))

    (a, b) = (1, 99999)
    (i, x) = max(
        enumerate(
            map(compose(len)(hailstone), enumFromTo(a)(b))
        ),
        key=snd
    )
    print(unlines([
        f'The number in the range {a}..{b} '
        f'which produces the longest sequence is {1 + i},',
        f'generating a hailstone sequence of {x} integers.'
    ]))

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

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

# drop :: Int -> [a] -> [a]
# drop :: Int -> String -> String
def drop(n):
    '''The sublist of xs beginning at
       (zero-based) index n.
    '''
    def go(xs):
        if isinstance(xs, (list, tuple, str)):
            return xs[n:]
        else:
            take(n)(xs)
            return xs
    return go

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

# 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

# snd :: (a, b) -> b
def snd(tpl):
    '''Second component of a tuple.'''
    return tpl[1]

# 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.
    '''
    def go(xs):
        return (
            xs[0:n]
            if isinstance(xs, (list, tuple))
            else list(islice(xs, n))
        )
    return go

# unlines :: [String] -> String
def unlines(xs):
    '''A single newline-delimited string derived
       from a list of strings.'''
    return '\n'.join(xs)

if __name__ == '__main__':
    main()


Harmonic series

{{Wikipedia|Harmonic number}}

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

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

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

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

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

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

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

;Related
* [[Egyptian fractions]]

Solution:
from  fractions import Fraction

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

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


Harshad or Niven series

The Harshad or Niven numbers are positive integers >= 1 that are divisible by the sum of their digits.

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

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

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

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

Show your output here.

;Related task
:*   Increasing gaps between consecutive Niven numbers

;See also
*    OEIS: A005349

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

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

1002
>>>


Harshad or Niven series

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

from itertools import count, dropwhile, islice

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

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

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

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

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

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

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

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

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

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

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

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

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

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


Hash join

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

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

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

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

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

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

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

|

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

|}

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

Solution:
from collections import defaultdict

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

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

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


Haversine formula

{{Wikipedia}}

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

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

;Task:
Implement a great-circle distance function, or use a library function,
to show the great-circle distance between:
* Nashville International Airport (BNA)   in Nashville, TN, USA,   which is:
    '''N''' 36deg7.2',   '''W''' 86deg40.2'     (36.12,   -86.67)           -and-
* Los Angeles International Airport (LAX)  in Los Angeles, CA, USA,   which is:
    '''N''' 33deg56.4',  '''W''' 118deg24.0'    (33.94,  -118.40)

User Kaimbridge clarified on the Talk page:

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

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

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

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

Most of the examples below adopted Kaimbridge's recommended value of
6372.8 km for the earth radius.  However, the derivation of this
ellipsoidal quadratic mean radius
is wrong (the averaging over azimuth is biased).  When applying these
examples in real applications, it is better to use the
mean earth radius,
6371 km.  This value is recommended by the International Union of
Geodesy and Geophysics and it minimizes the RMS relative error between the
great circle and geodesic distance.

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

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

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

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

    return R * c

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


Hello world/Line printer

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

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

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

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

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


Here document

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

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

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

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

;Related task:
*   [[Documentation]]

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


Heronian triangles

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

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

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

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

'''Heronian triangles'''
are triangles whose sides ''and area'' are all integers.
: An example is the triangle with sides   '''3, 4, 5'''   whose area is   '''6'''   (and whose perimeter is   '''12''').

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

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

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

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

Show all output here.

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

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

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

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

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

if __name__ == '__main__':
    MAXSIDE = 200

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

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

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


Hex words

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

;Task
Using unixdict.txt, find all hex words with '''4''' letters or more.

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

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

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

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

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

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

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

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


Hickerson series of almost integers

The following function,   due to D. Hickerson,   is said to generate "Almost integers" by the
"Almost Integer" page of Wolfram MathWorld,   (December 31 2013).   (See formula numbered   '''51'''.)

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

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

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

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

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

Solution:
from decimal import Decimal
import math

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

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

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


History variables

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

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

"History Variables:
The Semantics, Formal Correctness, and Implementation of History Variables
in an Imperative Programming Language" by Mallon and Takaoka

Concept also discussed on LtU and Patents.com.

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

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

Solution:
import sys

HIST = {}

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

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

def main():
    a = 10
    a = 20

    for i in range(5):
        c = i

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

sys.settrace(trace)
main()


Hofstadter-Conway $10,000 sequence

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

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

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

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

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

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

The sequence is so named because John Conway offered a prize of $10,000 to the first person who could
find the first position,   p   in the sequence where
    |a(n)/n| < 0.55  for all  n > p
It was later found that Hofstadter had also done prior work on the sequence.

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

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

;Also see:
*   Conways Challenge Sequence, Mallows' own account.
*   Mathworld Article.

Solution:
from __future__ import division

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

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

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

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

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


Hofstadter Figure-Figure sequences

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

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

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

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

;References:
* Sloane's A005228 and A030124.
* Wolfram MathWorld
* Wikipedia: Hofstadter Figure-Figure sequences.

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

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

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


Hofstadter Figure-Figure sequences

Solution:
from itertools import islice

def R():
	n = 1
	yield n
	for s in S():
		n += s
		yield n;

def S():
	yield 2
	yield 4
	u = 5
	for r in R():
		if r <= u: continue;
		for x in range(u, r): yield x
		u = r + 1

def lst(s, n): return list(islice(s(), n))

print "R:", lst(R, 10)
print "S:", lst(S, 10)
print sorted(lst(R, 40) + lst(S, 960)) == list(range(1,1001))

# perf test case
# print sum(lst(R, 10000000))


Hofstadter Q sequence

The Hofstadter Q sequence is defined as:
:: \begin{align}
Q(1)&=Q(2)=1, \\
Q(n)&=Q\big(n-Q(n-1)\big)+Q\big(n-Q(n-2)\big), \quad n>2.
\end{align}

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

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

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

Solution:
from sys import getrecursionlimit

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

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


Horner's rule for polynomial evaluation

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

'''Task Description'''
:Create a routine that takes a list of coefficients of a polynomial in order of increasing powers of x; together with a value of x to compute its value at, and return the value of the polynomial at that value using Horner's rule.

Cf. [[Formal power series]]

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

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

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


ISBN13 check digit

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

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

Show output here, on this page

;See also:
:*   for details:   13-digit ISBN method of validation.       (installs cookies.)

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

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


I before E except after C

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

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

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

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

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

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

;cf.:
* Schools to rethink 'i before e' - BBC news, 20 June 2009
* I Before E Except After C - QI Series 8 Ep 14, (humorous)
* Companion website for the book: "Word Frequencies in Written and Spoken English: based on the British National Corpus".

Solution:
import urllib.request
import re

PLAUSIBILITY_RATIO = 2

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

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

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

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


Identity matrix

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

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

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

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

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

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

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


Identity matrix

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

import operator

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

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

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

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

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

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

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


Idiomatically determine all the characters that can be used for symbols

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

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

;Task requirements

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

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

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

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


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

;Task requirements

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

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

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

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

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

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

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


Imaginary base numbers

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

''The quater-imaginary numeral system was first proposed by Donald Knuth in 1955 as a submission for a high school science talent search.  [Ref.]''

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

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

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

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

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

See Wikipedia: Quater-imaginary_base for more details.

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

Base 10
Base 2i

1
 1

2
 2

3
 3

4
 10300

5
 10301

6
 10302

7
 10303

8
 10200

9
 10201

10
 10202

11
 10203

12
 10100

13
 10101

14
 10102

15
 10103

16
 10000

Base 10
Base 2i

-1
 103

-2
 102

-3
 101

-4
 100

-5
 203

-6
 202

-7
 201

-8
 200

-9
 303

-10
 302

-11
 301

-12
 300

-13
 1030003

-14
 1030002

-15
 1030001

-16
 1030000

Base 10
Base 2i

1i
10.2

2i
10.0

3i
20.2

4i
20.0

5i
30.2

6i
30.0

7i
103000.2

8i
103000.0

9i
103010.2

10i
103010.0

11i
103020.2

12i
103020.0

13i
103030.2

14i
103030.0

15i
102000.2

16i
102000.0

Base 10
Base 2i

-1i
0.2

-2i
1030.0

-3i
1030.2

-4i
1020.0

-5i
1020.2

-6i
1010.0

-7i
1010.2

-8i
1000.0

-9i
1000.2

-10i
2030.0

-11i
2030.2

-12i
2020.0

-13i
2020.2

-14i
2010.0

-15i
2010.2

-16i
2000.0

Solution:
import math
import re

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

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

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

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

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

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

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

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

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

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

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

print "done"


Increasing gaps between consecutive Niven numbers

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

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

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

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

;Related task:
:*   Harshad or Niven series.

;Also see:
:*   Journal of Integer Sequences, Vol. 6 (2004), Article 03.2.5, Large and Small Gaps Between Consecutive Niven Numbers.
:*   (PDF) version of the (above) article by Doyon.

Solution:
"""

Python implementation of

http://rosettacode.org/wiki/Increasing_gaps_between_consecutive_Niven_numbers

"""

# based on C example

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

    return sum

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

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

niven = 1

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


Index finite lists of positive integers

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

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

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

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

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

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

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

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

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


Integer overflow

Some languages support one or more integer types of the underlying processor.

This integer types have fixed size;   usually   '''8'''-bit,   '''16'''-bit,   '''32'''-bit,   or   '''64'''-bit.
The integers supported by such a type can be   ''signed''   or   ''unsigned''.

Arithmetic for machine level integers can often be done by single CPU instructions.
This allows high performance and is the main reason to support machine level integers.

;Definition:
An integer overflow happens when the result of a computation does not fit into the fixed size integer.
The result can be too small or too big to be representable in the fixed size integer.

;Task:
When a language has fixed size integer types, create a program that
does arithmetic computations for the fixed size integers of the language.

These computations must be done such that the result would overflow.

The program should demonstrate what the following expressions do.

For 32-bit signed integers:
::::: {|class="wikitable"
!Expression
!Result that does not fit into a 32-bit signed integer
|-
| -(-2147483647-1)
| 2147483648
|-
| 2000000000 + 2000000000
| 4000000000
|-
| -2147483647 - 2147483647
| -4294967294
|-
| 46341 * 46341
| 2147488281
|-
| (-2147483647-1) / -1
| 2147483648
|}

For 64-bit signed integers:
::: {|class="wikitable"
!Expression
!Result that does not fit into a 64-bit signed integer
|-
| -(-9223372036854775807-1)
| 9223372036854775808
|-
| 5000000000000000000+5000000000000000000
| 10000000000000000000
|-
| -9223372036854775807 - 9223372036854775807
| -18446744073709551614
|-
| 3037000500 * 3037000500
| 9223372037000250000
|-
| (-9223372036854775807-1) / -1
| 9223372036854775808
|}

For 32-bit unsigned integers:
::::: {|class="wikitable"
!Expression
!Result that does not fit into a 32-bit unsigned integer
|-
| -4294967295
| -4294967295
|-
| 3000000000 + 3000000000
| 6000000000
|-
| 2147483647 - 4294967295
| -2147483648
|-
| 65537 * 65537
| 4295098369
|}

For 64-bit unsigned integers:
::: {|class="wikitable"
!Expression
!Result that does not fit into a 64-bit unsigned integer
|-
| -18446744073709551615
| -18446744073709551615
|-
| 10000000000000000000 + 10000000000000000000
| 20000000000000000000
|-
| 9223372036854775807 - 18446744073709551615
| -9223372036854775808
|-
| 4294967296 * 4294967296
| 18446744073709551616
|}

;Notes:
:*   When the integer overflow does trigger an exception show how the exception is caught.
:*   When the integer overflow produces some value,   print it.
:*   It should be explicitly noted when an integer overflow is not recognized,   the program continues with wrong results.
:*   This should be done for signed and unsigned integers of various sizes supported by the computer programming language.
:*   When a language has no fixed size integer type,   or when no integer overflow can occur for other reasons,   this should be noted.
:*   It is okay to mention,   when a language supports unlimited precision integers,   but this task is NOT the place to demonstrate the   capabilities of unlimited precision integers.

Solution:
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 10:38:22) [MSC v.1600 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> for calc in '''   -(-2147483647-1)
   2000000000 + 2000000000
   -2147483647 - 2147483647
   46341 * 46341
   (-2147483647-1) / -1'''.split('\n'):
	ans = eval(calc)
	print('Expression: %r evaluates to %s of type %s'
	      % (calc.strip(), ans, type(ans)))

Expression: '-(-2147483647-1)' evaluates to 2147483648 of type <class 'int'>
Expression: '2000000000 + 2000000000' evaluates to 4000000000 of type <class 'int'>
Expression: '-2147483647 - 2147483647' evaluates to -4294967294 of type <class 'int'>
Expression: '46341 * 46341' evaluates to 2147488281 of type <class 'int'>
Expression: '(-2147483647-1) / -1' evaluates to 2147483648.0 of type <class 'float'>
>>>


Integer sequence

Create a program that, when run, would display all integers from   '''1'''   to    '''    '''    (or any relevant implementation limit),   in sequence   (i.e.   1, 2, 3, 4, etc)   if given enough time.

An example may not be able to reach arbitrarily-large numbers based on implementations limits.   For example, if integers are represented as a 32-bit unsigned value with 0 as the smallest representable value, the largest representable value would be 4,294,967,295.   Some languages support arbitrarily-large numbers as a built-in feature, while others make use of a module or library.

If appropriate, provide an example which reflect the language implementation's common built-in limits as well as an example which supports arbitrarily large numbers, and describe the nature of such limitations--or lack thereof.

Solution:
from itertools import count

for i in count():
    print(i)


Intersecting number wheels

A number wheel has:
* A ''name'' which is an uppercase letter.
* A set of ordered ''values'' which are either ''numbers'' or ''names''.

A ''number'' is generated/yielded from a named wheel by:
:1. Starting at the first value of the named wheel and advancing through subsequent values and wrapping around to the first value to form a "wheel":
::1.a If the value is a number, yield it.
::1.b If the value is a name, yield the next value from the named wheel
::1.c Advance the position of this wheel.

Given the wheel
: A: 1 2 3
the number 1 is first generated, then 2, then 3, 1, 2, 3, 1, ...

'''Note:''' When more than one wheel is defined as a set of intersecting wheels then the
first named wheel is assumed to be the one that values are generated from.

;Examples:
Given the wheels:
    A: 1 B 2
    B: 3 4
The series of numbers generated starts:
    1, 3, 2, 1, 4, 2, 1, 3, 2, 1, 4, 2, 1, 3, 2...

The intersections of number wheels can be more complex, (and might loop forever),
and wheels may be multiply connected.

'''Note:''' If a named wheel is referenced more than
once by one or many other wheels, then there is only one position of the wheel
that is advanced by each and all references to it.

E.g.
  A:  1 D D
  D:  6 7 8
  Generates:
    1 6 7 1 8 6 1 7 8 1 6 7 1 8 6 1 7 8 1 6 ...

;Task:
Generate and show the first twenty terms of the sequence of numbers generated
from these groups:

    Intersecting Number Wheel group:
      A:  1 2 3

    Intersecting Number Wheel group:
      A:  1 B 2
      B:  3 4

    Intersecting Number Wheel group:
      A:  1 D D
      D:  6 7 8

    Intersecting Number Wheel group:
      A:  1 B C
      B:  3 4
      C:  5 B

Show your output here, on this page.

Solution:
from itertools import islice

class INW():
    """
    Intersecting Number Wheels
    represented as a dict mapping
    name to tuple of values.
    """

    def __init__(self, **wheels):
        self._wheels = wheels
        self.isect = {name: self._wstate(name, wheel)
                      for name, wheel in wheels.items()}

    def _wstate(self, name, wheel):
        "Wheel state holder"
        assert all(val in self._wheels for val in wheel if type(val) == str), \
               f"ERROR: Interconnected wheel not found in {name}: {wheel}"
        pos = 0
        ln = len(wheel)
        while True:
            nxt, pos = wheel[pos % ln], pos + 1
            yield next(self.isect[nxt]) if type(nxt) == str else nxt

    def __iter__(self):
        base_wheel_name = next(self.isect.__iter__())
        yield from self.isect[base_wheel_name]

    def __repr__(self):
        return f"{self.__class__.__name__}({self._wheels})"

    def __str__(self):
        txt = "Intersecting Number Wheel group:"
        for name, wheel in self._wheels.items():
            txt += f"\n  {name+':':4}" + ' '.join(str(v) for v in wheel)
        return txt

def first(iter, n):
    "Pretty print first few terms"
    return ' '.join(f"{nxt}" for nxt in islice(iter, n))

if __name__ == '__main__':
    for group in[
      {'A': (1, 2, 3)},
      {'A': (1, 'B', 2),
       'B': (3, 4)},
      {'A': (1, 'D', 'D'),
       'D': (6, 7, 8)},
      {'A': (1, 'B', 'C'),
       'B': (3, 4),
       'C': (5, 'B')}, # 135143145...
     ]:
        w = INW(**group)
        print(f"{w}\n  Generates:\n    {first(w, 20)} ...\n")


Intersecting number wheels

Solution:
'''Intersecting number wheels'''

from itertools import cycle, islice
from functools import reduce

# clockWorkTick :: Dict -> (Dict, Char)
def clockWorkTick(wheelMap):
    '''The new state of the wheels, tupled with a
       digit found by recursive descent from a single
       click of the first wheel.'''
    def click(wheels):
        def go(wheelName):
            wheel = wheels.get(wheelName, ['?'])
            v = wheel[0]
            return (Tuple if v.isdigit() or '?' == v else click)(
                insertDict(wheelName)(leftRotate(wheel))(wheels)
            )(v)
        return go
    return click(wheelMap)('A')

# leftRotate :: [a] -> String
def leftRotate(xs):
    ''' A string shifted cyclically towards
        the left by one position.
    '''
    return ''.join(islice(cycle(xs), 1, 1 + len(xs)))

# ------------------------- TEST -------------------------
# main :: IO ()
def main():
    '''First twenty values from each set of test wheels.'''

    wheelMaps = [dict(kvs) for kvs in [
        [('A', "123")],
        [('A', "1B2"), ('B', "34")],
        [('A', "1DD"), ('D', "678")],
        [('A', "1BC"), ('B', "34"), ('C', "5B")]
    ]]
    print('New state of wheel sets, after 20 clicks of each:\n')
    for wheels, series in [
            mapAccumL(compose(const)(clockWorkTick))(
                dct
            )(' ' * 20) for dct in wheelMaps
    ]:
        print((wheels, ''.join(series)))

    print('\nInital states:')
    for x in wheelMaps:
        print(x)

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

# Tuple (,) :: a -> b -> (a, b)
def Tuple(x):
    '''Constructor for a pair of values,
       possibly of two different types.
    '''
    return lambda y: (
        x + (y,)
    ) if isinstance(x, tuple) else (x, y)

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

# const :: a -> b -> a
def const(k):
    '''The latter of two arguments,
       with the first discarded.
    '''
    return lambda _: k

# insertDict :: String -> a -> Dict -> Dict
def insertDict(k):
    '''A new dictionary updated with a (k, v) pair.'''
    def go(v, dct):
        return dict(dct, **{k: v})
    return lambda v: lambda dct: go(v, dct)

# mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
def mapAccumL(f):
    '''A tuple of an accumulation and a map
       with accumulation from left to right.
    '''
    def nxt(a, x):
        tpl = f(a[0])(x)
        return tpl[0], a[1] + [tpl[1]]

    def go(acc):
        def g(xs):
            return reduce(nxt, xs, (acc, []))
        return g
    return go

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


Isqrt (integer square root) of X

Sometimes a function is needed to find the integer square root of   '''X''',   where   '''X'''   can be a
real non-negative number.

Often   '''X'''   is actually a non-negative integer.

For the purposes of this task,   '''X'''   can be an integer or a real number,   but if it
simplifies things in your computer programming language,   assume it's an integer.

One of the most common uses of   '''Isqrt'''   is in the division of an integer by all factors   (or
primes)   up to the
 X     of that
integer,   either to find the factors of that integer,   or to determine primality.

An alternative method for finding the   '''Isqrt'''   of a number is to
calculate:        floor( sqrt(X) )
::*   where    '''sqrt'''    is the   square root   function for non-negative real numbers,   and
::*   where   '''floor'''         is the   floor         function for real numbers.

If the hardware supports the computation of (real) square roots,   the above method might be a faster method for
small numbers that don't have very many significant (decimal) digits.

However, floating point arithmetic is limited in the number of   (binary or decimal)   digits that it can support.

;Pseudo-code using quadratic residue:
For this task, the integer square root of a non-negative number will be computed using a version
of   ''quadratic residue'',   which has the advantage that no   ''floating point''   calculations are
used,   only integer arithmetic.

Furthermore, the two divisions can be performed by bit shifting,   and the one multiplication can also be be performed by bit shifting or additions.

The disadvantage is the limitation of the size of the largest integer that a particular computer programming language can support.

Pseudo-code of a procedure for finding the integer square root of   '''X'''       (all variables are integers):
          q <-- 1                                /*initialize  Q  to unity.  */
                                   /*find a power of 4 that's greater than X.*/
                   perform  while q <= x         /*perform while  Q <= X.    */
                   q <-- q * 4                   /*multiply  Q  by  four.    */
                   end  /*perform*/
                                                 /*Q  is now greater than  X.*/
          z <-- x                                /*set  Z  to the value of X.*/
          r <-- 0                                /*initialize  R  to zero.   */
                   perform  while q > 1          /*perform while  Q > unity. */
                   q <-- q / 4                   /*integer divide by  four.  */
                   t <-- z - r - q               /*compute value of  T.      */
                   r <-- r / 2                   /*integer divide by  two.   */
                   if t >= 0  then do
                                   z <-- t       /*set  Z  to value of  T.   */
                                   r <-- r + q   /*compute new value of  R.  */
                                   end
                   end  /*perform*/
                                                 /*R  is now the  Isqrt(X).  */

          /* Sidenote: Also, Z is now the remainder after square root (i.e.  */
          /*           R^2 + Z = X, so if Z = 0 then X is a perfect square). */

Another version for the (above)   1st   '''perform'''   is:
                   perform  until q > X          /*perform until  Q > X.     */
                   q <-- q * 4                   /*multiply  Q  by  four.    */
                   end  /*perform*/

Integer square roots of some values:
 Isqrt( 0)  is   0               Isqrt(60)  is  7                Isqrt( 99)  is   9
 Isqrt( 1)  is   1               Isqrt(61)  is  7                Isqrt(100)  is  10
 Isqrt( 2)  is   1               Isqrt(62)  is  7                Isqrt(102)  is  10
 Isqrt( 3)  is   1               Isqrt(63)  is  7
 Isqrt( 4)  is   2               Isqrt(64)  is  8                Isqet(120)  is  10
 Isqrt( 5)  is   2               Isqrt(65)  is  8                Isqrt(121)  is  11
 Isqrt( 6)  is   2               Isqrt(66)  is  8                Isqrt(122)  is  11
 Isqrt( 7)  is   2               Isqrt(67)  is  8
 Isqrt( 8)  is   2               Isqrt(68)  is  8                Isqrt(143)  is  11
 Isqrt( 9)  is   3               Isqrt(69)  is  8                Isqrt(144)  is  12
 Isqrt(10)  is   3               Isqrt(70)  is  8                Isqrt(145)  is  12

;Task:
Compute and show all output here   (on this page)   for:
::*   the Isqrt of the     integers     from     '''0''' ---> '''65'''                (inclusive), shown in a       horizontal       format.
::*   the Isqrt of the   odd powers               from          '''71''' ---> '''773'''   (inclusive), shown in a   vertical   format.
::*   use commas in the displaying of larger numbers.

You can show more numbers for the 2nd requirement if the displays fits on one screen on Rosetta Code.
If your computer programming language only supports smaller integers,   show what you can.

;Related tasks:
:*   sequence of non-squares
:*   integer roots
:*   square root by hand

Solution:
def isqrt ( x ):
    q = 1
    while q <= x :
        q *= 4
    z,r = x,0
    while q > 1 :
        q  /= 4
        t,r = z-r-q,r/2
        if t >= 0 :
            z,r = t,r+q
    return r

print ' '.join( '%d'%isqrt( n ) for n in xrange( 66 ))
print '\n'.join( '{0:114,} = isqrt( 7^{1:3} )'.format( isqrt( 7**n ),n ) for n in range( 1,204,2 ))


Iterated digits squaring

If you add the square of the digits of a Natural number (an integer bigger than zero), you always end with either 1 or 89:
15 -> 26 -> 40 -> 16 -> 37 -> 58 -> 89
7 -> 49 -> 97 -> 130 -> 10 -> 1

An example in Python:

>>> step = lambda x: sum(int(d) ** 2 for d in str(x))
>>> iterate = lambda x: x if x in [1, 89] else iterate(step(x))
>>> [iterate(x) for x in xrange(1, 20)]
[1, 89, 89, 89, 89, 89, 1, 89, 89, 1, 89, 89, 1, 89, 89, 89, 89, 89, 1]

;Task:
: Count how many number chains for integers 1 <= n < 100_000_000 end with a value 89.
Or, for much less credit - (showing that your algorithm and/or language is slow):
: Count how many number chains for integers 1 <= n < 1_000_000 end with a value 89.

This problem derives from the Project Euler problem 92.

For a quick algorithm for this task see the talk page

;Related tasks:
* [[Combinations with repetitions]]
* [[Digital root]]
* [[Digital root/Multiplicative digital root]]

Solution:
from math import ceil, log10, factorial

def next_step(x):
    result = 0
    while x > 0:
        result += (x % 10) ** 2
        x /= 10
    return result

def check(number):
    candidate = 0
    for n in number:
        candidate = candidate * 10 + n

    while candidate != 89 and candidate != 1:
        candidate = next_step(candidate)

    if candidate == 89:
        digits_count = [0] * 10
        for d in number:
            digits_count[d] += 1

        result = factorial(len(number))
        for c in digits_count:
            result /= factorial(c)
        return result

    return 0

def main():
    limit = 100000000
    cache_size = int(ceil(log10(limit)))
    assert 10 ** cache_size == limit

    number = [0] * cache_size
    result = 0
    i = cache_size - 1

    while True:
        if i == 0 and number[i] == 9:
            break
        if i == cache_size - 1 and number[i] < 9:
            number[i] += 1
            result += check(number)
        elif number[i] == 9:
            i -= 1
        else:
            number[i] += 1
            for j in xrange(i + 1, cache_size):
                number[j] = number[i]
            i = cache_size - 1
            result += check(number)

    print result

main()


Iterated digits squaring

Solution:
from itertools import combinations_with_replacement
from array import array
from time import clock
D = 8
F = [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000]
def b(n):
    yield 1
    for g in range(1,n+1):
        gn = g
        res = 0
        while gn > 0:
            gn,rem = divmod(gn,10)
            res += rem**2
        if res==89:
            yield 0
        else:
            yield res
N = array('I',b(81*D))
for n in range(2,len(N)):
    q = N[n]
    while q>1:
        q = N[q]
    N[n] = q

es = clock()
z = 0
for n in combinations_with_replacement(range(10),D):
    t = 0
    for g in n:
        t += g*g
    if N[t] == 0:
        continue
    t = [0,0,0,0,0,0,0,0,0,0]
    for g in n:
        t[g] += 1
    t1 = F[D]
    for g in t:
        t1 /= F[g]
    z += t1
ee = clock() - es
print "\nD==" + str(D) + "\n  " + str(z) + " numbers produce 1 and " + str(10**D-z) + " numbers produce 89"
print "Time ~= " + str(ee) + " secs"


JSON

Load a JSON string into a data structure.
Also, create a new data structure and serialize it into JSON.

Use objects and arrays (as appropriate for your language)
and make sure your JSON is valid (https://jsonformatter.org).

Solution:
>>> import json
>>> data = json.loads('{ "foo": 1, "bar": [10, "apples"] }')
>>> sample = { "blue": [1,2], "ocean": "water" }
>>> json_string = json.dumps(sample)
>>> json_string
'{"blue": [1, 2], "ocean": "water"}'
>>> sample
{'blue': [1, 2], 'ocean': 'water'}
>>> data
{'foo': 1, 'bar': [10, 'apples']}


Jacobi symbol

The '''Jacobi symbol''' is a multiplicative function that generalizes the Legendre symbol. Specifically, the Jacobi symbol (a | n) equals the product of the Legendre symbols (a | p_i)^(k_i), where n = p_1^(k_1)*p_2^(k_2)*...*p_i^(k_i) and 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

If n is prime, then the Jacobi symbol (a | n) equals the Legendre symbol (a | n).

;Task:
Calculate the Jacobi symbol (a | n).

;Reference:
* Wikipedia article on Jacobi symbol.

Solution:
def jacobi(a, n):
    if n <= 0:
        raise ValueError("'n' must be a positive integer.")
    if n % 2 == 0:
        raise ValueError("'n' must be odd.")
    a %= n
    result = 1
    while a != 0:
        while a % 2 == 0:
            a /= 2
            n_mod_8 = n % 8
            if n_mod_8 in (3, 5):
                result = -result
        a, n = n, a
        if a % 4 == 3 and n % 4 == 3:
            result = -result
        a %= n
    if n == 1:
        return result
    else:
        return 0


Jacobsthal numbers

'''Jacobsthal numbers''' are an integer sequence related to Fibonacci numbers. Similar to Fibonacci, where each term is the sum of the previous two terms, each term is the sum of the previous, plus twice the one before that. Traditionally the sequence starts with the given terms 0, 1.

    J0 = 0
    J1 = 1
    Jn = Jn-1 + 2 x Jn-2

Terms may be calculated directly using one of several possible formulas:

    Jn = ( 2n - (-1)n ) / 3

'''Jacobsthal-Lucas numbers''' are very similar. They have the same recurrence relationship, the only difference is an initial starting value '''J0 = 2''' rather than '''J0 = 0'''.

Terms may be calculated directly using one of several possible formulas:

    JLn = 2n + (-1)n

'''Jacobsthal oblong numbers''' is the sequence obtained from multiplying each '''Jacobsthal number''' '''Jn''' by its direct successor '''Jn+1'''.

'''Jacobsthal primes''' are '''Jacobsthal numbers''' that are prime.

;Task
* Find and display the first 30 '''Jacobsthal numbers'''
* Find and display the first 30 '''Jacobsthal-Lucas numbers'''
* Find and display the first 20 '''Jacobsthal oblong numbers'''
* Find and display at least the first 10 '''Jacobsthal primes'''

;See also
;* Wikipedia: Jacobsthal number
;* Numbers Aplenty - Jacobsthal number
;* OEIS:A001045 - Jacobsthal sequence (or Jacobsthal numbers)
;* OEIS:A014551 - Jacobsthal-Lucas numbers.
;* OEIS:A084175 - Jacobsthal oblong numbers
;* OEIS:A049883 - Primes in the Jacobsthal sequence
;* Related task: Fibonacci sequence
;* Related task: Leonardo numbers

Solution:
#!/usr/bin/python
from math import floor, pow

def isPrime(n):
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

def odd(n):
    return n and 1 != 0

def jacobsthal(n):
    return floor((pow(2,n)+odd(n))/3)

def jacobsthal_lucas(n):
    return int(pow(2,n)+pow(-1,n))

def jacobsthal_oblong(n):
    return jacobsthal(n)*jacobsthal(n+1)

if __name__ == '__main__':
    print("First 30 Jacobsthal numbers:")
    for j in range(0, 30):
        print(jacobsthal(j), end="  ")

    print("\n\nFirst 30 Jacobsthal-Lucas numbers: ")
    for j in range(0, 30):
        print(jacobsthal_lucas(j), end = '\t')

    print("\n\nFirst 20 Jacobsthal oblong numbers: ")
    for j in range(0, 20):
        print(jacobsthal_oblong(j), end="  ")

    print("\n\nFirst 10 Jacobsthal primes: ")
    for j in range(3, 33):
        if isPrime(jacobsthal(j)):
            print(jacobsthal(j))


Jaro similarity

The Jaro distance is a measure of edit distance between two strings; its inverse, called the ''Jaro similarity'', is a measure of two strings' similarity: the higher the value, the more similar the strings are. The score is normalized such that   '''0'''   equates to no similarities and   '''1'''   is an exact match.

;;Definition

The Jaro similarity   d_j   of two given strings   s_1   and   s_2   is

: d_j = \left\{

\begin{array}{l l}
  0 & \text{if }m = 0\\
  \frac{1}{3}\left(\frac{m}{|s_1|} + \frac{m}{|s_2|} + \frac{m-t}{m}\right) & \text{otherwise} \end{array} \right.

Where:

* m   is the number of ''matching characters'';
* t   is half the number of ''transpositions''.

Two characters from   s_1   and   s_2   respectively, are considered ''matching'' only if they are the same and not farther apart than   \left\lfloor\frac{\max(|s_1|,|s_2|)}{2}\right\rfloor-1 characters.

Each character of   s_1   is compared with all its matching characters in   s_2. Each difference in position is half a ''transposition''; that is, the number of transpositions is half the number of characters which are common to the two strings but occupy different positions in each one.

;;Example

Given the strings   s_1   ''DWAYNE''   and   s_2   ''DUANE''   we find:

* m = 4
* |s_1| = 6
* |s_2| = 5
* t = 0

We find a Jaro score of:

: d_j = \frac{1}{3}\left(\frac{4}{6} + \frac{4}{5} + \frac{4-0}{4}\right) = 0.822

;Task

Implement the Jaro algorithm and show the similarity scores for each of the following pairs:

* ("MARTHA", "MARHTA")
* ("DIXON", "DICKSONX")
* ("JELLYFISH", "SMELLYFISH")

; See also
* Jaro-Winkler distance on Wikipedia.

Solution:
'''Jaro distance between two strings'''

from functools import reduce
import itertools

# --------------------- JARO FUNCTION ----------------------

# jaro :: String -> String -> Float
def jaro(x):
    '''The Jaro distance between two strings.'''
    def go(s1, s2):
        m, t = ap(compose(Tuple, len))(
            transpositionSum
        )(matches(s1, s2))
        return 0 if 0 == m else (
            (1 / 3) * ((m / len(s1)) + (
                m / len(s2)
            ) + ((m - t) / m))
        )
    return lambda y: go(x, y)

# -------------------------- TEST --------------------------
# main :: IO ()
def main():
    '''Sample word pairs'''

    print(
        fTable('Jaro distances:\n')(str)(
            showPrecision(3)
        )(
            uncurry(jaro)
        )([
            ("DWAYNE", "DUANE"),
            ("MARTHA", "MARHTA"),
            ("DIXON", "DICKSONX"),
            ("JELLYFISH", "SMELLYFISH")
        ])
    )

# ----------------- JARO HELPER FUNCTIONS ------------------

# transpositionSum :: [(Int, Char)] -> Int
def transpositionSum(xs):
    '''A count of the transpositions in xs.'''
    def f(a, xy):
        x, y = xy
        return 1 + a if fst(x) > fst(y) else a
    return reduce(f, zip(xs, xs[1:]), 0)

# matches :: String -> String -> [(Int, Char)]
def matches(s1, s2):
    '''A list of (Index, Char) correspondences
       between the two strings s1 and s2.'''

    [(_, xs), (l2, ys)] = sorted(map(
        ap(compose(Tuple, len))(list), [s1, s2]
    ))
    r = l2 // 2 - 1

    # match :: (Int, (Char, Int)) -> (Int, Char)
    def match(a, nc):
        n, c = nc
        offset = max(0, n - (1 + r))

        def indexChar(x):
            return a + [(offset + x, c)]

        return maybe(a)(indexChar)(
            elemIndex(c)(
                drop(offset)(take(n + r)(ys))
            )
        )
    return reduce(match, enumerate(xs), [])

# ------------------- GENERIC FUNCTIONS --------------------

# 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}

# Tuple (,) :: a -> b -> (a, b)
def Tuple(x):
    '''Constructor for a pair of values,
       possibly of two different types.
    '''
    def go(y):
        return (
            x + (y,)
        ) if isinstance(x, tuple) else (x, y)
    return go

# ap :: (a -> b -> c) -> (a -> b) -> a -> c
def ap(f):
    '''Applicative instance for functions.
    '''
    def go(g):
        def fxgx(x):
            return f(x)(
                g(x)
            )
        return fxgx
    return go

# compose :: ((a -> a), ...) -> (a -> a)
def compose(*fs):
    '''Composition, from right to left,
       of a series of functions.
    '''
    def go(f, g):
        def fg(x):
            return f(g(x))
        return fg
    return reduce(go, fs, lambda x: x)

# drop :: Int -> [a] -> [a]
# drop :: Int -> String -> String
def drop(n):
    '''The sublist of xs beginning at
       (zero-based) index n.
    '''
    def go(xs):
        if isinstance(xs, (list, tuple, str)):
            return xs[n:]
        else:
            take(n)(xs)
            return xs
    return go

# 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

# fst :: (a, b) -> a
def fst(tpl):
    '''First member of a pair.'''
    return tpl[0]

# 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'))

# showPrecision Int -> Float -> String
def showPrecision(n):
    '''A string showing a floating point number
       at a given degree of precision.'''
    return lambda x: str(round(x, n))

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

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

# 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.
    '''
    islice = itertools.islice

    def go(xs):
        return (
            xs[0:n]
            if isinstance(xs, (list, tuple))
            else list(islice(xs, n))
        )
    return go

# uncurry :: (a -> b -> c) -> ((a, b) -> c)
def uncurry(f):
    '''A function over a tuple derived from a curried function.'''
    return lambda xy: f(xy[0])(
        xy[1]
    )

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


Jewels and stones

Create a function which takes two string parameters: 'stones' and 'jewels' and returns an integer.

Both strings can contain any number of upper or lower case letters. However, in the case of 'jewels', all letters must be distinct.

The function should count (and return) how many 'stones' are 'jewels' or, in other words, how many letters in 'stones' are also letters in 'jewels'.

Note that:
:# Only letters in the ISO basic Latin alphabet i.e. 'A to Z' or 'a to z' need be considered.
:# A lower case letter is considered to be different from its upper case equivalent for this purpose, i.e., 'a' != 'A'.
:# The parameters do not need to have exactly the same names.
:# Validating the arguments is unnecessary.

So, for example, if passed "aAAbbbb" for 'stones' and "aA" for 'jewels', the function should return 3.

This task was inspired by this problem.

Solution:
def countJewels(s, j):
    return sum(x in j for x in s)

print countJewels("aAAbbbb", "aA")
print countJewels("ZZ", "z")


Juggler sequence

Background of the   '''juggler sequence''':

Juggler sequences were publicized by an American mathematician and author   Clifford A. Pickover.   The name of the sequence gets it's name from the similarity of the rising and falling nature of the numbers in the sequences,   much like balls in the hands of a juggler.

;Description
A juggler sequence is an integer sequence that starts with a positive integer a[0], with each subsequent term in the sequence being defined by the recurrence relation:

             a[k + 1]  =  floor(a[k] ^ 0.5)    if a[k] is even   ''' ''or'' '''
    a[k + 1]  =  floor(a[k] ^ 1.5)    if a[k] is odd

If a juggler sequence reaches 1, then all subsequent terms are equal to 1. This is known to be the case for initial terms up to 1,000,000 but it is not known whether all juggler sequences after that will eventually reach 1.

;Task:
Compute and show here the following statistics for juggler sequences with an initial term of a[n] where n is between '''20''' and '''39''' inclusive:

* l[n] - the number of terms needed to reach 1.
* h[n] - the maximum value reached in that sequence.
* i[n] - the index of the term (starting from 0) at which the maximum is (first) reached.

If your language supports ''big integers'' with an integer square root function, also compute and show here the same statistics for as many as you reasonably can of the following values for n:

113, 173, 193, 2183, 11229, 15065, 15845, 30817, 48443, 275485, 1267909, 2264915, 5812827

Those with fast languages and fast machines may also like to try their luck at n = 7110201.

However, as h[n] for most of these numbers is thousands or millions of digits long, show instead of h[n]:

* d[n] - the number of digits in h[n]

The results can be (partially) verified against the table here.

;Related tasks:
*   [[Hailstone sequence]]
*   [[Yellowstone sequence]]
*   [[Isqrt_(integer_square_root)_of_X]]

;See also:
* [[oeis:A007320]] Number of steps needed for Juggler sequence started at n to reach 1
* [[oeis:A094716]] Largest value in the Juggler sequence started at n

Solution:
from math import isqrt

def juggler(k, countdig=True, maxiters=1000):
    m, maxj, maxjpos = k, k, 0
    for i in range(1, maxiters):
        m = isqrt(m) if m % 2 == 0 else isqrt(m * m * m)
        if m >= maxj:
            maxj, maxjpos  = m, i
        if m == 1:
            print(f"{k: 9}{i: 6,}{maxjpos: 6}{len(str(maxj)) if countdig else maxj: 20,}{' digits' if countdig else ''}")
            return i

    print("ERROR: Juggler series starting with $k did not converge in $maxiters iterations")

print("       n    l(n)  i(n)       h(n) or d(n)\n-------------------------------------------")
for k in range(20, 40):
    juggler(k, False)

for k in [113, 173, 193, 2183, 11229, 15065, 15845, 30817, 48443, 275485, 1267909]:
    juggler(k)


Julia set

Task
Generate and draw a Julia set.

;Related tasks
*   Mandelbrot Set

Solution:
"""
Solution from:
https://codereview.stackexchange.com/questions/210271/generating-julia-set
"""
from functools import partial
from numbers import Complex
from typing import Callable

import matplotlib.pyplot as plt
import numpy as np

def douady_hubbard_polynomial(z: Complex,
                              c: Complex) -> Complex:
    """
    Monic and centered quadratic complex polynomial
    https://en.wikipedia.org/wiki/Complex_quadratic_polynomial#Map
    """
    return z ** 2 + c

def julia_set(mapping: Callable[[Complex], Complex],
              *,
              min_coordinate: Complex,
              max_coordinate: Complex,
              width: int,
              height: int,
              iterations_count: int = 256,
              threshold: float = 2.) -> np.ndarray:
    """
    As described in https://en.wikipedia.org/wiki/Julia_set
    :param mapping: function defining Julia set
    :param min_coordinate: bottom-left complex plane coordinate
    :param max_coordinate: upper-right complex plane coordinate
    :param height: pixels in vertical axis
    :param width: pixels in horizontal axis
    :param iterations_count: number of iterations
    :param threshold: if the magnitude of z becomes greater
    than the threshold we assume that it will diverge to infinity
    :return: 2D pixels array of intensities
    """
    im, re = np.ogrid[min_coordinate.imag: max_coordinate.imag: height * 1j,
                      min_coordinate.real: max_coordinate.real: width * 1j]
    z = (re + 1j * im).flatten()

    live, = np.indices(z.shape)  # indexes of pixels that have not escaped
    iterations = np.empty_like(z, dtype=int)

    for i in range(iterations_count):
        z_live = z[live] = mapping(z[live])
        escaped = abs(z_live) > threshold
        iterations[live[escaped]] = i
        live = live[~escaped]
        if live.size == 0:
            break
    else:
        iterations[live] = iterations_count

    return iterations.reshape((height, width))

if __name__ == '__main__':
    mapping = partial(douady_hubbard_polynomial,
                      c=-0.7 + 0.27015j)  # type: Callable[[Complex], Complex]

    image = julia_set(mapping,
                      min_coordinate=-1.5 - 1j,
                      max_coordinate=1.5 + 1j,
                      width=800,
                      height=600)
    plt.axis('off')
    plt.imshow(image,
               cmap='nipy_spectral_r',
               origin='lower')
    plt.show()


Jump anywhere

Imperative programs like to jump around, but some languages restrict these jumps. Many structured languages restrict their [[conditional structures]] and [[loops]] to ''local jumps'' within a function. Some assembly languages limit certain jumps or branches to a small range.

This task is to demonstrate a local jump and a global jump and the various other types of jumps that the language supports.
For the purpose of this task, the jumps need not be used for a single purpose and you have the freedom to use these jumps for different purposes.
You may also defer to more specific tasks, like [[Exceptions]] or [[Generator]].
This task provides a "grab bag" for several types of jumps. There are ''non-local jumps'' across function calls, or ''long jumps'' to anywhere within a program. Anywhere means not only to the tops of functions!

* Some languages can ''go to'' any global label in a program.
* Some languages can break multiple function calls, also known as ''unwinding the call stack''.
* Some languages can save a ''continuation''. The program can later continue from the same place. So you can jump anywhere, but only if you have a previous visit there (to save the continuation).

These jumps are not all alike.
A simple ''goto'' never touches the call stack.
A continuation saves the call stack, so you can continue a function call after it ends.

;Task:
Use your language to demonstrate the various types of jumps that it supports.

Because the possibilities vary by language, this task is not specific.
You have the freedom to use these jumps for different purposes.
You may also defer to more specific tasks, like [[Exceptions]] or [[Generator]].

Solution:
# Example 2: Restarting a loop:
from goto import goto, label
label .start
for i in range(1, 4):
    print i
    if i == 2:
        try:
            output = message
        except NameError:
            print "Oops - forgot to define 'message'!  Start again."
            message = "Hello world"
            goto .start
print output, "\n"