Poker hand analyser

Solution:
from collections import namedtuple

class Card(namedtuple('Card', 'face, suit')):
    def __repr__(self):
        return ''.join(self)

suit = '♥ ♦ ♣ ♠'.split()
# ordered strings of faces
faces   = '2 3 4 5 6 7 8 9 10 j q k a'
lowaces = 'a 2 3 4 5 6 7 8 9 10 j q k'
# faces as lists
face   = faces.split()
lowace = lowaces.split()

def straightflush(hand):
    f,fs = ( (lowace, lowaces) if any(card.face == '2' for card in hand)
             else (face, faces) )
    ordered = sorted(hand, key=lambda card: (f.index(card.face), card.suit))
    first, rest = ordered[0], ordered[1:]
    if ( all(card.suit == first.suit for card in rest) and
         ' '.join(card.face for card in ordered) in fs ):
        return 'straight-flush', ordered[-1].face
    return False

def fourofakind(hand):
    allfaces = [f for f,s in hand]
    allftypes = set(allfaces)
    if len(allftypes) != 2:
        return False
    for f in allftypes:
        if allfaces.count(f) == 4:
            allftypes.remove(f)
            return 'four-of-a-kind', [f, allftypes.pop()]
    else:
        return False

def fullhouse(hand):
    allfaces = [f for f,s in hand]
    allftypes = set(allfaces)
    if len(allftypes) != 2:
        return False
    for f in allftypes:
        if allfaces.count(f) == 3:
            allftypes.remove(f)
            return 'full-house', [f, allftypes.pop()]
    else:
        return False

def flush(hand):
    allstypes = {s for f, s in hand}
    if len(allstypes) == 1:
        allfaces = [f for f,s in hand]
        return 'flush', sorted(allfaces,
                               key=lambda f: face.index(f),
                               reverse=True)
    return False

def straight(hand):
    f,fs = ( (lowace, lowaces) if any(card.face == '2' for card in hand)
             else (face, faces) )
    ordered = sorted(hand, key=lambda card: (f.index(card.face), card.suit))
    first, rest = ordered[0], ordered[1:]
    if ' '.join(card.face for card in ordered) in fs:
        return 'straight', ordered[-1].face
    return False

def threeofakind(hand):
    allfaces = [f for f,s in hand]
    allftypes = set(allfaces)
    if len(allftypes) <= 2:
        return False
    for f in allftypes:
        if allfaces.count(f) == 3:
            allftypes.remove(f)
            return ('three-of-a-kind', [f] +
                     sorted(allftypes,
                            key=lambda f: face.index(f),
                            reverse=True))
    else:
        return False

def twopair(hand):
    allfaces = [f for f,s in hand]
    allftypes = set(allfaces)
    pairs = [f for f in allftypes if allfaces.count(f) == 2]
    if len(pairs) != 2:
        return False
    p0, p1 = pairs
    other = [(allftypes - set(pairs)).pop()]
    return 'two-pair', pairs + other if face.index(p0) > face.index(p1) else pairs[::-1] + other

def onepair(hand):
    allfaces = [f for f,s in hand]
    allftypes = set(allfaces)
    pairs = [f for f in allftypes if allfaces.count(f) == 2]
    if len(pairs) != 1:
        return False
    allftypes.remove(pairs[0])
    return 'one-pair', pairs + sorted(allftypes,
                                      key=lambda f: face.index(f),
                                      reverse=True)

def highcard(hand):
    allfaces = [f for f,s in hand]
    return 'high-card', sorted(allfaces,
                               key=lambda f: face.index(f),
                               reverse=True)

handrankorder =  (straightflush, fourofakind, fullhouse,
                  flush, straight, threeofakind,
                  twopair, onepair, highcard)

def rank(cards):
    hand = handy(cards)
    for ranker in handrankorder:
        rank = ranker(hand)
        if rank:
            break
    assert rank, "Invalid: Failed to rank cards: %r" % cards
    return rank

def handy(cards='2♥ 2♦ 2♣ k♣ q♦'):
    hand = []
    for card in cards.split():
        f, s = card[:-1], card[-1]
        assert f in face, "Invalid: Don't understand card face %r" % f
        assert s in suit, "Invalid: Don't understand card suit %r" % s
        hand.append(Card(f, s))
    assert len(hand) == 5, "Invalid: Must be 5 cards in a hand, not %i" % len(hand)
    assert len(set(hand)) == 5, "Invalid: All cards in the hand must be unique %r" % cards
    return hand

if __name__ == '__main__':
    hands = ["2♥ 2♦ 2♣ k♣ q♦",
     "2♥ 5♥ 7♦ 8♣ 9♠",
     "a♥ 2♦ 3♣ 4♣ 5♦",
     "2♥ 3♥ 2♦ 3♣ 3♦",
     "2♥ 7♥ 2♦ 3♣ 3♦",
     "2♥ 7♥ 7♦ 7♣ 7♠",
     "10♥ j♥ q♥ k♥ a♥"] + [
     "4♥ 4♠ k♠ 5♦ 10♠",
     "q♣ 10♣ 7♣ 6♣ 4♣",
     ]
    print("%-18s %-15s %s" % ("HAND", "CATEGORY", "TIE-BREAKER"))
    for cards in hands:
        r = rank(cards)
        print("%-18r %-15s %r" % (cards, r[0], r[1]))


Polyspiral

A [http://www.otherwise.com/Jurtle/screenshots_win/assets/DisplayWindow_Full.png Polyspiral] is a spiral made of multiple line segments, whereby each segment is larger (or smaller) than the previous one by a given amount. Each segment also changes direction at a given angle.

;Task
Animate a series of polyspirals, by drawing a complete spiral then incrementing the angle, and (after clearing the background) drawing the next, and so on. Every spiral will be a frame of the animation. The animation may stop as it goes full circle or continue indefinitely. The given input values may be varied.

If animation is not practical in your programming environment, you may show a single frame instead.

;Pseudo code

    set incr to 0.0

    // animation loop
    WHILE true

        incr = (incr + 0.05) MOD 360
        x = width / 2
        y = height / 2
        length = 5
        angle = incr

        // spiral loop
        FOR 1 TO 150
            drawline
            change direction by angle
            length = length + 3
            angle = (angle + incr) MOD 360
        ENDFOR

Solution:
#include
#include

#define factor M_PI/180
#define LAG 1000

void polySpiral(int windowWidth,int	windowHeight){
	int incr = 0, angle, i, length;
	double x,y,x1,y1;

	while(1){
		incr = (incr + 5)%360;

		x = windowWidth/2;
		y = windowHeight/2;

		length = 5;
		angle = incr;

		for(i=1;i<=150;i++){
			x1 = x + length*cos(factor*angle);
			y1 = y + length*sin(factor*angle);
			line(x,y,x1,y1);

			length += 3;

			angle = (angle + incr)%360;

			x = x1;
			y = y1;
		}
		delay(LAG);
		cleardevice();
	}
}

int main()
{
	initwindow(500,500,"Polyspiral");

	polySpiral(500,500);

	closegraph();

	return 0;
}


Polyspiral

Solution:
===Version #1 - Plain===
This Polyspiral Generator page alows user to enjoy hundreds of polyspirals in different colors.

This is inspired by a discovery made while using the gnuplot.
(See [[Talk:Polyspiral| Discussion ]] for Polyspiral task.)

'''Note:'''
* Some polyspirals would be degenerated to a single branch of it or even to a single line.

* An image uploading is still blocked. But you have a browser!? So, copy/paste/save this page and double click it.


Polyspiral

Solution:
Polyspiral Generator

Color:

red
darkred
green
darkgreen
blue
navy
brown
maroon
black

  Direction:

  Range:

    Polyspiral


Polyspiral

Solution:
import math

import pygame
from pygame.locals import *

pygame.init()
screen = pygame.display.set_mode((1024, 600))

pygame.display.set_caption("Polyspiral")

incr = 0

running = True

while running:
	pygame.time.Clock().tick(60)
	for event in pygame.event.get():
		if event.type==QUIT:
			running = False
			break

	incr = (incr + 0.05) % 360
	x1 = pygame.display.Info().current_w / 2
	y1 = pygame.display.Info().current_h / 2
	length = 5
	angle = incr

	screen.fill((255,255,255))

	for i in range(1,151):
		x2 = x1 + math.cos(angle) * length
		y2 = y1 + math.sin(angle) * length
		pygame.draw.line(screen, (255,0,0), (x1, y1), (x2, y2), 1)
		# pygame.draw.aaline(screen, (255,0,0), (x1, y1), (x2, y2)) # Anti-Aliased
		x1, y1 = x2, y2
		length += 3
		angle = (angle + incr) % 360

	pygame.display.flip()


Population count

The   ''population count''   is the number of   '''1'''s   (ones)   in the binary representation of a non-negative integer.

''Population count''   is also known as:
::::*   ''pop count''
::::*   ''popcount''
::::*   ''sideways sum''
::::*   ''bit summation''
::::*   ''Hamming weight''

For example,   '''5'''   (which is   '''101'''   in binary)   has a population count of   '''2'''.

''[http://mathworld.wolfram.com/EvilNumber.html Evil numbers]''   are non-negative integers  that have an   ''even''   population count.

''[http://mathworld.wolfram.com/OdiousNumber.html Odious numbers]''      are  positive integers that have an    ''odd''   population count.

;Task:
* write a function (or routine) to return the population count of a non-negative integer.
* all computation of the lists below should start with   '''0'''   (zero indexed).
:* display the   ''pop count''   of the   1st   thirty powers of   '''3'''       ('''30''',   '''31''',   '''32''',   '''33''',   '''34''',   ∙∙∙   '''329''').
:* display the   1st   thirty     ''evil''        numbers.
:* display the   1st   thirty          ''odious''           numbers.
* display each list of integers on one line   (which may or may not include a title),   each set of integers being shown should be properly identified.

;See also
* The On-Line Encyclopedia of Integer Sequences:   A000120 population count.
* The On-Line Encyclopedia of Integer Sequences:   A000069 odious numbers.
* The On-Line Encyclopedia of Integer Sequences:   A001969 evil numbers.

Solution:
#include

int main() {
  {
    unsigned long long n = 1;
    for (int i = 0; i < 30; i++) {
      // __builtin_popcount() for unsigned int
      // __builtin_popcountl() for unsigned long
      // __builtin_popcountll() for unsigned long long
      printf("%d ", __builtin_popcountll(n));
      n *= 3;
    }
    printf("\n");
  }

  int od[30];
  int ne = 0, no = 0;
  printf("evil  : ");
  for (int n = 0; ne+no < 60; n++) {
    if ((__builtin_popcount(n) & 1) == 0) {
      if (ne < 30) {
	printf("%d ", n);
	ne++;
      }
    } else {
      if (no < 30) {
	od[no++] = n;
      }
    }
  }
  printf("\n");
  printf("odious: ");
  for (int i = 0; i < 30; i++) {
    printf("%d ", od[i]);
  }
  printf("\n");

  return 0;
}


Population count

Solution:
>>> def popcount(n): return bin(n).count("1")
...
>>> [popcount(3**i) for i in range(30)]
[1, 2, 2, 4, 3, 6, 6, 5, 6, 8, 9, 13, 10, 11, 14, 15, 11, 14, 14, 17, 17, 20, 19, 22, 16, 18, 24, 30, 25, 25]
>>> evil, odious, i = [], [], 0
>>> while len(evil) < 30 or len(odious) < 30:
...     p = popcount(i)
...     if p % 2: odious.append(i)
...     else: evil.append(i)
...     i += 1
...
>>> evil[:30]
[0, 3, 5, 6, 9, 10, 12, 15, 17, 18, 20, 23, 24, 27, 29, 30, 33, 34, 36, 39, 40, 43, 45, 46, 48, 51, 53, 54, 57, 58]
>>> odious[:30]
[1, 2, 4, 7, 8, 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44, 47, 49, 50, 52, 55, 56, 59]
>>>


Population count

Solution:
'''Population count'''

from functools import reduce

# popCount :: Int -> Int
def popCount(n):
    '''The count of non-zero digits in the binary
       representation of the positive integer n.'''
    def go(x):
        return Just(divmod(x, 2)) if 0 < x else Nothing()
    return sum(unfoldl(go)(n))

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

    print('Population count of first 30 powers of 3:')
    print('    ' + showList(
        [popCount(pow(3, x)) for x in enumFromTo(0)(29)]
    ))

    evilNums, odiousNums = partition(
        compose(even, popCount)
    )(enumFromTo(0)(59))

    print("\nFirst thirty 'evil' numbers:")
    print('    ' + showList(evilNums))

    print("\nFirst thirty 'odious' numbers:")
    print('    ' + showList(odiousNums))

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

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

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

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

# enumFromTo :: Int -> Int -> [Int]
def enumFromTo(m):
    '''Enumeration of integer values [m..n]'''
    return lambda n: range(m, 1 + n)

# even :: Int -> Bool
def even(x):
    '''True if x is an integer
       multiple of two.
    '''
    return 0 == x % 2

# partition :: (a -> Bool) -> [a] -> ([a], [a])
def partition(p):
    '''The pair of lists of those elements in xs
       which respectively do, and don't
       satisfy the predicate p.
    '''

    def go(a, x):
        ts, fs = a
        return (ts + [x], fs) if p(x) else (ts, fs + [x])
    return lambda xs: reduce(go, xs, ([], []))

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

# unfoldl(lambda x: Just(((x - 1), x)) if 0 != x else Nothing())(10)
# -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# unfoldl :: (b -> Maybe (b, a)) -> b -> [a]
def unfoldl(f):
    '''Dual to reduce or foldl.
       Where these reduce a list to a summary value, unfoldl
       builds a list from a seed value.
       Where f returns Just(a, b), a is appended 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(v):
        x, r = v, v
        xs = []
        while True:
            mb = f(x)
            if mb.get('Nothing'):
                return xs
            else:
                x, r = mb.get('Just')
                xs.insert(0, r)
        return xs
    return go

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


Pragmatic directives

[[Category:Pragmatic directives]]

Pragmatic directives cause the language to operate in a specific manner,   allowing support for operational variances within the program code   (possibly by the loading of specific or alternative modules).

;Task:
List any pragmatic directives supported by the language,   and demonstrate how to activate and deactivate the pragmatic directives and to describe or demonstrate the scope of effect that the pragmatic directives have within a program.

Solution:
/*Almost every C program has the below line,
the #include preprocessor directive is used to
instruct the compiler which files to load before compiling the program.

All preprocessor commands begin with #
*/
#include

/*The #define preprocessor directive is often used to create abbreviations for code segments*/
#define Hi printf("Hi There.");

/*It can be used, or misused, for rather innovative uses*/

#define start int main(){
#define end return 0;}

start

Hi

/*And here's the nice part, want your compiler to talk to you ?
Just use the #warning pragma if you are using a C99 compliant compiler
like GCC*/
#warning "Don't you have anything better to do ?"

#ifdef __unix__
#warning "What are you doing still working on Unix ?"
printf("\nThis is an Unix system.");
#elif _WIN32
#warning "You couldn't afford a 64 bit ?"
printf("\nThis is a 32 bit Windows system.");
#elif _WIN64
#warning "You couldn't afford an Apple ?"
printf("\nThis is a 64 bit Windows system.");
#endif

end

/*Enlightened ?*/


Pragmatic directives

Solution:
Python 3.2 (r32:88445, Feb 20 2011, 21:30:00) [MSC v.1500 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import __future__
>>> __future__.all_feature_names
['nested_scopes', 'generators', 'division', 'absolute_import', 'with_statement', 'print_function', 'unicode_literals', 'barry_as_FLUFL']
>>>


Prime triangle

You will require a function f which when given an integer S will return a list of the arrangements of the integers 1 to S such that g1=1 gS=S and generally for n=1 to n=S-1 gn+gn+1 is prime. S=1 is undefined. For S=2 to S=20 print f(S) to form a triangle. Then again for S=2 to S=20 print the number of possible arrangements of 1 to S meeting these requirements.

;See also
:* OEIS:A036440

Solution:
#include
#include
#include
#include

bool is_prime(unsigned int n) {
    assert(n < 64);
    static bool isprime[] = {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0,
                             0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1,
                             0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1,
                             0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0};
    return isprime[n];
}

void swap(unsigned int* a, size_t i, size_t j) {
    unsigned int tmp = a[i];
    a[i] = a[j];
    a[j] = tmp;
}

bool prime_triangle_row(unsigned int* a, size_t length) {
    if (length == 2)
        return is_prime(a[0] + a[1]);
    for (size_t i = 1; i + 1 < length; i += 2) {
        if (is_prime(a[0] + a[i])) {
            swap(a, i, 1);
            if (prime_triangle_row(a + 1, length - 1))
                return true;
            swap(a, i, 1);
        }
    }
    return false;
}

int prime_triangle_count(unsigned int* a, size_t length) {
    int count = 0;
    if (length == 2) {
        if (is_prime(a[0] + a[1]))
            ++count;
    } else {
        for (size_t i = 1; i + 1 < length; i += 2) {
            if (is_prime(a[0] + a[i])) {
                swap(a, i, 1);
                count += prime_triangle_count(a + 1, length - 1);
                swap(a, i, 1);
            }
        }
    }
    return count;
}

void print(unsigned int* a, size_t length) {
    if (length == 0)
        return;
    printf("%2u", a[0]);
    for (size_t i = 1; i < length; ++i)
        printf(" %2u", a[i]);
    printf("\n");
}

int main() {
    clock_t start = clock();
    for (unsigned int n = 2; n < 21; ++n) {
        unsigned int a[n];
        for (unsigned int i = 0; i < n; ++i)
            a[i] = i + 1;
        if (prime_triangle_row(a, n))
            print(a, n);
    }
    printf("\n");
    for (unsigned int n = 2; n < 21; ++n) {
        unsigned int a[n];
        for (unsigned int i = 0; i < n; ++i)
            a[i] = i + 1;
        if (n > 2)
            printf(" ");
        printf("%d", prime_triangle_count(a, n));
    }
    printf("\n");
    clock_t end = clock();
    double duration = (end - start + 0.0) / CLOCKS_PER_SEC;
    printf("\nElapsed time: %f seconds\n", duration);
    return 0;
}


Prime triangle

Solution:
from numpy import array
# for Rosetta Code by MG - 20230312
def is_prime(n: int) -> bool:
    assert n < 64
    return ((1 << n) & 0x28208a20a08a28ac) != 0

def prime_triangle_row(a: array, start: int, length: int) -> bool:
    if length == 2:
        return is_prime(a[0] + a[1])
    for i in range(1, length - 1, 1):
        if is_prime(a[start] + a[start + i]):
            a[start + i], a[start + 1] = a[start + 1], a[start + i]
            if prime_triangle_row(a, start + 1, length - 1):
                return True
            a[start + i], a[start + 1] = a[start + 1], a[start + i]
    return False

def prime_triangle_count(a: array, start: int, length: int) -> int:
    count: int = 0
    if length == 2:
        if is_prime(a[start] + a[start + 1]):
            count += 1
    else:
        for i in range(1, length - 1, 1):
            if is_prime(a[start] + a[start + i]):
                a[start + i], a[start + 1] = a[start + 1], a[start + i]
                count += prime_triangle_count(a, start + 1, length - 1)
                a[start + i], a[start + 1] = a[start + 1], a[start + i]
    return count

def print_row(a: array):
    if a == []:
        return
    print("%2d"% a[0], end=" ")
    for x in a[1:]:
        print("%2d"% x, end=" ")
    print()

for n in range(2, 21):
    tr: array = [_ for _ in range(1, n + 1)]
    if prime_triangle_row(tr, 0, n):
        print_row(tr)
print()
for n in range(2, 21):
    tr: array = [_ for _ in range(1, n + 1)]
    if n > 2:
        print(" ", end="")
    print(prime_triangle_count(tr, 0, n), end="")
print()


Priority queue

A queue, with an important distinction: each item is added to a priority queue with a priority level, and will be later removed from the queue with the highest priority element first. That is, the items are (conceptually) stored in the queue in priority order instead of in insertion order.

;Task:
Create a priority queue.   The queue must support at least two operations:
:#   Insertion.   An element is added to the queue with a priority (a numeric value).
:#   Top item removal.   Deletes the element or one of the elements with the current top priority and return it.

Optionally, other operations may be defined, such as peeking (find what current top priority/top element is), merging (combining two priority queues into one), etc.

To test your implementation, insert a number of elements into the queue, each with some random priority.

Then dequeue them sequentially; now the elements should be sorted by priority.

You can use the following task/priority items as input data:
         '''Priority'''         '''Task'''
        ══════════   ════════════════
            3         Clear drains
            4         Feed cat
            5         Make tea
            1         Solve RC tasks
            2         Tax return

The implementation should try to be efficient.   A typical implementation has   '''O(log n)'''   insertion and extraction time,   where   '''n'''   is the number of items in the queue.

You may choose to impose certain limits such as small range of allowed priority levels, limited capacity, etc.   If so, discuss the reasons behind it.

Solution:
#include
#include

typedef struct {
    int priority;
    char *data;
} node_t;

typedef struct {
    node_t *nodes;
    int len;
    int size;
} heap_t;

void push (heap_t *h, int priority, char *data) {
    if (h->len + 1 >= h->size) {
        h->size = h->size ? h->size * 2 : 4;
        h->nodes = (node_t *)realloc(h->nodes, h->size * sizeof (node_t));
    }
    int i = h->len + 1;
    int j = i / 2;
    while (i > 1 && h->nodes[j].priority > priority) {
        h->nodes[i] = h->nodes[j];
        i = j;
        j = j / 2;
    }
    h->nodes[i].priority = priority;
    h->nodes[i].data = data;
    h->len++;
}

char *pop (heap_t *h) {
    int i, j, k;
    if (!h->len) {
        return NULL;
    }
    char *data = h->nodes[1].data;

    h->nodes[1] = h->nodes[h->len];

    h->len--;

    i = 1;
    while (i!=h->len+1) {
        k = h->len+1;
        j = 2 * i;
        if (j <= h->len && h->nodes[j].priority < h->nodes[k].priority) {
            k = j;
        }
        if (j + 1 <= h->len && h->nodes[j + 1].priority < h->nodes[k].priority) {
            k = j + 1;
        }
        h->nodes[i] = h->nodes[k];
        i = k;
    }
    return data;
}

int main () {
    heap_t *h = (heap_t *)calloc(1, sizeof (heap_t));
    push(h, 3, "Clear drains");
    push(h, 4, "Feed cat");
    push(h, 5, "Make tea");
    push(h, 1, "Solve RC tasks");
    push(h, 2, "Tax return");
    int i;
    for (i = 0; i < 5; i++) {
        printf("%s\n", pop(h));
    }
    return 0;
}


Priority queue

Solution:
>>> import queue
>>> help(queue.PriorityQueue)
Help on class PriorityQueue in module queue:

class PriorityQueue(Queue)
 |  Variant of Queue that retrieves open entries in priority order (lowest first).
 |
 |  Entries are typically tuples of the form:  (priority number, data).
 |
 |  Method resolution order:
 |      PriorityQueue
 |      Queue
 |      builtins.object
 |
 |  Methods inherited from Queue:
 |
 |  __init__(self, maxsize=0)
 |
 |  empty(self)
 |      Return True if the queue is empty, False otherwise (not reliable!).
 |
 |      This method is likely to be removed at some point.  Use qsize() == 0
 |      as a direct substitute, but be aware that either approach risks a race
 |      condition where a queue can grow before the result of empty() or
 |      qsize() can be used.
 |
 |      To create code that needs to wait for all queued tasks to be
 |      completed, the preferred technique is to use the join() method.
 |
 |  full(self)
 |      Return True if the queue is full, False otherwise (not reliable!).
 |
 |      This method is likely to be removed at some point.  Use qsize() >= n
 |      as a direct substitute, but be aware that either approach risks a race
 |      condition where a queue can shrink before the result of full() or
 |      qsize() can be used.
 |
 |  get(self, block=True, timeout=None)
 |      Remove and return an item from the queue.
 |
 |      If optional args 'block' is true and 'timeout' is None (the default),
 |      block if necessary until an item is available. If 'timeout' is
 |      a positive number, it blocks at most 'timeout' seconds and raises
 |      the Empty exception if no item was available within that time.
 |      Otherwise ('block' is false), return an item if one is immediately
 |      available, else raise the Empty exception ('timeout' is ignored
 |      in that case).
 |
 |  get_nowait(self)
 |      Remove and return an item from the queue without blocking.
 |
 |      Only get an item if one is immediately available. Otherwise
 |      raise the Empty exception.
 |
 |  join(self)
 |      Blocks until all items in the Queue have been gotten and processed.
 |
 |      The count of unfinished tasks goes up whenever an item is added to the
 |      queue. The count goes down whenever a consumer thread calls task_done()
 |      to indicate the item was retrieved and all work on it is complete.
 |
 |      When the count of unfinished tasks drops to zero, join() unblocks.
 |
 |  put(self, item, block=True, timeout=None)
 |      Put an item into the queue.
 |
 |      If optional args 'block' is true and 'timeout' is None (the default),
 |      block if necessary until a free slot is available. If 'timeout' is
 |      a positive number, it blocks at most 'timeout' seconds and raises
 |      the Full exception if no free slot was available within that time.
 |      Otherwise ('block' is false), put an item on the queue if a free slot
 |      is immediately available, else raise the Full exception ('timeout'
 |      is ignored in that case).
 |
 |  put_nowait(self, item)
 |      Put an item into the queue without blocking.
 |
 |      Only enqueue the item if a free slot is immediately available.
 |      Otherwise raise the Full exception.
 |
 |  qsize(self)
 |      Return the approximate size of the queue (not reliable!).
 |
 |  task_done(self)
 |      Indicate that a formerly enqueued task is complete.
 |
 |      Used by Queue consumer threads.  For each get() used to fetch a task,
 |      a subsequent call to task_done() tells the queue that the processing
 |      on the task is complete.
 |
 |      If a join() is currently blocking, it will resume when all items
 |      have been processed (meaning that a task_done() call was received
 |      for every item that had been put() into the queue).
 |
 |      Raises a ValueError if called more times than there were items
 |      placed in the queue.
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from Queue:
 |
 |  __dict__
 |      dictionary for instance variables (if defined)
 |
 |  __weakref__
 |      list of weak references to the object (if defined)

>>>


Pseudo-random numbers/Combined recursive generator MRG32k3a

;[https://www.nag.com/numeric/fl/nagdoc_fl23/pdf/g05/g05intro.pdf MRG32k3a] Combined recursive generator (pseudo-code):

    /* Constants */
    /* First generator */
    a1 = [0, 1403580, -810728]
    m1 = 2**32 - 209
    /* Second Generator */
    a2 = [527612, 0, -1370589]
    m2 = 2**32 - 22853

    d = m1 + 1

    class MRG32k3a
        x1 = [0, 0, 0]  /* list of three last values of gen #1 */
        x2 = [0, 0, 0]  /* list of three last values of gen #2 */

        method seed(u64 seed_state)
            assert seed_state in range >0 and < d
            x1 = [seed_state, 0, 0]
            x2 = [seed_state, 0, 0]
        end method

        method next_int()
            x1i = (a1[0]*x1[0] + a1[1]*x1[1] + a1[2]*x1[2]) mod m1
            x2i = (a2[0]*x2[0] + a2[1]*x2[1] + a2[2]*x2[2]) mod m2
            x1 = [x1i, x1[0], x1[1]]    /* Keep last three */
            x2 = [x2i, x2[0], x2[1]]    /* Keep last three */
            z = (x1i - x2i) % m1
            answer = (z + 1)

            return answer
        end method

        method next_float():
            return float next_int() / d
        end method

    end class

:MRG32k3a Use:
    random_gen = instance MRG32k3a
    random_gen.seed(1234567)
    print(random_gen.next_int())   /* 1459213977 */
    print(random_gen.next_int())   /* 2827710106 */
    print(random_gen.next_int())   /* 4245671317 */
    print(random_gen.next_int())   /* 3877608661 */
    print(random_gen.next_int())   /* 2595287583 */

;Task

* Generate a class/set of functions that generates pseudo-random
numbers as shown above.

* Show that the first five integers generated with the seed `1234567`
are as shown above

* Show that for an initial seed of '987654321' the counts of 100_000
repetitions of

    floor(random_gen.next_float() * 5)

Is as follows:

    0: 20002, 1: 20060, 2: 19948, 3: 20059, 4: 19931

* Show your output here, on this page.

Solution:
#include
#include
#include

int64_t mod(int64_t x, int64_t y) {
    int64_t m = x % y;
    if (m < 0) {
        if (y < 0) {
            return m - y;
        } else {
            return m + y;
        }
    }
    return m;
}

// Constants
// First generator
const static int64_t a1[3] = { 0, 1403580, -810728 };
const static int64_t m1 = (1LL << 32) - 209;
// Second generator
const static int64_t a2[3] = { 527612, 0, -1370589 };
const static int64_t m2 = (1LL << 32) - 22853;

const static int64_t d = (1LL << 32) - 209 + 1; // m1 + 1

// the last three values of the first generator
static int64_t x1[3];
// the last three values of the second generator
static int64_t x2[3];

void seed(int64_t seed_state) {
    x1[0] = seed_state;
    x1[1] = 0;
    x1[2] = 0;

    x2[0] = seed_state;
    x2[1] = 0;
    x2[2] = 0;
}

int64_t next_int() {
    int64_t x1i = mod((a1[0] * x1[0] + a1[1] * x1[1] + a1[2] * x1[2]), m1);
    int64_t x2i = mod((a2[0] * x2[0] + a2[1] * x2[1] + a2[2] * x2[2]), m2);
    int64_t z = mod(x1i - x2i, m1);

    // keep last three values of the first generator
    x1[2] = x1[1];
    x1[1] = x1[0];
    x1[0] = x1i;

    // keep last three values of the second generator
    x2[2] = x2[1];
    x2[1] = x2[0];
    x2[0] = x2i;

    return z + 1;
}

double next_float() {
    return (double)next_int() / d;
}

int main() {
    int counts[5] = { 0, 0, 0, 0, 0 };
    int i;

    seed(1234567);
    printf("%lld\n", next_int());
    printf("%lld\n", next_int());
    printf("%lld\n", next_int());
    printf("%lld\n", next_int());
    printf("%lld\n", next_int());
    printf("\n");

    seed(987654321);
    for (i = 0; i < 100000; i++) {
        int64_t value = floor(next_float() * 5);
        counts[value]++;
    }
    for (i = 0; i < 5; i++) {
        printf("%d: %d\n", i, counts[i]);
    }

    return 0;
}


Solution:
# Constants
a1 = [0, 1403580, -810728]
m1 = 2**32 - 209
#
a2 = [527612, 0, -1370589]
m2 = 2**32 - 22853
#
d = m1 + 1

class MRG32k3a():

    def __init__(self, seed_state=123):
        self.seed(seed_state)

    def seed(self, seed_state):
        assert 0


Pseudo-random numbers/Middle-square method

; The Method:
To generate a sequence of n-digit pseudorandom numbers, an n-digit starting value is created and squared, producing a 2n-digit number. If the result has fewer than 2n digits, leading zeroes are added to compensate. The middle n digits of the result would be the next number in the sequence and returned as the result. This process is then repeated to generate more numbers.
; Pseudo code:

var seed = 675248
function random()
    var s = str(seed * seed) 'str: turn a number into string
    do while not len(s) = 12
        s = "0" + s          'add zeroes before the string
    end do
    seed = val(mid(s, 4, 6)) 'mid: string variable, start, length
                             'val: turn a string into number
    return seed
end function

; Middle-square method use:

for i = 1 to 5
    print random()
end for

;Task:

* Generate a class/set of functions that generates pseudo-random
numbers (6 digits) as shown above.

* Show the first five integers generated with the seed 675248 as shown above.

* Show your output here, on this page.

Solution:
#include
long long seed;
long long random(){
        seed = seed * seed / 1000 % 1000000;
        return seed;
}
int main(){
        seed = 675248;
        for(int i=1;i<=5;i++)
                printf("%lld\n",random());
        return 0;
}


Solution:
seed = 675248
def random():
    global seed
    seed = int(str(seed ** 2).zfill(12)[3:9])
    return seed
for _ in range(5):
    print(random())


Pseudo-random numbers/PCG32

;Some definitions to help in the explanation:

:Floor operation
::https://en.wikipedia.org/wiki/Floor_and_ceiling_functions
::Greatest integer less than or equal to a real number.

:Bitwise Logical shift operators (c-inspired)
::https://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts
::Binary bits of value shifted left or right, with zero bits shifted in where appropriate.
::Examples are shown for 8 bit binary numbers; most significant bit to the left.

:: '''<<''' Logical shift left by given number of bits.
:::E.g Binary 00110101 '''<<''' 2 == Binary 11010100

:: '''>>''' Logical shift right by given number of bits.
:::E.g Binary 00110101 '''>>''' 2 == Binary 00001101

:'''^''' Bitwise exclusive-or operator
::https://en.wikipedia.org/wiki/Exclusive_or
::Bitwise comparison for if bits differ
:::E.g Binary 00110101 '''^''' Binary 00110011 == Binary 00000110

:'''|''' Bitwise or operator
::https://en.wikipedia.org/wiki/Bitwise_operation#OR
::Bitwise comparison gives 1 if any of corresponding bits are 1
:::E.g Binary 00110101 '''|''' Binary 00110011 == Binary 00110111

;[https://www.pcg-random.org/download.html#minimal-c-implementation| PCG32] Generator (pseudo-code):

PCG32 has two unsigned 64-bit integers of internal state:
# '''state''': All 2**64 values may be attained.
# '''sequence''': Determines which of 2**63 sequences that state iterates through. (Once set together with state at time of seeding will stay constant for this generators lifetime).

Values of sequence allow 2**63 ''different'' sequences of random numbers from the same state.

The algorithm is given 2 U64 inputs called seed_state, and seed_sequence. The algorithm proceeds in accordance with the following pseudocode:-

const N<-U64 6364136223846793005
const inc<-U64 (seed_sequence << 1) | 1
state<-U64 ((inc+seed_state)*N+inc
do forever
  xs<-U32 (((state>>18)^state)>>27)
  rot<-INT (state>>59)
  OUTPUT U32 (xs>>rot)|(xs<<((-rot)&31))
  state<-state*N+inc
end do

Note that this an anamorphism – dual to catamorphism, and encoded in some languages as a general higher-order `unfold` function, dual to `fold` or `reduce`.

;Task:

* Generate a class/set of functions that generates pseudo-random
numbers using the above.

* Show that the first five integers generated with the seed 42, 54
are: 2707161783 2068313097 3122475824 2211639955 3215226955

* Show that for an initial seed of 987654321, 1 the counts of 100_000 repetitions of

    floor(random_gen.next_float() * 5)

:Is as follows:

    0: 20049, 1: 20022, 2: 20115, 3: 19809, 4: 20005

* Show your output here, on this page.

Solution:
#include
#include
#include

const uint64_t N = 6364136223846793005;

static uint64_t state = 0x853c49e6748fea9b;
static uint64_t inc = 0xda3e39cb94b95bdb;

uint32_t pcg32_int() {
    uint64_t old = state;
    state = old * N + inc;
    uint32_t shifted = (uint32_t)(((old >> 18) ^ old) >> 27);
    uint32_t rot = old >> 59;
    return (shifted >> rot) | (shifted << ((~rot + 1) & 31));
}

double pcg32_float() {
    return ((double)pcg32_int()) / (1LL << 32);
}

void pcg32_seed(uint64_t seed_state, uint64_t seed_sequence) {
    state = 0;
    inc = (seed_sequence << 1) | 1;
    pcg32_int();
    state = state + seed_state;
    pcg32_int();
}

int main() {
    int counts[5] = { 0, 0, 0, 0, 0 };
    int i;

    pcg32_seed(42, 54);
    printf("%u\n", pcg32_int());
    printf("%u\n", pcg32_int());
    printf("%u\n", pcg32_int());
    printf("%u\n", pcg32_int());
    printf("%u\n", pcg32_int());
    printf("\n");

    pcg32_seed(987654321, 1);
    for (i = 0; i < 100000; i++) {
        int j = (int)floor(pcg32_float() * 5.0);
        counts[j]++;
    }

    printf("The counts for 100,000 repetitions are:\n");
    for (i = 0; i < 5; i++) {
        printf("  %d : %d\n", i, counts[i]);
    }

    return 0;
}


Pseudo-random numbers/PCG32

Solution:
mask64 = (1 << 64) - 1
mask32 = (1 << 32) - 1
CONST = 6364136223846793005

class PCG32():

    def __init__(self, seed_state=None, seed_sequence=None):
        if all(type(x) == int for x in (seed_state, seed_sequence)):
            self.seed(seed_state, seed_sequence)
        else:
            self.state = self.inc = 0

    def seed(self, seed_state, seed_sequence):
        self.state = 0
        self.inc = ((seed_sequence << 1) | 1) & mask64
        self.next_int()
        self.state = (self.state + seed_state)
        self.next_int()

    def next_int(self):
        "return random 32 bit unsigned int"
        old = self.state
        self.state = ((old * CONST) + self.inc) & mask64
        xorshifted = (((old >> 18) ^ old) >> 27) & mask32
        rot = (old >> 59) & mask32
        answer = (xorshifted >> rot) | (xorshifted << ((-rot) & 31))
        answer = answer &mask32

        return answer

    def  next_float(self):
        "return random float between 0 and 1"
        return self.next_int() / (1 << 32)

if __name__ == '__main__':
    random_gen = PCG32()
    random_gen.seed(42, 54)
    for i in range(5):
        print(random_gen.next_int())

    random_gen.seed(987654321, 1)
    hist = {i:0 for i in range(5)}
    for i in range(100_000):
        hist[int(random_gen.next_float() *5)] += 1
    print(hist)


Pseudo-random numbers/Xorshift star

;Some definitions to help in the explanation:

:Floor operation
::https://en.wikipedia.org/wiki/Floor_and_ceiling_functions
::Greatest integer less than or equal to a real number.

:Bitwise Logical shift operators (c-inspired)
::https://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts
::Binary bits of value shifted left or right, with zero bits shifted in where appropriate.
::Examples are shown for 8 bit binary numbers; most significant bit to the left.

:: '''<<''' Logical shift left by given number of bits.
:::E.g Binary 00110101 '''<<''' 2 == Binary 11010100

:: '''>>''' Logical shift right by given number of bits.
:::E.g Binary 00110101 '''>>''' 2 == Binary 00001101

:'''^''' Bitwise exclusive-or operator
::https://en.wikipedia.org/wiki/Exclusive_or
::Bitwise comparison for if bits differ
:::E.g Binary 00110101 '''^''' Binary 00110011 == Binary 00000110

;[https://en.wikipedia.org/wiki/Xorshift#xorshift*| Xorshift_star] Generator (pseudo-code):

    /* Let u64 denote an unsigned 64 bit integer type. */
    /* Let u32 denote an unsigned 32 bit integer type. */

    class Xorshift_star
        u64 state       /* Must be seeded to non-zero initial value */
        u64 const = HEX '2545F4914F6CDD1D'

        method seed(u64 num):
            state =  num
        end method

        method next_int():
            u64 x = state
            x = x ^ (x >> 12)
            x = x ^ (x << 25)
            x = x ^ (x >> 27)
            state = x
            u32 answer = ((x * const) >> 32)

            return answer
        end method

        method next_float():
            return float next_int() / (1 << 32)
        end method

    end class

:;Xorshift use:

    random_gen = instance Xorshift_star
    random_gen.seed(1234567)
    print(random_gen.next_int())   /* 3540625527 */
    print(random_gen.next_int())   /* 2750739987 */
    print(random_gen.next_int())   /* 4037983143 */
    print(random_gen.next_int())   /* 1993361440 */
    print(random_gen.next_int())   /* 3809424708 */

;Task:

* Generate a class/set of functions that generates pseudo-random
numbers as shown above.

* Show that the first five integers genrated with the seed 1234567
are as shown above

* Show that for an initial seed of 987654321, the counts of 100_000 repetitions of

    floor(random_gen.next_float() * 5)

:Is as follows:

    0: 20103, 1: 19922, 2: 19937, 3: 20031, 4: 20007

* Show your output here, on this page.

Solution:
#include
#include
#include

static uint64_t state;
static const uint64_t STATE_MAGIC = 0x2545F4914F6CDD1D;

void seed(uint64_t num) {
    state = num;
}

uint32_t next_int() {
    uint64_t x;
    uint32_t answer;

    x = state;
    x = x ^ (x >> 12);
    x = x ^ (x << 25);
    x = x ^ (x >> 27);
    state = x;
    answer = ((x * STATE_MAGIC) >> 32);

    return answer;
}

float next_float() {
    return (float)next_int() / (1LL << 32);
}

int main() {
    int counts[5] = { 0, 0, 0, 0, 0 };
    int i;

    seed(1234567);
    printf("%u\n", next_int());
    printf("%u\n", next_int());
    printf("%u\n", next_int());
    printf("%u\n", next_int());
    printf("%u\n", next_int());
    printf("\n");

    seed(987654321);
    for (i = 0; i < 100000; i++) {
        int j = (int)floor(next_float() * 5.0);
        counts[j]++;
    }
    for (i = 0; i < 5; i++) {
        printf("%d: %d\n", i, counts[i]);
    }

    return 0;
}


Pseudo-random numbers/Xorshift star

Solution:
mask64 = (1 << 64) - 1
mask32 = (1 << 32) - 1
const = 0x2545F4914F6CDD1D

class Xorshift_star():

    def __init__(self, seed=0):
        self.state = seed & mask64

    def seed(self, num):
        self.state =  num & mask64

    def next_int(self):
        "return random int between 0 and 2**32"
        x = self.state
        x = (x ^ (x >> 12)) & mask64
        x = (x ^ (x << 25)) & mask64
        x = (x ^ (x >> 27)) & mask64
        self.state = x
        answer = (((x * const) & mask64) >> 32) & mask32
        return answer

    def  next_float(self):
        "return random float between 0 and 1"
        return self.next_int() / (1 << 32)

if __name__ == '__main__':
    random_gen = Xorshift_star()
    random_gen.seed(1234567)
    for i in range(5):
        print(random_gen.next_int())

    random_gen.seed(987654321)
    hist = {i:0 for i in range(5)}
    for i in range(100_000):
        hist[int(random_gen.next_float() *5)] += 1
    print(hist)


Pythagoras tree

right

The Pythagoras tree is a fractal tree constructed from squares.  It is named after Pythagoras because each triple of touching squares encloses a right triangle, in a configuration traditionally used to represent the Pythagorean theorem.

;Task
Construct a Pythagoras tree of order 7 using only vectors (no rotation or trigonometric functions).

;Related tasks
* Fractal tree

Solution:
#include
#include
#include
#include

typedef struct{
	double x,y;
}point;

void pythagorasTree(point a,point b,int times){

	point c,d,e;

	c.x = b.x - (a.y -  b.y);
	c.y = b.y - (b.x - a.x);

	d.x = a.x - (a.y -  b.y);
	d.y = a.y - (b.x - a.x);

	e.x = d.x +  ( b.x - a.x - (a.y -  b.y) ) / 2;
	e.y = d.y -  ( b.x - a.x + a.y -  b.y ) / 2;

	if(times>0){
		setcolor(rand()%15 + 1);

		line(a.x,a.y,b.x,b.y);
		line(c.x,c.y,b.x,b.y);
		line(c.x,c.y,d.x,d.y);
		line(a.x,a.y,d.x,d.y);

		pythagorasTree(d,e,times-1);
		pythagorasTree(e,c,times-1);
	}
}

int main(){

	point a,b;
	double side;
	int iter;

	time_t t;

	printf("Enter initial side length : ");
	scanf("%lf",&side);

	printf("Enter number of iterations : ");
	scanf("%d",&iter);

	a.x = 6*side/2 - side/2;
	a.y = 4*side;
	b.x = 6*side/2 + side/2;
	b.y = 4*side;

	initwindow(6*side,4*side,"Pythagoras Tree ?");

	srand((unsigned)time(&t));

	pythagorasTree(a,b,iter);

	getch();

	closegraph();

	return 0;

}


Pythagoras tree

Solution:
from turtle import goto, pu, pd, color, done

def level(ax, ay, bx, by, depth=0):
    if depth > 0:
        dx,dy = bx-ax, ay-by
        x3,y3 = bx-dy, by-dx
        x4,y4 = ax-dy, ay-dx
        x5,y5 = x4 + (dx - dy)/2, y4 - (dx + dy)/2
        goto(ax, ay), pd()
        for x, y in ((bx, by), (x3, y3), (x4, y4), (ax, ay)):
            goto(x, y)
        pu()
        level(x4,y4, x5,y5, depth - 1)
        level(x5,y5, x3,y3, depth - 1)

if __name__ == '__main__':
    color('red', 'yellow')
    pu()
    level(-100, 500, 100, 500, depth=8)
    done()


Pythagorean quadruples

One form of   '''Pythagorean quadruples'''   is   (for positive integers   '''a''',   '''b''',   '''c''',   and   '''d'''):

::::::::    a2   +   b2   +   c2     =     d2

An example:

::::::::    22   +   32   +   62     =     72

::::: which is:

::::::::    4    +   9    +   36     =     49

;Task:

For positive integers up   '''2,200'''   (inclusive),   for all values of   '''a''',
'''b''',   '''c''',   and   '''d''',
find   (and show here)   those values of   '''d'''   that   ''can't''   be represented.

Show the values of   '''d'''   on one line of output   (optionally with a title).

;Related tasks:
*   [[Euler's sum of powers conjecture]].
*   [[Pythagorean triples]].

;Reference:
:*   the Wikipedia article:   [https://en.wikipedia.org/wiki/Pythagorean_quadruple Pythagorean quadruple].

Solution:
#include
#include
#include

#define N 2200

int main(int argc, char **argv){
   int a,b,c,d;
   int r[N+1];
   memset(r,0,sizeof(r));	// zero solution array
   for(a=1; a<=N; a++){
      for(b=a; b<=N; b++){
	 int aabb;
	 if(a&1 && b&1) continue;  // for positive odd a and b, no solution.
	 aabb=a*a + b*b;
	 for(c=b; c<=N; c++){
	    int aabbcc=aabb + c*c;
	    d=(int)sqrt((float)aabbcc);
	    if(aabbcc == d*d && d<=N) r[d]=1;	// solution
	 }
      }
   }
   for(a=1; a<=N; a++)
      if(!r[a]) printf("%d ",a);	// print non solution
   printf("\n");
}


Pythagorean quadruples

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

    // main :: IO ()
    const main = () => {
        const xs = takeWhileGen(
            x => 2200 >= x,
            mergeInOrder(
                powersOfTwo(),
                fmapGen(x => 5 * x, powersOfTwo())
            )
        );

        return (
            console.log(JSON.stringify(xs)),
            xs
        );
    }

    // powersOfTwo :: Gen [Int]
    const powersOfTwo = () =>
        iterate(x => 2 * x, 1);

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

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

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

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

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

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

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

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

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

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

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

    // takeWhileGen :: (a -> Bool) -> Generator [a] -> [a]
    const takeWhileGen = (p, xs) => {
        const ys = [];
        let
            nxt = xs.next(),
            v = nxt.value;
        while (!nxt.done && p(v)) {
            ys.push(v);
            nxt = xs.next();
            v = nxt.value
        }
        return ys;
    };

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

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

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


Pythagorean quadruples

Solution:
def quad(top=2200):
    r = [False] * top
    ab = [False] * (top * 2)**2
    for a in range(1, top):
        for b in range(a, top):
            ab[a * a + b * b] = True
    s = 3
    for c in range(1, top):
        s1, s, s2 = s, s + 2, s + 2
        for d in range(c + 1, top):
            if ab[s1]:
                r[d] = True
            s1 += s2
            s2 += 2
    return [i for i, val in enumerate(r) if not val and i]

if __name__ == '__main__':
    n = 2200
    print(f"Those values of d in 1..{n} that can't be represented: {quad(n)}")


Pythagorean triples

A Pythagorean triple is defined as three positive integers (a, b, c) where a < b < c, and a^2+b^2=c^2.

They are called primitive triples if a, b, c are co-prime, that is, if their pairwise greatest common divisors {\rm gcd}(a, b) = {\rm gcd}(a, c) = {\rm gcd}(b, c) = 1.

Because of their relationship through the Pythagorean theorem, a, b, and c are co-prime if a and b are co-prime ({\rm gcd}(a, b) = 1).

Each triple forms the length of the sides of a right triangle, whose perimeter is P=a+b+c.

;Task:
The task is to determine how many Pythagorean triples there are with a perimeter no larger than 100 and the number of these that are primitive.

;Extra credit:
Deal with large values.   Can your program handle a maximum perimeter of 1,000,000?   What about 10,000,000?   100,000,000?

Note: the extra credit is not for you to demonstrate how fast your language is compared to others;   you need a proper algorithm to solve them in a timely manner.

;Related tasks:
*   [[Euler's sum of powers conjecture]]
*   [[List comprehensions]]
*   [[Pythagorean quadruples]]

Solution:
#include
#include
#include

/* should be 64-bit integers if going over 1 billion */
typedef unsigned long xint;
#define FMT "%lu"

xint total, prim, max_peri;
xint U[][9] =  {{ 1, -2, 2,  2, -1, 2,  2, -2, 3},
        { 1,  2, 2,  2,  1, 2,  2,  2, 3},
        {-1,  2, 2, -2,  1, 2, -2,  2, 3}};

void new_tri(xint in[])
{
    int i;
    xint t[3], p = in[0] + in[1] + in[2];

    if (p > max_peri) return;

    prim ++;

    /* for every primitive triangle, its multiples would be right-angled too;
     * count them up to the max perimeter */
    total += max_peri / p;

    /* recursively produce next tier by multiplying the matrices */
    for (i = 0; i < 3; i++) {
        t[0] = U[i][0] * in[0] + U[i][1] * in[1] + U[i][2] * in[2];
        t[1] = U[i][3] * in[0] + U[i][4] * in[1] + U[i][5] * in[2];
        t[2] = U[i][6] * in[0] + U[i][7] * in[1] + U[i][8] * in[2];
        new_tri(t);
    }
}

int main()
{
    xint seed[3] = {3, 4, 5};

    for (max_peri = 10; max_peri <= 100000000; max_peri *= 10) {
        total = prim = 0;
        new_tri(seed);

        printf( "Up to "FMT": "FMT" triples, "FMT" primitives.\n",
            max_peri, total, prim);
    }
    return 0;
}


Pythagorean triples

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

    // Arguments: predicate, maximum perimeter
    // pythTripleCount :: ((Int, Int, Int) -> Bool) -> Int -> Int
    const pythTripleCount = p =>
        maxPerim => {
            const
                xs = enumFromTo(1)(
                    Math.floor(maxPerim / 2)
                );

            return xs.flatMap(
                x => xs.slice(x).flatMap(
                    y => xs.slice(y).flatMap(
                        z => ((x + y + z <= maxPerim) &&
                            ((x * x) + (y * y) === z * z) &&
                            p(x, y, z)) ? [
                            [x, y, z]
                        ] : []
                    )
                )
            ).length;
        };

    // ---------------------- TEST -----------------------
    const main = () => [10, 100, 1000]
        .map(n => ({
            maxPerimeter: n,
            triples: pythTripleCount(() => true)(n),
            primitives: pythTripleCount(
                (x, y) => gcd(x)(y) === 1
            )(n)
        }));

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

    // abs :: Num -> Num
    const abs =
        // Absolute value of a given number
        // without the sign.
        x => 0 > x ? (
            -x
        ) : x;

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

    // gcd :: Integral a => a -> a -> a
    const gcd = x =>
        y => {
            const zero = x.constructor(0);
            const go = (a, b) =>
                zero === b ? (
                    a
                ) : go(b, a % b);

            return go(abs(x), abs(y));
        };

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


Pythagorean triples

Solution:
from fractions import gcd

def pt1(maxperimeter=100):
    '''
# Naive method
    '''
    trips = []
    for a in range(1, maxperimeter):
        aa = a*a
        for b in range(a, maxperimeter-a+1):
            bb = b*b
            for c in range(b, maxperimeter-b-a+1):
                cc = c*c
                if a+b+c > maxperimeter or cc > aa + bb: break
                if aa + bb == cc:
                    trips.append((a,b,c, gcd(a, b) == 1))
    return trips

def pytrip(trip=(3,4,5),perim=100, prim=1):
    a0, b0, c0 = a, b, c = sorted(trip)
    t, firstprim = set(), prim>0
    while a + b + c <= perim:
        t.add((a, b, c, firstprim>0))
        a, b, c, firstprim = a+a0, b+b0, c+c0, False
    #
    t2 = set()
    for a, b, c, firstprim in t:
        a2, a5, b2, b5, c2, c3, c7 = a*2, a*5, b*2, b*5, c*2, c*3, c*7
        if  a5 - b5 + c7 <= perim:
            t2 |= pytrip(( a - b2 + c2,  a2 - b + c2,  a2 - b2 + c3), perim, firstprim)
        if  a5 + b5 + c7 <= perim:
            t2 |= pytrip(( a + b2 + c2,  a2 + b + c2,  a2 + b2 + c3), perim, firstprim)
        if -a5 + b5 + c7 <= perim:
            t2 |= pytrip((-a + b2 + c2, -a2 + b + c2, -a2 + b2 + c3), perim, firstprim)
    return t | t2

def pt2(maxperimeter=100):
    '''
# Parent/child relationship method:
# http://en.wikipedia.org/wiki/Formulas_for_generating_Pythagorean_triples#XI.
    '''
    trips = pytrip((3,4,5), maxperimeter, 1)
    return trips

def printit(maxperimeter=100, pt=pt1):
    trips = pt(maxperimeter)
    print("  Up to a perimeter of %i there are %i triples, of which %i are primitive"
          % (maxperimeter,
             len(trips),
             len([prim for a,b,c,prim in trips if prim])))

for algo, mn, mx in ((pt1, 250, 2500), (pt2, 500, 20000)):
    print(algo.__doc__)
    for maxperimeter in range(mn, mx+1, mn):
        printit(maxperimeter, algo)


Quaternion type

complex numbers.

A complex number has a real and complex part,   sometimes written as     a + bi,
where     a     and     b     stand for real numbers, and     i     stands for the square root of minus 1.

An example of a complex number might be     -3 + 2i,
where the real part,     a     is     '''-3.0'''     and the complex part,     b     is     '''+2.0'''.

A quaternion has one real part and ''three'' imaginary parts,     i,       j,     and     k.

A quaternion might be written as     a + bi + cj + dk.

In the quaternion numbering system:
:::*     i∙i = j∙j = k∙k = i∙j∙k = -1,         or more simply,
:::*     ii  = jj  = kk  = ijk   = -1.

The order of multiplication is important, as, in general, for two quaternions:
::::     q1     and     q2:         q1q2 ≠ q2q1.

An example of a quaternion might be     1 +2i +3j +4k

There is a list form of notation where just the numbers are shown and the imaginary multipliers    i,       j,     and     k     are assumed by position.

So the example above would be written as     (1, 2, 3, 4)

;Task:
Given the three quaternions and their components:
    q  = (1, 2, 3, 4) = (a,  b,  c,  d)
    q1 = (2, 3, 4, 5) = (a1, b1, c1, d1)
    q2 = (3, 4, 5, 6) = (a2, b2, c2, d2)
And a wholly real number     r = 7.

Create functions   (or classes)   to perform simple maths with quaternions including computing:
# The norm of a quaternion: = \sqrt{a^2 + b^2 + c^2 + d^2}
# The negative of a quaternion:    = (-a, -b, -c, -d)
# The conjugate of a quaternion:    = ( a, -b, -c, -d)
# Addition of a real number     r     and a quaternion     q:      r + q = q + r = (a+r, b, c, d)
# Addition of two quaternions:    q1 + q2 = (a1+a2, b1+b2, c1+c2, d1+d2)
# Multiplication of a real number and a quaternion:    qr = rq = (ar, br, cr, dr)
# Multiplication of two quaternions     q1     and   q2     is given by:    ( a1a2 − b1b2 − c1c2 − d1d2,      a1b2 + b1a2 + c1d2 − d1c2,      a1c2 − b1d2 + c1a2 + d1b2,      a1d2 + b1c2 − c1b2 + d1a2 )
# Show that, for the two quaternions     q1     and     q2:  q1q2 ≠ q2q1

If a language has built-in support for quaternions, then use it.

;C.f.:
*   [[Vector products]]
*   [http://www.maths.tcd.ie/pub/HistMath/People/Hamilton/QLetter/QLetter.pdf On Quaternions];   or on a new System of Imaginaries in Algebra.   By Sir William Rowan Hamilton LL.D, P.R.I.A., F.R.A.S., Hon. M. R. Soc. Ed. and Dub., Hon. or Corr. M. of the Royal or Imperial Academies of St. Petersburgh, Berlin, Turin and Paris, Member of the American Academy of Arts and Sciences, and of other Scientific Societies at Home and Abroad, Andrews' Prof. of Astronomy in the University of Dublin, and Royal Astronomer of Ireland.

Solution:
#include
#include
#include
#include

typedef struct quaternion
{
  double q[4];
} quaternion_t;

quaternion_t *quaternion_new(void)
{
  return malloc(sizeof(quaternion_t));
}

quaternion_t *quaternion_new_set(double q1,
				 double q2,
				 double q3,
				 double q4)
{
  quaternion_t *q = malloc(sizeof(quaternion_t));
  if (q != NULL) {
    q->q[0] = q1; q->q[1] = q2; q->q[2] = q3; q->q[3] = q4;
  }
  return q;
}

void quaternion_copy(quaternion_t *r, quaternion_t *q)
{
  size_t i;

  if (r == NULL || q == NULL) return;
  for(i = 0; i < 4; i++) r->q[i] = q->q[i];
}

double quaternion_norm(quaternion_t *q)
{
  size_t i;
  double r = 0.0;

  if (q == NULL) {
    fprintf(stderr, "NULL quaternion in norm\n");
    return 0.0;
  }

  for(i = 0; i < 4; i++) r += q->q[i] * q->q[i];
  return sqrt(r);
}

void quaternion_neg(quaternion_t *r, quaternion_t *q)
{
  size_t i;

  if (q == NULL || r == NULL) return;
  for(i = 0; i < 4; i++) r->q[i] = -q->q[i];
}

void quaternion_conj(quaternion_t *r, quaternion_t *q)
{
  size_t i;

  if (q == NULL || r == NULL) return;
  r->q[0] = q->q[0];
  for(i = 1; i < 4; i++) r->q[i] = -q->q[i];
}

void quaternion_add_d(quaternion_t *r, quaternion_t *q, double d)
{
  if (q == NULL || r == NULL) return;
  quaternion_copy(r, q);
  r->q[0] += d;
}

void quaternion_add(quaternion_t *r, quaternion_t *a, quaternion_t *b)
{
  size_t i;

  if (r == NULL || a == NULL || b == NULL) return;
  for(i = 0; i < 4; i++) r->q[i] = a->q[i] + b->q[i];
}

void quaternion_mul_d(quaternion_t *r, quaternion_t *q, double d)
{
  size_t i;

  if (r == NULL || q == NULL) return;
  for(i = 0; i < 4; i++) r->q[i] = q->q[i] * d;
}

bool quaternion_equal(quaternion_t *a, quaternion_t *b)
{
  size_t i;

  for(i = 0; i < 4; i++) if (a->q[i] != b->q[i]) return false;
  return true;
}

#define A(N) (a->q[(N)])
#define B(N) (b->q[(N)])
#define R(N) (r->q[(N)])
void quaternion_mul(quaternion_t *r, quaternion_t *a, quaternion_t *b)
{
  size_t i;
  double ri = 0.0;

  if (r == NULL || a == NULL || b == NULL) return;
  R(0) = A(0)*B(0) - A(1)*B(1) - A(2)*B(2) - A(3)*B(3);
  R(1) = A(0)*B(1) + A(1)*B(0) + A(2)*B(3) - A(3)*B(2);
  R(2) = A(0)*B(2) - A(1)*B(3) + A(2)*B(0) + A(3)*B(1);
  R(3) = A(0)*B(3) + A(1)*B(2) - A(2)*B(1) + A(3)*B(0);
}
#undef A
#undef B
#undef R

void quaternion_print(quaternion_t *q)
{
  if (q == NULL) return;
  printf("(%lf, %lf, %lf, %lf)\n",
	 q->q[0], q->q[1], q->q[2], q->q[3]);
}


Quaternion type

Solution:
var Quaternion = (function() {
    // The Q() function takes an array argument and changes it
    // prototype so that it becomes a Quaternion instance.  This is
    // scoped only for prototype member access.
    function Q(a) {
	a.__proto__ = proto;
	return a;
    }

    // Actual constructor.  This constructor converts its arguments to
    // an array, then that array to a Quaternion instance, then
    // returns that instance.  (using "new" with this constructor is
    // optional)
    function Quaternion() {
	return Q(Array.prototype.slice.call(arguments, 0, 4));
    }

    // Prototype for all Quaternions
    const proto = {
	// Inherits from a 4-element Array
	__proto__ : [0,0,0,0],

	// Properties -- In addition to Array[0..3] access, we
	// also define matching a, b, c, and d properties
	get a() this[0],
	get b() this[1],
	get c() this[2],
	get d() this[3],

	// Methods
	norm : function() Math.sqrt(this.map(function(x) x*x).reduce(function(x,y) x+y)),
	negate : function() Q(this.map(function(x) -x)),
	conjugate : function() Q([ this[0] ].concat(this.slice(1).map(function(x) -x))),
	add : function(x) {
	    if ("number" === typeof x) {
		return Q([ this[0] + x ].concat(this.slice(1)));
	    } else {
		return Q(this.map(function(v,i) v+x[i]));
	    }
	},
	mul : function(r) {
	    var q = this;
	    if ("number" === typeof r) {
		return Q(q.map(function(e) e*r));
	    } else {
		return Q([ q[0] * r[0] - q[1] * r[1] - q[2] * r[2] - q[3] * r[3],
			   q[0] * r[1] + q[1] * r[0] + q[2] * r[3] - q[3] * r[2],
			   q[0] * r[2] - q[1] * r[3] + q[2] * r[0] + q[3] * r[1],
			   q[0] * r[3] + q[1] * r[2] - q[2] * r[1] + q[3] * r[0] ]);
	    }
	},
	equals : function(q) this.every(function(v,i) v === q[i]),
	toString : function() (this[0] + " + " + this[1] + "i + "+this[2] + "j + " + this[3] + "k").replace(/\+ -/g, '- ')
    };

    Quaternion.prototype = proto;
    return Quaternion;
})();


Quaternion type

Solution:
from collections import namedtuple
import math

class Q(namedtuple('Quaternion', 'real, i, j, k')):
    'Quaternion type: Q(real=0.0, i=0.0, j=0.0, k=0.0)'

    __slots__ = ()

    def __new__(_cls, real=0.0, i=0.0, j=0.0, k=0.0):
        'Defaults all parts of quaternion to zero'
        return super().__new__(_cls, float(real), float(i), float(j), float(k))

    def conjugate(self):
        return Q(self.real, -self.i, -self.j, -self.k)

    def _norm2(self):
        return sum( x*x for x in self)

    def norm(self):
        return math.sqrt(self._norm2())

    def reciprocal(self):
        n2 = self._norm2()
        return Q(*(x / n2 for x in self.conjugate()))

    def __str__(self):
        'Shorter form of Quaternion as string'
        return 'Q(%g, %g, %g, %g)' % self

    def __neg__(self):
        return Q(-self.real, -self.i, -self.j, -self.k)

    def __add__(self, other):
        if type(other) == Q:
            return Q( *(s+o for s,o in zip(self, other)) )
        try:
            f = float(other)
        except:
            return NotImplemented
        return Q(self.real + f, self.i, self.j, self.k)

    def __radd__(self, other):
        return Q.__add__(self, other)

    def __mul__(self, other):
        if type(other) == Q:
            a1,b1,c1,d1 = self
            a2,b2,c2,d2 = other
            return Q(
                 a1*a2 - b1*b2 - c1*c2 - d1*d2,
                 a1*b2 + b1*a2 + c1*d2 - d1*c2,
                 a1*c2 - b1*d2 + c1*a2 + d1*b2,
                 a1*d2 + b1*c2 - c1*b2 + d1*a2 )
        try:
            f = float(other)
        except:
            return NotImplemented
        return Q(self.real * f, self.i * f, self.j * f, self.k * f)

    def __rmul__(self, other):
        return Q.__mul__(self, other)

    def __truediv__(self, other):
        if type(other) == Q:
            return self.__mul__(other.reciprocal())
        try:
            f = float(other)
        except:
            return NotImplemented
        return Q(self.real / f, self.i / f, self.j / f, self.k / f)

    def __rtruediv__(self, other):
        return other * self.reciprocal()

    __div__, __rdiv__ = __truediv__, __rtruediv__

Quaternion = Q

q  = Q(1, 2, 3, 4)
q1 = Q(2, 3, 4, 5)
q2 = Q(3, 4, 5, 6)
r  = 7


Quine

A quine is a self-referential program that can,
without any external access, output its own source.

A   '''quine'''   (named after Willard Van Orman Quine)   is also known as:
::*   ''self-reproducing automata''        (1972)
::*   ''self-replicating program''                             or   ''self-replicating computer program''
::*   ''self-reproducing program''                                  or   ''self-reproducing computer program''
::*   ''self-copying program''                       or   ''self-copying computer program''

It is named after the philosopher and logician
who studied self-reference and quoting in natural language,
as for example in the paradox "'Yields falsehood when preceded by its quotation' yields falsehood when preceded by its quotation."

"Source" has one of two meanings. It can refer to the text-based program source.
For languages in which program source is represented as a data structure, "source" may refer to the data structure: quines in these languages fall into two categories: programs which print a textual representation of themselves, or expressions which evaluate to a data structure which is equivalent to that expression.

The usual way to code a quine works similarly to this paradox: The program consists of two identical parts, once as plain code and once ''quoted'' in some way (for example, as a character string, or a literal data structure). The plain code then accesses the quoted code and prints it out twice, once unquoted and once with the proper quotation marks added. Often, the plain code and the quoted code have to be nested.

;Task:
Write a program that outputs its own source code in this way. If the language allows it, you may add a variant that accesses the code directly. You are not allowed to read any external files with the source code. The program should also contain some sort of self-reference, so constant expressions which return their own value which some top-level interpreter will print out.  Empty programs producing no output are not allowed.

There are several difficulties that one runs into when writing a quine, mostly dealing with quoting:
* Part of the code usually needs to be stored as a string or structural literal in the language, which needs to be quoted somehow. However, including quotation marks in the string literal itself would be troublesome because it requires them to be escaped, which then necessitates the escaping character (e.g. a backslash) in the string, which itself usually needs to be escaped, and so on.
** Some languages have a function for getting the "source code representation" of a string (i.e. adds quotation marks, etc.); in these languages, this can be used to circumvent the quoting problem.
** Another solution is to construct the quote character from its [[character code]], without having to write the quote character itself. Then the character is inserted into the string at the appropriate places. The ASCII code for double-quote is 34, and for single-quote is 39.
* Newlines in the program may have to be reproduced as newlines in the string, which usually requires some kind of escape sequence (e.g. "\n"). This causes the same problem as above, where the escaping character needs to itself be escaped, etc.
** If the language has a way of getting the "source code representation", it usually handles the escaping of characters, so this is not a problem.
** Some languages allow you to have a string literal that spans multiple lines, which embeds the newlines into the string without escaping.
** Write the entire program on one line, for free-form languages (as you can see for some of the solutions here, they run off the edge of the screen), thus removing the need for newlines. However, this may be unacceptable as some languages require a newline at the end of the file; and otherwise it is still generally good style to have a newline at the end of a file. (The task is not clear on whether a newline is required at the end of the file.) Some languages have a print statement that appends a newline; which solves the newline-at-the-end issue; but others do not.

'''Next to the Quines presented here, many other versions can be found on the [http://www.nyx.net/~gthompso/quine.htm Quine] page.'''

;Related task:
:*   [https://rosettacode.org/wiki/Print_itself print itself].

Solution:
#include

static char sym[] = "\n\t\\\"";

int main(void) {
	const char *code = "#include %c%cstatic char sym[] = %c%cn%ct%c%c%c%c%c;%c%cint main(void) {%c%cconst char *code = %c%s%c;%c%cprintf(code, sym[0], sym[0], sym[3], sym[2], sym[2], sym[2], sym[2], sym[2], sym[3], sym[3], sym[0], sym[0], sym[0], sym[1], sym[3], code, sym[3], sym[0], sym[1], sym[0], sym[0], sym[1], sym[0], sym[0]);%c%c%creturn 0;%c}%c";
	printf(code, sym[0], sym[0], sym[3], sym[2], sym[2], sym[2], sym[2], sym[2], sym[3], sym[3], sym[0], sym[0], sym[0], sym[1], sym[3], code, sym[3], sym[0], sym[1], sym[0], sym[0], sym[1], sym[0], sym[0]);

	return 0;
}


Quine


Quine

Solution: import sys,inspect;sys.stdout.write(inspect.getsource(inspect.currentframe()))


Quine

Solution: x = 'x = {!r};print(x.format(x))';print(x.format(x))


Quine

Solution:
data = (
	'ZGF0YSA9ICgKCSc=',
	'JywKCSc=',
	'JwopCnByZWZpeCwgc2VwYXJhdG9yLCBzdWZmaXggPSAoZC5kZWNvZGUoJ2Jhc2U2NCcpIGZvciBkIGluIGRhdGEpCnByaW50IHByZWZpeCArIGRhdGFbMF0gKyBzZXBhcmF0b3IgKyBkYXRhWzFdICsgc2VwYXJhdG9yICsgZGF0YVsyXSArIHN1ZmZpeA=='
)
prefix, separator, suffix = (d.decode('base64') for d in data)
print prefix + data[0] + separator + data[1] + separator + data[2] + suffix


RIPEMD-160

'''RIPEMD-160''' is another hash function; it computes a 160-bit message digest.

There is a [http://homes.esat.kuleuven.be/~bosselae/ripemd160.html RIPEMD-160 home page], with test vectors and [http://www.esat.kuleuven.be/~bosselae/ripemd/rmd160.txt pseudocode for RIPEMD-160].
For padding the message, RIPEMD-160 acts like [[MD4]] (RFC 1320).

Find the RIPEMD-160 message digest of a string of [[octet]]s.
Use the ASCII encoded string “Rosetta Code”.
You may either call an RIPEMD-160 library, or implement RIPEMD-160 in your language.

Solution:
#ifndef RMDsize
#define RMDsize 160
#endif

#include
#include
#include
#include
#if RMDsize == 128
#include "rmd128.h"
#include "rmd128.c"  /* Added to remove errors during compilation */
#elif RMDsize == 160
#include "rmd160.h"
#include "rmd160.c"  /* Added to remove errors during compilation */
#endif


RIPEMD-160

Solution:
Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import hashlib
>>> h = hashlib.new('ripemd160')
>>> h.update(b"Rosetta Code")
>>> h.hexdigest()
'b3be159860842cebaa7174c8fff0aa9e50a5199f'
>>>


RPG attributes generator

[[Category:Simple]]
'''RPG'''   =   Role Playing Game.

You're running a tabletop RPG, and your players are creating characters.

Each character has six core attributes: strength, dexterity, constitution, intelligence, wisdom, and charisma.

One way of generating values for these attributes is to roll four, 6-sided dice (d6) and sum the three highest rolls, discarding the lowest roll.

Some players like to assign values to their attributes in the order they're rolled.

To ensure generated characters don't put players at a disadvantage, the following requirements must be satisfied:

* The total of all character attributes must be at least 75.
* At least two of the attributes must be at least 15.

However, this can require a lot of manual dice rolling. A programatic solution would be much faster.

;Task:
Write a program that:
# Generates 4 random, whole values between 1 and 6.
# Saves the sum of the 3 largest values.
# Generates a total of 6 values this way.
# Displays the total, and all 6 values once finished.

* The order in which each value was generated must be preserved.
* The total of all 6 values must be at least 75.
* At least 2 of the values must be 15 or more.

Solution:
#include
#include
#include

int compareInts(const void *i1, const void *i2) {
    int a = *((int *)i1);
    int b = *((int *)i2);
    return a - b;
}

int main() {
    int i, j, nsum, vsum, vcount, values[6], numbers[4];
    srand(time(NULL));
    for (;;) {
        vsum = 0;
        for (i = 0; i < 6; ++i) {
            for (j = 0; j < 4; ++j) {
                numbers[j] = 1 + rand() % 6;
            }
            qsort(numbers, 4, sizeof(int), compareInts);
            nsum = 0;
            for (j = 1; j < 4; ++j) {
                nsum += numbers[j];
            }
            values[i] = nsum;
            vsum += values[i];
        }
        if (vsum < 75) continue;
        vcount = 0;
        for (j = 0; j < 6; ++j) {
            if (values[j] >= 15) vcount++;
        }
        if (vcount < 2) continue;
        printf("The 6 random numbers generated are:\n");
        printf("[");
        for (j = 0; j < 6; ++j) printf("%d ", values[j]);
        printf("\b]\n");
        printf("\nTheir sum is %d and %d of them are >= 15\n", vsum, vcount);
        break;
    }
    return 0;
}


RPG attributes generator

Solution:
import random
random.seed()
attributes_total = 0
count = 0

while attributes_total < 75 or count < 2:
    attributes = []

    for attribute in range(0, 6):
        rolls = []

        for roll in range(0, 4):
            result = random.randint(1, 6)
            rolls.append(result)

        sorted_rolls = sorted(rolls)
        largest_3 = sorted_rolls[1:]
        rolls_total = sum(largest_3)

        if rolls_total >= 15:
            count += 1

        attributes.append(rolls_total)

    attributes_total = sum(attributes)

print(attributes_total, attributes)


Ramanujan's constant

Calculate Ramanujan's constant (as described on the [http://oeis.org/wiki/Ramanujan%27s_constant OEIS site]) with at least
32 digits of precision, by the method of your choice.  Optionally, if using the 𝑒**(π*√''x'') approach,
show that when evaluated with the last four [https://en.wikipedia.org/wiki/Heegner_number Heegner numbers]
the result is ''almost'' an integer.

Solution:
from mpmath import mp
heegner = [19,43,67,163]
mp.dps = 50
x = mp.exp(mp.pi*mp.sqrt(163))
print("calculated Ramanujan's constant: {}".format(x))
print("Heegner numbers yielding 'almost' integers:")
for i in heegner:
    print(" for {}: {} ~ {} error: {}".format(str(i),mp.exp(mp.pi*mp.sqrt(i)),round(mp.exp(mp.pi*mp.sqrt(i))),(mp.pi*mp.sqrt(i)) - round(mp.pi*mp.sqrt(i))))


Ramer-Douglas-Peucker line simplification

The   '''Ramer–Douglas–Peucker'''   algorithm is a line simplification algorithm for reducing the number of points used to define its shape.

;Task:
Using the   '''Ramer–Douglas–Peucker'''   algorithm, simplify the   2D   line defined by the points:
    (0,0)  (1,0.1)  (2,-0.1)  (3,5)  (4,6)  (5,7)  (6,8.1)  (7,9)  (8,9)  (9,9)

The error threshold to be used is:   '''1.0'''.

Display the remaining points here.

;Reference:
:*   the Wikipedia article:   [https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm Ramer-Douglas-Peucker algorithm].

Solution:
#include
#include
#include

typedef struct point_tag {
    double x;
    double y;
} point_t;

// Returns the distance from point p to the line between p1 and p2
double perpendicular_distance(point_t p, point_t p1, point_t p2) {
    double dx = p2.x - p1.x;
    double dy = p2.y - p1.y;
    double d = sqrt(dx * dx + dy * dy);
    return fabs(p.x * dy - p.y * dx + p2.x * p1.y - p2.y * p1.x)/d;
}

// Simplify an array of points using the Ramer–Douglas–Peucker algorithm.
// Returns the number of output points.
size_t douglas_peucker(const point_t* points, size_t n, double epsilon,
                       point_t* dest, size_t destlen) {
    assert(n >= 2);
    assert(epsilon >= 0);
    double max_dist = 0;
    size_t index = 0;
    for (size_t i = 1; i + 1 < n; ++i) {
        double dist = perpendicular_distance(points[i], points[0], points[n - 1]);
        if (dist > max_dist) {
            max_dist = dist;
            index = i;
        }
    }
    if (max_dist > epsilon) {
        size_t n1 = douglas_peucker(points, index + 1, epsilon, dest, destlen);
        if (destlen >= n1 - 1) {
            destlen -= n1 - 1;
            dest += n1 - 1;
        } else {
            destlen = 0;
        }
        size_t n2 = douglas_peucker(points + index, n - index, epsilon, dest, destlen);
        return n1 + n2 - 1;
    }
    if (destlen >= 2) {
        dest[0] = points[0];
        dest[1] = points[n - 1];
    }
    return 2;
}

void print_points(const point_t* points, size_t n) {
    for (size_t i = 0; i < n; ++i) {
        if (i > 0)
            printf(" ");
        printf("(%g, %g)", points[i].x, points[i].y);
    }
    printf("\n");
}

int main() {
    point_t points[] = {
        {0,0}, {1,0.1}, {2,-0.1}, {3,5}, {4,6},
        {5,7}, {6,8.1}, {7,9}, {8,9}, {9,9}
    };
    const size_t len = sizeof(points)/sizeof(points[0]);
    point_t out[len];
    size_t n = douglas_peucker(points, len, 1.0, out, len);
    print_points(out, n);
    return 0;
}


Solution:
/**
 * @typedef {{
 *    x: (!number),
 *    y: (!number)
 * }}
 */
let pointType;

/**
 * @param {!Array} l
 * @param {number} eps
 */
const RDP = (l, eps) => {
  const last = l.length - 1;
  const p1 = l[0];
  const p2 = l[last];
  const x21 = p2.x - p1.x;
  const y21 = p2.y - p1.y;

  const [dMax, x] = l.slice(1, last)
      .map(p => Math.abs(y21 * p.x - x21 * p.y + p2.x * p1.y - p2.y * p1.x))
      .reduce((p, c, i) => {
        const v = Math.max(p[0], c);
        return [v, v === p[0] ? p[1] : i + 1];
      }, [-1, 0]);

  if (dMax > eps) {
    return [...RDP(l.slice(0, x + 1), eps), ...RDP(l.slice(x), eps).slice(1)];
  }
  return [l[0], l[last]]
};

const points = [
  {x: 0, y: 0},
  {x: 1, y: 0.1},
  {x: 2, y: -0.1},
  {x: 3, y: 5},
  {x: 4, y: 6},
  {x: 5, y: 7},
  {x: 6, y: 8.1},
  {x: 7, y: 9},
  {x: 8, y: 9},
  {x: 9, y: 9}];

console.log(RDP(points, 1));


Solution:
from __future__ import print_function
from shapely.geometry import LineString

if __name__=="__main__":
	line = LineString([(0,0),(1,0.1),(2,-0.1),(3,5),(4,6),(5,7),(6,8.1),(7,9),(8,9),(9,9)])
	print (line.simplify(1.0, preserve_topology=False))


Random Latin squares

A Latin square of size n is an arrangement of n symbols  in an n-by-n square in such a way that each row and column has each symbol appearing exactly once.
For the purposes of this task, a random Latin square of size n is a Latin square constructed or generated by a probabilistic procedure such that the probability of any particular Latin square of size n being produced is non-zero.

;Example n=4 randomised Latin square:
0 2 3 1
2 1 0 3
3 0 1 2
1 3 2 0

;Task:
# Create a function/routine/procedure/method/... that given n generates a randomised Latin square of size n.
# Use the function to generate ''and show here'', two randomly generated squares of size 5.

;Note:
Strict ''uniformity'' in the random generation is a hard problem and '''not''' a requirement of the task.

;Related tasks:
* [[Latin Squares in reduced form/Randomizing using Jacobson and Matthews’ Technique]]
* [[Latin Squares in reduced form]]

;Reference:
* Wikipedia: Latin square
* OEIS: A002860

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

// low <= num < high
int randInt(int low, int high) {
    return (rand() % (high - low)) + low;
}

// shuffle an array of n elements
void shuffle(int *const array, const int n) {
    if (n > 1) {
        int i;
        for (i = 0; i < n - 1; i++) {
            int j = randInt(i, n);

            int t = array[i];
            array[i] = array[j];
            array[j] = t;
        }
    }
}

// print an n * n array
void printSquare(const int *const latin, const int n) {
    int i, j;
    for (i = 0; i < n; i++) {
        printf("[");
        for (j = 0; j < n; j++) {
            if (j > 0) {
                printf(", ");
            }
            printf("%d", latin[i * n + j]);
        }
        printf("]\n");
    }
    printf("\n");
}

void latinSquare(const int n) {
    int *latin, *used;
    int i, j, k;

    if (n <= 0) {
        printf("[]\n");
        return;
    }

    // allocate
    latin = (int *)malloc(n * n * sizeof(int));
    if (!latin) {
        printf("Failed to allocate memory.");
        return;
    }

    // initialize
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            latin[i * n + j] = j;
        }
    }

    // first row
    shuffle(latin, n);

    // middle row(s)
    for (i = 1; i < n - 1; i++) {
        bool shuffled = false;

        while (!shuffled) {
            shuffle(&latin[i * n], n);

            for (k = 0; k < i; k++) {
                for (j = 0; j < n; j++) {
                    if (latin[k * n + j] == latin[i * n + j]) {
                        goto shuffling;
                    }
                }
            }
            shuffled = true;

        shuffling: {}
        }
    }

    //last row
    used = (int *)malloc(n * sizeof(int));
    for (j = 0; j < n; j++) {
        memset(used, 0, n * sizeof(int));
        for (i = 0; i < n - 1; i++) {
            used[latin[i * n + j]] = 1;
        }
        for (k = 0; k < n; k++) {
            if (used[k] == 0) {
                latin[(n - 1) * n + j] = k;
                break;
            }
        }
    }
    free(used);

    // print the result
    printSquare(latin, n);
    free(latin);
}

int main() {
    // initialze the random number generator
    srand((unsigned int)time((time_t)0));

    latinSquare(5);
    latinSquare(5);
    latinSquare(10);

    return 0;
}


Random Latin squares

Solution:
from random import choice, shuffle
from copy import deepcopy

def rls(n):
    if n <= 0:
        return []
    else:
        symbols = list(range(n))
        square = _rls(symbols)
        return _shuffle_transpose_shuffle(square)

def _shuffle_transpose_shuffle(matrix):
    square = deepcopy(matrix)
    shuffle(square)
    trans = list(zip(*square))
    shuffle(trans)
    return trans

def _rls(symbols):
    n = len(symbols)
    if n == 1:
        return [symbols]
    else:
        sym = choice(symbols)
        symbols.remove(sym)
        square = _rls(symbols)
        square.append(square[0].copy())
        for i in range(n):
            square[i].insert(i, sym)
        return square

def _to_text(square):
    if square:
        width = max(len(str(sym)) for row in square for sym in row)
        txt = '\n'.join(' '.join(f"{sym:>{width}}" for sym in row)
                        for row in square)
    else:
        txt = ''
    return txt

def _check(square):
    transpose = list(zip(*square))
    assert _check_rows(square) and _check_rows(transpose), \
        "Not a Latin square"

def _check_rows(square):
    if not square:
        return True
    set_row0 = set(square[0])
    return all(len(row) == len(set(row)) and set(row) == set_row0
               for row in square)

if __name__ == '__main__':
    for i in [3, 3,  5, 5, 12]:
        square = rls(i)
        print(_to_text(square))
        _check(square)
        print()


Random number generator (device)

[[Category:Input Output]]

;Task:
If your system has a means to generate random numbers involving not only a software algorithm   (like the /dev/urandom devices in Unix),   then:

show how to obtain a random 32-bit number from that mechanism.

;Related task
* [[Random_number_generator_(included)]]

Solution:
#include
#include

#define RANDOM_PATH "/dev/urandom"

int main(void)
{
        unsigned char buf[4];
        unsigned long v;
        FILE *fin;

        if ((fin = fopen(RANDOM_PATH, "r")) == NULL) {
                fprintf(stderr, "%s: unable to open file\n", RANDOM_PATH);
                return EXIT_FAILURE;
        }
        if (fread(buf, 1, sizeof buf, fin) != sizeof buf) {
                fprintf(stderr, "%s: not enough bytes (expected %u)\n",
                        RANDOM_PATH, (unsigned) sizeof buf);
                return EXIT_FAILURE;
        }
        fclose(fin);
        v = buf[0] | buf[1] << 8UL | buf[2] << 16UL | buf[3] << 24UL;
        printf("%lu\n", v);
        return 0;
}


Random number generator (device)

Solution:
#include   /* printf */
#include
#include  /* CryptAcquireContext, CryptGenRandom */

int
main()
{
  HCRYPTPROV p;
  ULONG i;

  if (CryptAcquireContext(&p, NULL, NULL,
      PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == FALSE) {
    fputs("CryptAcquireContext failed.\n", stderr);
    return 1;
  }
  if (CryptGenRandom(p, sizeof i, (BYTE *)&i) == FALSE) {
    fputs("CryptGenRandom failed.\n", stderr);
    return 1;
  }
  printf("%lu\n", i);
  CryptReleaseContext(p, 0);
  return 0;
}


Random number generator (device)

Solution:
#include
#include

/*
   (C) 2020 J.G.A. Debaere, all rights reserved 2020/10/29

    Put into Public Domain for individuals only

    Tested with NIST, Diehard, Diehard 3.31

    gcc -lm ./jpsrand_f.c -o ./jpsrand_f.o

    dieharder -a -f /tmp/tmp.bin

	I consider it TRNG,

	using Time, Hardddisk and Memory as the hardware component

	No warranty of any kind, "AS IS"

	Last time I tested  ( 2021/07/07 ) with dieharder:

	rgb_bitdist		|   8|    100000|     100|0.99716738|   WEAK
	rgb_lagged_sum	|   3|   1000000|     100|0.99661184|   WEAK

	Out of 114 tests, rest PASSED

        Obviously, it changes per run :)

*/

unsigned int  jps_rand()
{
    /* (C) 2020 J.G.A. Debaere, all rights reserved */

    #include

    #include

    struct timeval current_time ;

    DIR *folder ;

    struct dirent *en ;

    folder = opendir ( "." ) ;

    while ( ( folder ) && ( en = readdir ( folder ) ) != NULL )

        asm ( "nop" ) ;

    closedir ( folder ) ;

    gettimeofday( ¤t_time, NULL ) ;

    unsigned int t = ( current_time.tv_sec * current_time.tv_usec / 17.17 ) ;

    return t ;
}

int main()
{
    FILE * f1;

    f1 = fopen("/tmp/tmp.bin", "wb");

    unsigned int t = ( unsigned int ) jps_rand() ;

    for ( unsigned int k = 0;  k < 40000000 ; k++ )
    {
        t = jps_rand () ;

        fwrite ( &t, sizeof( unsigned int ),  1, f1 ) ;
    }

    fflush(f1);

    fclose(f1);

    return 0;
}


Random number generator (device)

Solution:
import random
rand = random.SystemRandom()
rand.randint(1,10)


Random sentence from book

* Read in the book "[http://www.gutenberg.org/files/36/36-0.txt The War of the Worlds]", by H. G. Wells.
* Skip to the start of the book, proper.
* Remove extraneous punctuation, but keep at least sentence-ending punctuation characters . ! and ?
* Keep account of what words follow words and how many times it is seen, (treat sentence terminators as words too).
* Keep account of what words follow ''two'' words and how many times it is seen, (again treating sentence terminators as words too).
* Assume that a sentence starts with a not to be shown full-stop character then ''use a weighted random choice'' of the possible words that may follow a full-stop to add to the sentence.
* Then repeatedly add words to the sentence based on weighted random choices of what words my follow the last two words to extend the sentence.
* Stop after adding a sentence ending punctuation character.
* Tidy and then print the sentence.

Show examples of random sentences generated.

;Related task
* [[Markov_chain_text_generator]]

Solution:
from urllib.request import urlopen
import re
from string import punctuation
from collections import Counter, defaultdict
import random

# The War of the Worlds, by H. G. Wells
text_url = 'http://www.gutenberg.org/files/36/36-0.txt'
text_start = 'No one would have believed'

sentence_ending = '.!?'
sentence_pausing = ',;:'

def read_book(text_url, text_start) -> str:
    with urlopen(text_url) as book:
        text = book.read().decode('utf-8')
    return text[text.index(text_start):]

def remove_punctuation(text: str, keep=sentence_ending+sentence_pausing)-> str:
    "Remove punctuation, keeping some"
    to_remove = ''.join(set(punctuation) - set(keep))
    text = text.translate(str.maketrans(to_remove, ' ' * len(to_remove))).strip()
    text = re.sub(fr"[^a-zA-Z0-9{keep}\n ]+", ' ', text)
    # Remove duplicates and put space around remaining punctuation
    if keep:
        text = re.sub(f"([{keep}])+", r" \1 ", text).strip()
    if text[-1] not in sentence_ending:
        text += ' .'
    return text.lower()

def word_follows_words(txt_with_pauses_and_endings):
    "return dict of freq of words following one/two words"
    words = ['.'] + txt_with_pauses_and_endings.strip().split()

    # count of what word follows this
    word2next = defaultdict(lambda :defaultdict(int))
    word2next2 = defaultdict(lambda :defaultdict(int))
    for lh, rh in zip(words, words[1:]):
        word2next[lh][rh] += 1
    for lh, mid, rh in zip(words, words[1:], words[2:]):
        word2next2[(lh, mid)][rh] += 1

    return dict(word2next), dict(word2next2)

def gen_sentence(word2next, word2next2) -> str:

    s = ['.']
    s += random.choices(*zip(*word2next[s[-1]].items()))
    while True:
        s += random.choices(*zip(*word2next2[(s[-2], s[-1])].items()))
        if s[-1] in sentence_ending:
            break

    s  = ' '.join(s[1:]).capitalize()
    s = re.sub(fr" ([{sentence_ending+sentence_pausing}])", r'\1', s)
    s = re.sub(r" re\b", "'re", s)
    s = re.sub(r" s\b", "'s", s)
    s = re.sub(r"\bi\b", "I", s)

    return s

if __name__ == "__main__":
    txt_with_pauses_and_endings = remove_punctuation(read_book(text_url, text_start))
    word2next, word2next2 = word_follows_words(txt_with_pauses_and_endings)
    #%%
    sentence = gen_sentence(word2next, word2next2)
    print(sentence)


Range consolidation

Define a range of numbers   '''R''',   with bounds   '''b0'''   and   '''b1'''   covering all numbers ''between and including both bounds''.

That range can be shown as:
::::::::: '''[b0, b1]'''
::::::::    or equally as:
::::::::: '''[b1, b0]'''

Given two ranges, the act of consolidation between them compares the two ranges:
*   If one range covers all of the other then the result is that encompassing range.
*   If the ranges touch or intersect then the result is   ''one''   new single range covering the overlapping ranges.
*   Otherwise the act of consolidation is to return the two non-touching ranges.

Given   '''N'''   ranges where   '''N > 2'''   then the result is the same as repeatedly replacing all combinations of two ranges by their consolidation until no further consolidation between range pairs is possible.

If   '''N < 2'''   then range consolidation has no strict meaning and the input can be returned.

;Example 1:
:   Given the two ranges   '''[1, 2.5]'''   and   '''[3, 4.2]'''   then
:   there is no common region between the ranges and the result is the same as the input.

;Example 2:
:   Given the two ranges   '''[1, 2.5]'''   and   '''[1.8, 4.7]'''   then
:   there is :   an overlap   '''[2.5, 1.8]'''   between the ranges and
:   the result is the single range   '''[1, 4.7]'''.
:   Note that order of bounds in a range is not (yet) stated.

;Example 3:
:   Given the two ranges   '''[6.1, 7.2]'''   and   '''[7.2, 8.3]'''   then
:   they touch at   '''7.2'''   and
:   the result is the single range   '''[6.1, 8.3]'''.

;Example 4:
:   Given the three ranges   '''[1, 2]'''   and   '''[4, 8]'''   and   '''[2, 5]'''
:   then there is no intersection of the ranges   '''[1, 2]'''   and   '''[4, 8]'''
:   but the ranges   '''[1, 2]'''   and   '''[2, 5]'''   overlap and
:   consolidate to produce the range   '''[1, 5]'''.
:   This range, in turn, overlaps the other range   '''[4, 8]''',   and
:   so consolidates to the final output of the single range   '''[1, 8]'''.

;Task:
Let a normalized range display show the smaller bound to the left;   and show the
range with the smaller lower bound to the left of other ranges when showing multiple ranges.

Output the ''normalized'' result of applying consolidation to these five sets of ranges:
            [1.1, 2.2]
            [6.1, 7.2], [7.2, 8.3]
            [4, 3], [2, 1]
            [4, 3], [2, 1], [-1, -2], [3.9, 10]
            [1, 3], [-6, -1], [-4, -5], [8, 2], [-6, -6]
Show all output here.

;See also:
* [[Set consolidation]]
* [[Set of real numbers]]

Solution:
#include
#include

typedef struct range_tag {
    double low;
    double high;
} range_t;

void normalize_range(range_t* range) {
    if (range->high < range->low) {
        double tmp = range->low;
        range->low = range->high;
        range->high = tmp;
    }
}

int range_compare(const void* p1, const void* p2) {
    const range_t* r1 = p1;
    const range_t* r2 = p2;
    if (r1->low < r2->low)
        return -1;
    if (r1->low > r2->low)
        return 1;
    if (r1->high < r2->high)
        return -1;
    if (r1->high > r2->high)
        return 1;
    return 0;
}

void normalize_ranges(range_t* ranges, size_t count) {
    for (size_t i = 0; i < count; ++i)
        normalize_range(&ranges[i]);
    qsort(ranges, count, sizeof(range_t), range_compare);
}

// Consolidates an array of ranges in-place. Returns the
// number of ranges after consolidation.
size_t consolidate_ranges(range_t* ranges, size_t count) {
    normalize_ranges(ranges, count);
    size_t out_index = 0;
    for (size_t i = 0; i < count; ) {
        size_t j = i;
        while (++j < count && ranges[j].low <= ranges[i].high) {
            if (ranges[i].high < ranges[j].high)
                ranges[i].high = ranges[j].high;
        }
        ranges[out_index++] = ranges[i];
        i = j;
    }
    return out_index;
}

void print_range(const range_t* range) {
    printf("[%g, %g]", range->low, range->high);
}

void print_ranges(const range_t* ranges, size_t count) {
    if (count == 0)
        return;
    print_range(&ranges[0]);
    for (size_t i = 1; i < count; ++i) {
        printf(", ");
        print_range(&ranges[i]);
    }
}

void test_consolidate_ranges(range_t* ranges, size_t count) {
    print_ranges(ranges, count);
    printf(" -> ");
    count = consolidate_ranges(ranges, count);
    print_ranges(ranges, count);
    printf("\n");
}

#define LENGTHOF(a) sizeof(a)/sizeof(a[0])

int main() {
    range_t test1[] = { {1.1, 2.2} };
    range_t test2[] = { {6.1, 7.2}, {7.2, 8.3} };
    range_t test3[] = { {4, 3}, {2, 1} };
    range_t test4[] = { {4, 3}, {2, 1}, {-1, -2}, {3.9, 10} };
    range_t test5[] = { {1, 3}, {-6, -1}, {-4, -5}, {8, 2}, {-6, -6} };
    test_consolidate_ranges(test1, LENGTHOF(test1));
    test_consolidate_ranges(test2, LENGTHOF(test2));
    test_consolidate_ranges(test3, LENGTHOF(test3));
    test_consolidate_ranges(test4, LENGTHOF(test4));
    test_consolidate_ranges(test5, LENGTHOF(test5));
    return 0;
}