Padovan n-step number sequences

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

    // ---------- PADOVAN N-STEP NUMBER SERIES -----------

    // padovans :: Int -> [Int]
    const padovans = n => {
        // Padovan number series of step N
        const recurrence = ns => [
            ns[0],
            ns.slice(1).concat(
                sum(take(n)(ns))
            )
        ];

        return 0 > n ? (
            []
        ) : unfoldr(recurrence)(
            take(1 + n)(
                3 > n ? (
                    repeat(1)
                ) : padovans(n - 1)
            )
        );
    };

    // ---------------------- TEST -----------------------
    // main :: IO ()
    const main = () =>
        fTable("Padovan N-step series:")(str)(
            xs => xs.map(
                compose(justifyRight(4)(" "), str)
            )
            .join("")
        )(
            compose(take(15), padovans)
        )(
            enumFromTo(2)(8)
        );

    // --------------------- GENERIC ---------------------

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (...fs) =>
        // A function defined by the right-to-left
        // composition of all the functions in fs.
        fs.reduce(
            (f, g) => x => f(g(x)),
            x => x
        );

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

    // repeat :: a -> Generator [a]
    const repeat = function* (x) {
        while (true) {
            yield x;
        }
    };

    // sum :: [Num] -> Num
    const sum = xs =>
        // The numeric sum of all values in xs.
        xs.reduce((a, x) => a + x, 0);

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = n =>
        // The first n elements of a list,
        // string of characters, or stream.
        xs => "GeneratorFunction" !== xs
        .constructor.constructor.name ? (
            xs.slice(0, n)
        ) : [].concat(...Array.from({
            length: n
        }, () => {
            const x = xs.next();

            return x.done ? [] : [x.value];
        }));

    // unfoldr :: (b -> Maybe (a, b)) -> b -> Gen [a]
    const unfoldr = f =>
        // A lazy (generator) list unfolded from a seed value
        // by repeated application of f to a value until no
        // residue remains. Dual to fold/reduce.
        // f returns either Nothing or Just (value, residue).
        // For a strict output list,
        // wrap with `list` or Array.from
        x => (
            function* () {
                let valueResidue = f(x);

                while (null !== valueResidue) {
                    yield valueResidue[0];
                    valueResidue = f(valueResidue[1]);
                }
            }()
        );

    // ------------------- FORMATTING --------------------

    // fTable :: String -> (a -> String) ->
    // (b -> String) -> (a -> b) -> [a] -> String
    const fTable = s =>
        // Heading -> x display function ->
        //           fx display function ->
        //    f -> values -> tabular string
        xShow => fxShow => f => xs => {
            const
                ys = xs.map(xShow),
                w = Math.max(...ys.map(y => [...y].length)),
                table = zipWith(
                    a => b => `${a.padStart(w, " ")} ->${b}`
                )(ys)(
                    xs.map(x => fxShow(f(x)))
                ).join("\n");

            return `${s}\n${table}`;
        };

    // justifyRight :: Int -> Char -> String -> String
    const justifyRight = n =>
        // The string s, preceded by enough padding (with
        // the character c) to reach the string length n.
        c => s => n > s.length ? (
            s.padStart(n, c)
        ) : s;

    // str :: a -> String
    const str = x => `${x}`;

    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f =>
        // A list constructed by zipping with a
        // custom function, rather than with the
        // default tuple constructor.
        xs => ys => take(
            Math.min(xs.length, ys.length)
        )(
            xs.map((x, i) => f(x)(ys[i]))
        );

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


Padovan sequence

The Fibonacci sequence in several ways.
Some are given in the table below, and the referenced video shows some of the geometric
similarities.

::{| class="wikitable"
! Comment !! Padovan !! Fibonacci
|-
|  ||  ||
|-
| Named after. || Richard Padovan || Leonardo of Pisa: Fibonacci
|-
|  ||  ||
|-
| Recurrence initial values. || P(0)=P(1)=P(2)=1 || F(0)=0, F(1)=1
|-
| Recurrence relation. || P(n)=P(n-2)+P(n-3) || F(n)=F(n-1)+F(n-2)
|-
|  ||  ||
|-
| First 10 terms. || 1,1,1,2,2,3,4,5,7,9 || 0,1,1,2,3,5,8,13,21,34
|-
|  ||  ||
|-
| Ratio of successive terms... || Plastic ratio, p || Golden ratio, g
|-
|  || 1.324717957244746025960908854… || 1.6180339887498948482...
|-
| Exact formula of ratios p and q. || ((9+69**.5)/18)**(1/3) + ((9-69**.5)/18)**(1/3) || (1+5**0.5)/2
|-
| Ratio is real root of polynomial. || p: x**3-x-1 || g: x**2-x-1
|-
|  ||  ||
|-
| Spirally tiling the plane using. || Equilateral triangles || Squares
|-
|  ||  ||
|-
| Constants for ... || s= 1.0453567932525329623 || a=5**0.5
|-
| ... Computing by truncation. || P(n)=floor(p**(n-1) / s + .5) || F(n)=floor(g**n / a + .5)
|-
|  ||  ||
|-
| L-System Variables. || A,B,C || A,B
|-
| L-System Start/Axiom. || A || A
|-
| L-System Rules. || A->B,B->C,C->AB || A->B,B->AB
|}

;Task:
* Write a function/method/subroutine to compute successive members of the Padovan series using the recurrence relation.
* Write a function/method/subroutine to compute successive members of the Padovan series using the floor function.
* Show the first twenty terms of the sequence.
* Confirm that the recurrence and floor based functions give the same results for 64 terms,
* Write a function/method/... using the L-system to generate successive strings.
* Show the first 10 strings produced from the L-system
* Confirm that the length of the first 32 strings produced is the Padovan sequence.

Show output here, on this page.

;Ref:
* [https://www.youtube.com/watch?v=PsGUEj4w9Cc The Plastic Ratio] - Numberphile video.

Solution:
#include
#include
#include
#include

/* Generate (and memoize) the Padovan sequence using
 * the recurrence relationship */
int pRec(int n) {
    static int *memo = NULL;
    static size_t curSize = 0;

    /* grow memoization array when necessary and fill with zeroes */
    if (curSize <= (size_t) n) {
        size_t lastSize = curSize;
        while (curSize <= (size_t) n) curSize += 1024 * sizeof(int);
        memo = realloc(memo, curSize * sizeof(int));
        memset(memo + lastSize, 0, (curSize - lastSize) * sizeof(int));
    }

    /* if we don't have the value for N yet, calculate it */
    if (memo[n] == 0) {
        if (n<=2) memo[n] = 1;
        else memo[n] = pRec(n-2) + pRec(n-3);
    }

    return memo[n];
}

/* Calculate the Nth value of the Padovan sequence
 * using the floor function */
int pFloor(int n) {
    long double p = 1.324717957244746025960908854;
    long double s = 1.0453567932525329623;
    return powl(p, n-1)/s + 0.5;
}

/* Given the previous value for the L-system, generate the
 * next value */
void nextLSystem(const char *prev, char *buf) {
    while (*prev) {
        switch (*prev++) {
            case 'A': *buf++ = 'B'; break;
            case 'B': *buf++ = 'C'; break;
            case 'C': *buf++ = 'A'; *buf++ = 'B'; break;
        }
    }
    *buf = '\0';
}

int main() {
    // 8192 is enough up to P_33.
    #define BUFSZ 8192
    char buf1[BUFSZ], buf2[BUFSZ];
    int i;

    /* Print P_0..P_19 */
    printf("P_0 .. P_19: ");
    for (i=0; i<20; i++) printf("%d ", pRec(i));
    printf("\n");

    /* Check that functions match up to P_63 */
    printf("The floor- and recurrence-based functions ");
    for (i=0; i<64; i++) {
        if (pRec(i) != pFloor(i)) {
            printf("do not match at %d: %d != %d.\n",
                i, pRec(i), pFloor(i));
            break;
        }
    }
    if (i == 64) {
        printf("match from P_0 to P_63.\n");
    }

    /* Show first 10 L-system strings */
    printf("\nThe first 10 L-system strings are:\n");
    for (strcpy(buf1, "A"), i=0; i<10; i++) {
        printf("%s\n", buf1);
        strcpy(buf2, buf1);
        nextLSystem(buf2, buf1);
    }

    /* Check lengths of strings against pFloor up to P_31 */
    printf("\nThe floor- and L-system-based functions ");
    for (strcpy(buf1, "A"), i=0; i<32; i++) {
        if ((int)strlen(buf1) != pFloor(i)) {
            printf("do not match at %d: %d != %d\n",
                i, (int)strlen(buf1), pFloor(i));
            break;
        }
        strcpy(buf2, buf1);
        nextLSystem(buf2, buf1);
    }
    if (i == 32) {
        printf("match from P_0 to P_31.\n");
    }

    return 0;
}


Padovan sequence

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

    // ----------------- PADOVAN NUMBERS -----------------

    // padovans :: [Int]
    const padovans = () => {
        // Non-finite series of Padovan numbers,
        // defined in terms of recurrence relations.
        const f = ([a, b, c]) => [
            a,
            [b, c, a + b]
        ];

        return unfoldr(f)([1, 1, 1]);
    };

    // padovanFloor :: [Int]
    const padovanFloor = () => {
        // The Padovan series, defined in terms
        // of a floor function.
        const
            // NB JavaScript loses some of this
            // precision at run-time.
            p = 1.324717957244746025960908854,
            s = 1.0453567932525329623;

        const f = n => [
            Math.floor(((p ** (n - 1)) / s) + 0.5),
            1 + n
        ];

        return unfoldr(f)(0);
    };

    // padovanLSystem : [Int]
    const padovanLSystem = () => {
        // An L-system generating terms whose lengths
        // are the values of the Padovan integer series.
        const rule = c =>
            "A" === c ? (
                "B"
            ) : "B" === c ? (
                "C"
            ) : "AB";

        const f = s => [
            s,
            chars(s).flatMap(rule)
            .join("")
        ];

        return unfoldr(f)("A");
    };

    // ---------------------- TEST -----------------------
    // main :: IO ()
    const main = () => {
        // prefixesMatch :: [a] -> [a] -> Bool
        const prefixesMatch = xs =>
            ys => n => and(
                zipWith(a => b => a === b)(
                    take(n)(xs)
                )(
                    take(n)(ys)
                )
            );

        return [
                "First 20 padovans:",
                take(20)(padovans()),

                "\nThe recurrence and floor-based functions",
                "match over the first 64 terms:\n",
                prefixesMatch(
                    padovans()
                )(
                    padovanFloor()
                )(64),

                "\nFirst 10 L-System strings:",
                take(10)(padovanLSystem()),

                "\nThe lengths of the first 32 L-System",
                "strings match the Padovan sequence:\n",
                prefixesMatch(
                    padovans()
                )(
                    fmap(length)(padovanLSystem())
                )(32)
            ]
            .map(str)
            .join("\n");
    };

    // --------------------- GENERIC ---------------------

    // and :: [Bool] -> Bool
    const and = xs =>
        // True unless any value in xs is false.
        [...xs].every(Boolean);

    // chars :: String -> [Char]
    const chars = s =>
        s.split("");

    // fmap <$> :: (a -> b) -> Gen [a] -> Gen [b]
    const fmap = f =>
        function* (gen) {
            let v = take(1)(gen);

            while (0 < v.length) {
                yield f(v[0]);
                v = take(1)(gen);
            }
        };

    // length :: [a] -> Int
    const length = xs =>
        // 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
        "GeneratorFunction" !== xs.constructor
        .constructor.name ? (
            xs.length
        ) : Infinity;

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = n =>
        // The first n elements of a list,
        // string of characters, or stream.
        xs => "GeneratorFunction" !== xs
        .constructor.constructor.name ? (
            xs.slice(0, n)
        ) : [].concat(...Array.from({
            length: n
        }, () => {
            const x = xs.next();

            return x.done ? [] : [x.value];
        }));

    // str :: a -> String
    const str = x =>
        "string" !== typeof x ? (
            JSON.stringify(x)
        ) : x;

    // unfoldr :: (b -> Maybe (a, b)) -> b -> Gen [a]
    const unfoldr = f =>
        // A lazy (generator) list unfolded from a seed value
        // by repeated application of f to a value until no
        // residue remains. Dual to fold/reduce.
        // f returns either Null or just (value, residue).
        // For a strict output list,
        // wrap with `list` or Array.from
        x => (
            function* () {
                let valueResidue = f(x);

                while (null !== valueResidue) {
                    yield valueResidue[0];
                    valueResidue = f(valueResidue[1]);
                }
            }()
        );

    // zipWithList :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f =>
        // A list constructed by zipping with a
        // custom function, rather than with the
        // default tuple constructor.
        xs => ys => ((xs_, ys_) => {
            const lng = Math.min(length(xs_), length(ys_));

            return take(lng)(xs_).map(
                (x, i) => f(x)(ys_[i])
            );
        })([...xs], [...ys]);

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


Palindrome dates

Today   ('''2020-02-02''',   at the time of this writing)   happens to be a palindrome,   without the hyphens,   not only for those countries which express their dates in the   '''yyyy-mm-dd'''   format but,   unusually,   also for countries which use the   '''dd-mm-yyyy'''   format.

;Task
Write a program which calculates and shows the next 15 palindromic dates for those countries which express their dates in the   '''yyyy-mm-dd'''   format.

Solution:
#include
#include
#include
#include

bool is_palindrome(const char* str) {
    size_t n = strlen(str);
    for (size_t i = 0; i + 1 < n; ++i, --n) {
        if (str[i] != str[n - 1])
            return false;
    }
    return true;
}

int main() {
    time_t timestamp = time(0);
    const int seconds_per_day = 24*60*60;
    int count = 15;
    char str[32];
    printf("Next %d palindrome dates:\n", count);
    for (; count > 0; timestamp += seconds_per_day) {
        struct tm* ptr = gmtime(×tamp);
        strftime(str, sizeof(str), "%Y%m%d", ptr);
        if (is_palindrome(str)) {
            strftime(str, sizeof(str), "%F", ptr);
            printf("%s\n", str);
            --count;
        }
    }
    return 0;
}


Palindrome dates

Solution:
===Functional===
Defined in terms of string reversal:


Palindrome dates

Solution:
'''Palindrome dates'''

from datetime import datetime
from itertools import chain

# palinDay :: Int -> [ISO Date]
def palinDay(y):
    '''A possibly empty list containing the palindromic
       date for the given year, if such a date exists.
    '''
    s = str(y)
    r = s[::-1]
    iso = '-'.join([s, r[0:2], r[2:]])
    try:
        datetime.strptime(iso, '%Y-%m-%d')
        return [iso]
    except ValueError:
        return []

# --------------------------TEST---------------------------
# main :: IO ()
def main():
    '''Count and samples of palindromic dates [2021..9999]
    '''
    palinDates = list(chain.from_iterable(
        map(palinDay, range(2021, 10000))
    ))
    for x in [
            'Count of palindromic dates [2021..9999]:',
            len(palinDates),
            '\nFirst 15:',
            '\n'.join(palinDates[0:15]),
            '\nLast 15:',
            '\n'.join(palinDates[-15:])
    ]:
        print(x)

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


Palindromic gapful numbers

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

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

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

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

A palindromic number is   (for this task, a positive integer expressed in base ten),   when the number is
reversed,   is the same as the original number.

;Task:
:*   Show   (nine sets)   the first   '''20'''   palindromic gapful numbers that   ''end''   with:
:::*   the digit   '''1'''
:::*   the digit   '''2'''
:::*   the digit   '''3'''
:::*   the digit   '''4'''
:::*   the digit   '''5'''
:::*   the digit   '''6'''
:::*   the digit   '''7'''
:::*   the digit   '''8'''
:::*   the digit   '''9'''
:*   Show   (nine sets, like above)   of palindromic gapful numbers:
:::*   the last   '''15'''   palindromic gapful numbers   (out of      '''100''')
:::*   the last   '''10'''   palindromic gapful numbers   (out of                '''1,000''')       {optional}

For other ways of expressing the (above) requirements, see the   ''discussion''   page.

;Note:
All palindromic gapful numbers are divisible by eleven.

;Related tasks:
:*   [https://rosettacode.org/wiki/Palindrome_detection palindrome detection].
:*   [https://rosettacode.org/wiki/Gapful_numbers gapful numbers].

;Also see:
:*   The OEIS entry:   [https://oeis.org/A108343 A108343 gapful numbers].

Solution:
#include
#include
#include

typedef uint64_t integer;

integer reverse(integer n) {
    integer rev = 0;
    while (n > 0) {
        rev = rev * 10 + (n % 10);
        n /= 10;
    }
    return rev;
}

typedef struct palgen_tag {
    integer power;
    integer next;
    int digit;
    bool even;
} palgen_t;

void init_palgen(palgen_t* palgen, int digit) {
    palgen->power = 10;
    palgen->next = digit * palgen->power - 1;
    palgen->digit = digit;
    palgen->even = false;
}

integer next_palindrome(palgen_t* p) {
    ++p->next;
    if (p->next == p->power * (p->digit + 1)) {
        if (p->even)
            p->power *= 10;
        p->next = p->digit * p->power;
        p->even = !p->even;
    }
    return p->next * (p->even ? 10 * p->power : p->power)
        + reverse(p->even ? p->next : p->next/10);
}

bool gapful(integer n) {
    integer m = n;
    while (m >= 10)
        m /= 10;
    return n % (n % 10 + 10 * m) == 0;
}

void print(int len, integer array[][len]) {
    for (int digit = 1; digit < 10; ++digit) {
        printf("%d: ", digit);
        for (int i = 0; i < len; ++i)
            printf(" %llu", array[digit - 1][i]);
        printf("\n");
    }
}

int main() {
    const int n1 = 20, n2 = 15, n3 = 10;
    const int m1 = 100, m2 = 1000;

    integer pg1[9][n1];
    integer pg2[9][n2];
    integer pg3[9][n3];

    for (int digit = 1; digit < 10; ++digit) {
        palgen_t pgen;
        init_palgen(&pgen, digit);
        for (int i = 0; i < m2; ) {
            integer n = next_palindrome(&pgen);
            if (!gapful(n))
                continue;
            if (i < n1)
                pg1[digit - 1][i] = n;
            else if (i < m1 && i >= m1 - n2)
                pg2[digit - 1][i - (m1 - n2)] = n;
            else if (i >= m2 - n3)
                pg3[digit - 1][i - (m2 - n3)] = n;
            ++i;
        }
    }

    printf("First %d palindromic gapful numbers ending in:\n", n1);
    print(n1, pg1);

    printf("\nLast %d of first %d palindromic gapful numbers ending in:\n", n2, m1);
    print(n2, pg2);

    printf("\nLast %d of first %d palindromic gapful numbers ending in:\n", n3, m2);
    print(n3, pg3);

    return 0;
}


Palindromic gapful numbers

Solution:
from itertools import count
from pprint import pformat
import re
import heapq

def pal_part_gen(odd=True):
    for i in count(1):
        fwd = str(i)
        rev = fwd[::-1][1:] if odd else fwd[::-1]
        yield int(fwd + rev)

def pal_ordered_gen():
    yield from heapq.merge(pal_part_gen(odd=True), pal_part_gen(odd=False))

def is_gapful(x):
    return (x % (int(str(x)[0]) * 10 + (x % 10)) == 0)

if __name__ == '__main__':
    start = 100
    for mx, last in [(20, 20), (100, 15), (1_000, 10)]:
        print(f"\nLast {last} of the first {mx} binned-by-last digit "
              f"gapful numbers >= {start}")
        bin = {i: [] for i in range(1, 10)}
        gen = (i for i in pal_ordered_gen() if i >= start and is_gapful(i))
        while any(len(val) < mx for val in bin.values()):
            g = next(gen)
            val = bin[g % 10]
            if len(val) < mx:
                val.append(g)
        b = {k:v[-last:] for k, v in bin.items()}
        txt = pformat(b, width=220)
        print('', re.sub(r"[{},\[\]]", '', txt))


Pancake numbers

Adrian Monk has problems and an assistant,  Sharona Fleming. Sharona can deal with most of Adrian's problems except his lack of punctuality paying her remuneration. 2 pay checks down and she prepares him pancakes for breakfast. Knowing that he will be unable to eat them unless they are stacked in ascending order of size she leaves him only a skillet which he can insert at any point in the pile and flip all the above pancakes, repeating until the pile is sorted. Sharona has left the pile of n pancakes such that the maximum number of flips is required. Adrian is determined to do this in as few flips as possible. This sequence n->p(n) is known as the Pancake numbers.

The task is to determine p(n) for n = 1 to 9, and for each show an example requiring p(n) flips.

[[Sorting_algorithms/Pancake_sort]] actually performs the sort some giving the number of flips used. How do these compare with p(n)?

Few people know p(20), generously I shall award an extra credit for anyone doing more than p(16).

;References
# [https://www.bbvaopenmind.com/en/science/mathematics/bill-gates-and-the-pancake-problem Bill Gates and the pancake problem]
# [https://oeis.org/A058986 A058986]

Solution:
#include

int pancake(int n) {
    int gap = 2, sum = 2, adj = -1;
    while (sum < n) {
        adj++;
        gap = gap * 2 - 1;
        sum += gap;
    }
    return n + adj;
}

int main() {
    int i, j;
    for (i = 0; i < 4; i++) {
        for (j = 1; j < 6; j++) {
            int n = i * 5 + j;
            printf("p(%2d) = %2d  ", n, pancake(n));
        }
        printf("\n");
    }
    return 0;
}


Pancake numbers

Solution:
"""Pancake numbers. Requires Python>=3.7."""
import time

from collections import deque
from operator import itemgetter
from typing import Tuple

Pancakes = Tuple[int, ...]

def flip(pancakes: Pancakes, position: int) -> Pancakes:
    """Flip the stack of pancakes at the given position."""
    return tuple([*reversed(pancakes[:position]), *pancakes[position:]])

def pancake(n: int) -> Tuple[Pancakes, int]:
    """Return the nth pancake number."""
    init_stack = tuple(range(1, n + 1))
    stack_flips = {init_stack: 0}
    queue = deque([init_stack])

    while queue:
        stack = queue.popleft()
        flips = stack_flips[stack] + 1

        for i in range(2, n + 1):
            flipped = flip(stack, i)
            if flipped not in stack_flips:
                stack_flips[flipped] = flips
                queue.append(flipped)

    return max(stack_flips.items(), key=itemgetter(1))

if __name__ == "__main__":
    start = time.time()

    for n in range(1, 10):
        pancakes, p = pancake(n)
        print(f"pancake({n}) = {p:>2}. Example: {list(pancakes)}")

    print(f"\nTook {time.time() - start:.3} seconds.")


Pangram checker

A pangram is a sentence that contains all the letters of the English alphabet at least once.

For example:   ''The quick brown fox jumps over the lazy dog''.

;Task:
Write a function or method to check a sentence to see if it is a   pangram   (or not)   and show its use.

;Related tasks:
:*   [https://rosettacode.org/wiki/Determine_if_a_string_has_all_the_same_characters determine if a string has all the same characters]
:*   [https://rosettacode.org/wiki/Determine_if_a_string_has_all_unique_characters determine if a string has all unique characters]

Solution:
#include

int is_pangram(const char *s)
{
	const char *alpha = ""
		"abcdefghjiklmnopqrstuvwxyz"
		"ABCDEFGHIJKLMNOPQRSTUVWXYZ";

	char ch, wasused[26] = {0};
	int total = 0;

	while ((ch = *s++) != '\0') {
		const char *p;
		int idx;

		if ((p = strchr(alpha, ch)) == NULL)
			continue;

		idx = (p - alpha) % 26;

		total += !wasused[idx];
		wasused[idx] = 1;
		if (total == 26)
			return 1;
	}
	return 0;
}

int main(void)
{
	int i;
	const char *tests[] = {
		"The quick brown fox jumps over the lazy dog.",
		"The qu1ck brown fox jumps over the lazy d0g."
	};

	for (i = 0; i < 2; i++)
		printf("\"%s\" is %sa pangram\n",
			tests[i], is_pangram(tests[i])?"":"not ");
	return 0;
}


Pangram checker

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

    // ----------------- PANGRAM CHECKER -----------------

    // isPangram :: String -> Bool
    const isPangram = s =>
        0 === "abcdefghijklmnopqrstuvwxyz"
        .split("")
        .filter(c => -1 === s.toLowerCase().indexOf(c))
        .length;

    // ---------------------- TEST -----------------------
    return [
        "is this a pangram",
        "The quick brown fox jumps over the lazy dog"
    ].map(isPangram);
})();


Pangram checker

Solution:
import string, sys
if sys.version_info[0] < 3:
    input = raw_input

def ispangram(sentence, alphabet=string.ascii_lowercase):
    alphaset = set(alphabet)
    return alphaset <= set(sentence.lower())

print ( ispangram(input('Sentence: ')) )


Paraffins

right

This organic chemistry task is essentially to implement a tree enumeration algorithm.

;Task:
Enumerate, without repetitions and in order of increasing size, all possible paraffin molecules (also known as alkanes).

Paraffins are built up using only carbon atoms, which has four bonds, and hydrogen, which has one bond.   All bonds for each atom must be used, so it is easiest to think of an alkane as linked carbon atoms forming the "backbone" structure, with adding hydrogen atoms linking the remaining unused bonds.

In a paraffin, one is allowed neither double bonds (two bonds between the same pair of atoms), nor cycles of linked carbons.   So all paraffins with   '''n'''   carbon atoms share the empirical formula     CnH2n+2

But for all   '''n''' ≥ 4   there are several distinct molecules ("isomers") with the same formula but different structures.

The number of isomers rises rather rapidly when   '''n'''   increases.

In counting isomers it should be borne in mind that the four bond positions on a given carbon atom can be freely interchanged and bonds rotated (including 3-D "out of the paper" rotations when it's being observed on a flat diagram),   so rotations or re-orientations of parts of the molecule (without breaking bonds) do not give different isomers.   So what seem at first to be different molecules may in fact turn out to be different orientations of the same molecule.

;Example:
With   '''n''' = 3   there is only one way of linking the carbons despite the different orientations the molecule can be drawn;   and with   '''n''' = 4   there are two configurations:
:::*   a   straight   chain:     (CH3)(CH2)(CH2)(CH3)
:::*   a        branched chain:       (CH3)(CH(CH3))(CH3)

Due to bond rotations, it doesn't matter which direction the branch points in.

The phenomenon of "stereo-isomerism" (a molecule being different from its mirror image due to the actual 3-D arrangement of bonds) is ignored for the purpose of this task.

The input is the number   '''n'''   of carbon atoms of a molecule (for instance '''17''').

The output is how many different different paraffins there are with   '''n'''   carbon atoms  (for instance   24,894   if   '''n''' = 17).

The sequence of those results is visible in the OEIS entry:
:::   A00602: number of n-node unrooted quartic trees; number of n-carbon alkanes C(n)H(2n+2) ignoring stereoisomers.

The sequence is (the index starts from zero, and represents the number of carbon atoms):

 1, 1, 1, 1, 2, 3, 5, 9, 18, 35, 75, 159, 355, 802, 1858, 4347, 10359,
 24894, 60523, 148284, 366319, 910726, 2278658, 5731580, 14490245,
 36797588, 93839412, 240215803, 617105614, 1590507121, 4111846763,
 10660307791, 27711253769, ...

;Extra credit:
Show the paraffins in some way.

A flat 1D representation, with arrays or lists is enough, for instance:

*Main> all_paraffins 1
                        [CCP H H H H]
*Main> all_paraffins 2
                        [BCP (C H H H) (C H H H)]
*Main> all_paraffins 3
                        [CCP H H (C H H H) (C H H H)]
*Main> all_paraffins 4
                        [BCP (C H H (C H H H)) (C H H (C H H H)),
                         CCP H (C H H H) (C H H H) (C H H H)]
*Main> all_paraffins 5
                        [CCP H H (C H H (C H H H)) (C H H (C H H H)),
                         CCP H (C H H H) (C H H H) (C H H (C H H H)),
                         CCP (C H H H) (C H H H) (C H H H) (C H H H)]
*Main> all_paraffins 6
                        [BCP (C H H (C H H (C H H H))) (C H H (C H H (C H H H))),
                         BCP (C H H (C H H (C H H H))) (C H (C H H H) (C H H H)),
                         BCP (C H (C H H H) (C H H H)) (C H (C H H H) (C H H H)),
                         CCP H (C H H H) (C H H (C H H H)) (C H H (C H H H)),
                         CCP (C H H H) (C H H H) (C H H H) (C H H (C H H H))]
Showing a basic 2D ASCII-art representation of the paraffins is better; for instance (molecule names aren't necessary):
       methane          ethane               propane               isobutane

          H              H   H              H   H   H              H   H   H
          │              │   │              │   │   │              │   │   │
      H ─ C ─ H      H ─ C ─ C ─ H      H ─ C ─ C ─ C ─ H      H ─ C ─ C ─ C ─ H
          │              │   │              │   │   │              │   │   │
          H              H   H              H   H   H              H   │   H
                                                                       │
                                                                   H ─ C ─ H
                                                                       │
                                                                       H

;Links:
*   A paper that explains the problem and its solution in a functional language:
http://www.cs.wright.edu/~tkprasad/courses/cs776/paraffins-turner.pdf

*   A Haskell implementation:
https://github.com/ghc/nofib/blob/master/imaginary/paraffins/Main.hs

*   A Scheme implementation:
http://www.ccs.neu.edu/home/will/Twobit/src/paraffins.scm

*   A Fortress implementation:         (this site has been closed)
http://java.net/projects/projectfortress/sources/sources/content/ProjectFortress/demos/turnersParaffins0.fss?rev=3005

Solution:
#include

#define MAX_N 33	/* max number of tree nodes */
#define BRANCH 4	/* max number of edges a single node can have */

/* The basic idea: a paraffin molecule can be thought as a simple tree
   with each node being a carbon atom.  Counting molecules is thus the
   problem of counting free (unrooted) trees of given number of nodes.

   An unrooted tree needs to be uniquely represented, so we need a way
   to cannonicalize equivalent free trees.  For that, we need to first
   define the cannonical form of rooted trees.  Since rooted trees can
   be constructed by a root node and up to BRANCH rooted subtrees that
   are arranged in some definite order, we can define it thusly:
     * Given the root of a tree, the weight of each of its branches is
       the number of nodes contained in that branch;
     * A cannonical rooted tree would have its direct subtrees ordered
       in descending order by weight;
     * In case multiple subtrees are the same weight, they are ordered
       by some unstated, but definite, order (this code doesn't really
       care what the ordering is; it only counts the number of choices
       in such a case, not enumerating individual trees.)

   A rooted tree of N nodes can then be constructed by adding smaller,
   cannonical rooted trees to a root node, such that:
     * Each subtree has fewer than BRANCH branches (since it must have
       an empty slot for an edge to connect to the new root);
     * Weight of those subtrees added later are no higher than earlier
       ones;
     * Their weight total N-1.
   A rooted tree so constructed would be itself cannonical.

   For an unrooted tree, we can define the radius of any of its nodes:
   it's the maximum weight of any of the subtrees if this node is used
   as the root.  A node is the center of a tree if it has the smallest
   radius among all the nodes.  A tree can have either one or two such
   centers; if two, they must be adjacent (cf. Knuth, tAoCP 2.3.4.4).

   An important fact is that, a node in a tree is its sole center, IFF
   its radius times 2 is no greater than the sum of the weights of all
   branches (ibid).  While we are making rooted trees, we can add such
   trees encountered to the count of cannonical unrooted trees.

   A bi-centered unrooted tree with N nodes can be made by joining two
   trees, each with N/2 nodes and fewer than BRANCH subtrees, at root.
   The pair must be ordered in aforementioned implicit way so that the
   product is cannonical. */

typedef unsigned long long xint;
#define FMT "llu"

xint rooted[MAX_N] = {1, 1, 0};
xint unrooted[MAX_N] = {1, 1, 0};

/* choose k out of m possible values; chosen values may repeat, but the
   ordering of them does not matter.  It's binomial(m + k - 1, k) */
xint choose(xint m, xint k)
{
	xint i, r;

	if (k == 1) return m;
	for (r = m, i = 1; i < k; i++)
		r = r * (m + i) / (i + 1);
	return r;
}

/* constructing rooted trees of BR branches at root, with at most
   N radius, and SUM nodes in the partial tree already built. It's
   recursive, and CNT and L carry down the number of combinations
   and the tree radius already encountered. */
void tree(xint br, xint n, xint cnt, xint sum, xint l)
{
	xint b, c, m, s;

	for (b = br + 1; b <= BRANCH; b++) {
		s = sum + (b - br) * n;
		if (s >= MAX_N) return;

		/* First B of BR branches are all of weight n; the
		   rest are at most of weight N-1 */
		c = choose(rooted[n], b - br) * cnt;

		/* This partial tree is singly centered as is */
		if (l * 2 < s) unrooted[s] += c;

		/* Trees saturate at root can't be used as building
		   blocks for larger trees, so forget them */
		if (b == BRANCH) return;
		rooted[s] += c;

		/* Build the rest of the branches */
		for (m = n; --m; ) tree(b, m, c, s, l);
	}
}

void bicenter(int s)
{
	if (s & 1) return;

	/* Pick two of the half-size building blocks, allowing
	   repetition. */
	unrooted[s] += rooted[s/2] * (rooted[s/2] + 1) / 2;
}

int main()
{
	xint n;
	for (n = 1; n < MAX_N; n++) {
		tree(0, n, 1, 1, n);
		bicenter(n);
		printf("%"FMT": %"FMT"\n", n, unrooted[n]);
	}

	return 0;
}


Paraffins

Solution:
from itertools import count, chain, tee, islice, cycle
from fractions import Fraction
from sys import setrecursionlimit
setrecursionlimit(5000)

def frac(a,b): return a//b if a%b == 0 else Fraction(a,b)

# infinite polynomial class
class Poly:
    def __init__(self, gen = None):
        self.gen, self.source = (None, gen) if type(gen) is Poly \
            else (gen, None)

    def __iter__(self):
        # We're essentially tee'ing it everytime the iterator
        # is, well, iterated.  This may be excessive.
        return Poly(self)

    def getsource(self):
        if self.gen == None:
            s = self.source
            s.getsource()
            s.gen, self.gen = tee(s.gen, 2)

    def next(self):
        self.getsource()
        return next(self.gen)

    __next__ = next

    # Overload "<<" as stream input operator. Hey, C++ does it.
    def __lshift__(self, a): self.gen = a

    # The other operators are pretty much what one would expect
    def __neg__(self): return Poly(-x for x in self)

    def __sub__(a, b): return a + (-b)

    def __rsub__(a, n):
        a = Poly(a)
        def gen():
            yield(n - next(a))
            for x in a: yield(-x)
        return Poly(gen())

    def __add__(a, b):
        if type(b) is Poly:
            return Poly(x + y for (x,y) in zip(a,b))

        a = Poly(a)
        def gen():
            yield(next(a) + b)
            for x in a: yield(x)

        return Poly(gen())

    def __radd__(a,b):
        return a + b

    def __mul__(a,b):
        if not type(b) is Poly:
            return Poly(x*b for x in a)

        def gen():
            s = Poly(cycle([0]))
            for y in b:
                s += y*a
                yield(next(s))

        return Poly(gen())

    def __rmul__(a,b): return a*b

    def __truediv__(a,b):
        if not type(b) is Poly:
            return Poly(frac(x, b) for x in a)

        a, b = Poly(a), Poly(b)
        def gen():
            r, bb = a,next(b)
            while True:
                aa = next(r)
                q = frac(aa, bb)
                yield(q)
                r -= q*b

        return Poly(gen())

    def repl(self, n):
        def gen():
            for x in self:
                yield(x)
                for i in range(n-1): yield(0)
        return Poly(gen())

    def __pow__(self, n):
        return Poly(self) if n == 1 else self * self**(n-1)

def S2(a,b): return (a*a + b)/2
def S4(a,b,c,d): return a**4/24 + a**2*b/4 + a*c/3 + b**2/8 + d/4

x1 = Poly()
x2 = x1.repl(2)
x3 = x1.repl(3)
x4 = x1.repl(4)
x1 << chain([1], (x1**3 + 3*x1*x2 + 2*x3)/6)

a598 = x1
a678 = Poly(chain([0], S4(x1, x2, x3, x4)))
a599 = S2(x1 - 1, x2 - 1)
a602 = a678 - a599 + x2

for n,x in zip(count(0), islice(a602, 500)): print(n,x)


Parse an IP Address

The purpose of this task is to demonstrate parsing of text-format IP addresses, using IPv4 and IPv6.

Taking the following as inputs:
::: {| border="5" cellspacing="0" cellpadding=2
|-
|127.0.0.1
|The "localhost" IPv4 address
|-
|127.0.0.1:80
|The "localhost" IPv4 address, with a specified port (80)
|-
|::1
|The "localhost" IPv6 address
|-
|[::1]:80
|The "localhost" IPv6 address, with a specified port (80)
|-
|2605:2700:0:3::4713:93e3
|Rosetta Code's primary server's public IPv6 address
|-
|[2605:2700:0:3::4713:93e3]:80
|Rosetta Code's primary server's public IPv6 address, with a specified port (80)
|}

;Task:
Emit each described IP address as a hexadecimal integer representing the address, the address space, and the port number specified, if any.

In languages where variant result types are clumsy, the result should be ipv4 or ipv6 address number, something which says which address space was represented, port number and something that says if the port was specified.

;Example:
'''127.0.0.1'''   has the address number   '''7F000001'''   (2130706433 decimal)
in the ipv4 address space.

'''::ffff:127.0.0.1'''   represents the same address in the ipv6 address space where it has the
address number    '''FFFF7F000001'''   (281472812449793 decimal).

'''::1'''   has address number   '''1'''   and serves the same purpose in the ipv6 address
space that   '''127.0.0.1'''   serves in the ipv4 address space.

Solution:
#include
#include

static unsigned int _parseDecimal ( const char** pchCursor )
{
    unsigned int nVal = 0;
    char chNow;
    while ( chNow = **pchCursor, chNow >= '0' && chNow <= '9' )
    {
        //shift digit in
        nVal *= 10;
        nVal += chNow - '0';

        ++*pchCursor;
    }
    return nVal;
}

static unsigned int _parseHex ( const char** pchCursor )
{
    unsigned int nVal = 0;
    char chNow;
    while ( chNow = **pchCursor & 0x5f, //(collapses case, but mutilates digits)
            (chNow >= ('0'&0x5f) && chNow <= ('9'&0x5f)) ||
            (chNow >= 'A' && chNow <= 'F')
            )
    {
        unsigned char nybbleValue;
        chNow -= 0x10;  //scootch digital values down; hex now offset by x31
        nybbleValue = ( chNow > 9 ? chNow - (0x31-0x0a) : chNow );
        //shift nybble in
        nVal <<= 4;
        nVal += nybbleValue;

        ++*pchCursor;
    }
    return nVal;
}

//Parse a textual IPv4 or IPv6 address, optionally with port, into a binary
//array (for the address, in network order), and an optionally provided port.
//Also, indicate which of those forms (4 or 6) was parsed.  Return true on
//success.  ppszText must be a nul-terminated ASCII string.  It will be
//updated to point to the character which terminated parsing (so you can carry
//on with other things.  abyAddr must be 16 bytes.  You can provide NULL for
//abyAddr, nPort, bIsIPv6, if you are not interested in any of those
//informations.  If we request port, but there is no port part, then nPort will
//be set to 0.  There may be no whitespace leading or internal (though this may
//be used to terminate a successful parse.
//Note:  the binary address and integer port are in network order.
int ParseIPv4OrIPv6 ( const char** ppszText,
        unsigned char* abyAddr, int* pnPort, int* pbIsIPv6 )
{
    unsigned char* abyAddrLocal;
    unsigned char abyDummyAddr[16];

    //find first colon, dot, and open bracket
    const char* pchColon = strchr ( *ppszText, ':' );
    const char* pchDot = strchr ( *ppszText, '.' );
    const char* pchOpenBracket = strchr ( *ppszText, '[' );
    const char* pchCloseBracket = NULL;

    //we'll consider this to (probably) be IPv6 if we find an open
    //bracket, or an absence of dots, or if there is a colon, and it
    //precedes any dots that may or may not be there
    int bIsIPv6local = NULL != pchOpenBracket || NULL == pchDot ||
            ( NULL != pchColon && ( NULL == pchDot || pchColon < pchDot ) );
    //OK, now do a little further sanity check our initial guess...
    if ( bIsIPv6local )
    {
        //if open bracket, then must have close bracket that follows somewhere
        pchCloseBracket = strchr ( *ppszText, ']' );
        if ( NULL != pchOpenBracket && ( NULL == pchCloseBracket ||
                pchCloseBracket < pchOpenBracket ) )
            return 0;
    }
    else    //probably ipv4
    {
        //dots must exist, and precede any colons
        if ( NULL == pchDot || ( NULL != pchColon && pchColon < pchDot ) )
            return 0;
    }

    //we figured out this much so far....
    if ( NULL != pbIsIPv6 )
        *pbIsIPv6 = bIsIPv6local;

    //especially for IPv6 (where we will be decompressing and validating)
    //we really need to have a working buffer even if the caller didn't
    //care about the results.
    abyAddrLocal = abyAddr; //prefer to use the caller's
    if ( NULL == abyAddrLocal ) //but use a dummy if we must
        abyAddrLocal = abyDummyAddr;

    //OK, there should be no correctly formed strings which are miscategorized,
    //and now any format errors will be found out as we continue parsing
    //according to plan.
    if ( ! bIsIPv6local )   //try to parse as IPv4
    {
        //4 dotted quad decimal; optional port if there is a colon
        //since there are just 4, and because the last one can be terminated
        //differently, I'm just going to unroll any potential loop.
        unsigned char* pbyAddrCursor = abyAddrLocal;
        unsigned int nVal;
        const char* pszTextBefore = *ppszText;
        nVal =_parseDecimal ( ppszText );           //get first val
        if ( '.' != **ppszText || nVal > 255 || pszTextBefore == *ppszText )    //must be in range and followed by dot and nonempty
            return 0;
        *(pbyAddrCursor++) = (unsigned char) nVal;  //stick it in addr
        ++(*ppszText);  //past the dot

        pszTextBefore = *ppszText;
        nVal =_parseDecimal ( ppszText );           //get second val
        if ( '.' != **ppszText || nVal > 255 || pszTextBefore == *ppszText )
            return 0;
        *(pbyAddrCursor++) = (unsigned char) nVal;
        ++(*ppszText);  //past the dot

        pszTextBefore = *ppszText;
        nVal =_parseDecimal ( ppszText );           //get third val
        if ( '.' != **ppszText || nVal > 255 || pszTextBefore == *ppszText )
            return 0;
        *(pbyAddrCursor++) = (unsigned char) nVal;
        ++(*ppszText);  //past the dot

        pszTextBefore = *ppszText;
        nVal =_parseDecimal ( ppszText );           //get fourth val
        if ( nVal > 255 || pszTextBefore == *ppszText ) //(we can terminate this one in several ways)
            return 0;
        *(pbyAddrCursor++) = (unsigned char) nVal;

        if ( ':' == **ppszText && NULL != pnPort )  //have port part, and we want it
        {
            unsigned short usPortNetwork;   //save value in network order
            ++(*ppszText);  //past the colon
            pszTextBefore = *ppszText;
            nVal =_parseDecimal ( ppszText );
            if ( nVal > 65535 || pszTextBefore == *ppszText )
                return 0;
            ((unsigned char*)&usPortNetwork)[0] = ( nVal & 0xff00 ) >> 8;
            ((unsigned char*)&usPortNetwork)[1] = ( nVal & 0xff );
            *pnPort = usPortNetwork;
            return 1;
        }
        else    //finished just with ip address
        {
            if ( NULL != pnPort )
                *pnPort = 0;    //indicate we have no port part
            return 1;
        }
    }
    else    //try to parse as IPv6
    {
        unsigned char* pbyAddrCursor;
        unsigned char* pbyZerosLoc;
        int bIPv4Detected;
        int nIdx;
        //up to 8 16-bit hex quantities, separated by colons, with at most one
        //empty quantity, acting as a stretchy run of zeroes.  optional port
        //if there are brackets followed by colon and decimal port number.
        //A further form allows an ipv4 dotted quad instead of the last two
        //16-bit quantities, but only if in the ipv4 space ::ffff:x:x .
        if ( NULL != pchOpenBracket )   //start past the open bracket, if it exists
            *ppszText = pchOpenBracket + 1;
        pbyAddrCursor = abyAddrLocal;
        pbyZerosLoc = NULL; //if we find a 'zero compression' location
        bIPv4Detected = 0;
        for ( nIdx = 0; nIdx < 8; ++nIdx )  //we've got up to 8 of these, so we will use a loop
        {
            const char* pszTextBefore = *ppszText;
            unsigned nVal =_parseHex ( ppszText );      //get value; these are hex
            if ( pszTextBefore == *ppszText )   //if empty, we are zero compressing; note the loc
            {
                if ( NULL != pbyZerosLoc )  //there can be only one!
                {
                    //unless it's a terminal empty field, then this is OK, it just means we're done with the host part
                    if ( pbyZerosLoc == pbyAddrCursor )
                    {
                        --nIdx;
                        break;
                    }
                    return 0;   //otherwise, it's a format error
                }
                if ( ':' != **ppszText )    //empty field can only be via :
                    return 0;
                if ( 0 == nIdx )    //leading zero compression requires an extra peek, and adjustment
                {
                    ++(*ppszText);
                    if ( ':' != **ppszText )
                        return 0;
                }

                pbyZerosLoc = pbyAddrCursor;
                ++(*ppszText);
            }
            else
            {
                if ( '.' == **ppszText )    //special case of ipv4 convenience notation
                {
                    //who knows how to parse ipv4?  we do!
                    const char* pszTextlocal = pszTextBefore;   //back it up
                    unsigned char abyAddrlocal[16];
                    int bIsIPv6local;
                    int bParseResultlocal = ParseIPv4OrIPv6 ( &pszTextlocal, abyAddrlocal, NULL, &bIsIPv6local );
                    *ppszText = pszTextlocal;   //success or fail, remember the terminating char
                    if ( ! bParseResultlocal || bIsIPv6local )  //must parse and must be ipv4
                        return 0;
                    //transfer addrlocal into the present location
                    *(pbyAddrCursor++) = abyAddrlocal[0];
                    *(pbyAddrCursor++) = abyAddrlocal[1];
                    *(pbyAddrCursor++) = abyAddrlocal[2];
                    *(pbyAddrCursor++) = abyAddrlocal[3];
                    ++nIdx; //pretend like we took another short, since the ipv4 effectively is two shorts
                    bIPv4Detected = 1;  //remember how we got here for further validation later
                    break;  //totally done with address
                }

                if ( nVal > 65535 ) //must be 16 bit quantity
                    return 0;
                *(pbyAddrCursor++) = nVal >> 8;     //transfer in network order
                *(pbyAddrCursor++) = nVal & 0xff;
                if ( ':' == **ppszText )    //typical case inside; carry on
                {
                    ++(*ppszText);
                }
                else    //some other terminating character; done with this parsing parts
                {
                    break;
                }
            }
        }

        //handle any zero compression we found
        if ( NULL != pbyZerosLoc )
        {
            int nHead = (int)( pbyZerosLoc - abyAddrLocal );    //how much before zero compression
            int nTail = nIdx * 2 - (int)( pbyZerosLoc - abyAddrLocal ); //how much after zero compression
            int nZeros = 16 - nTail - nHead;        //how much zeros
            memmove ( &abyAddrLocal[16-nTail], pbyZerosLoc, nTail );    //scootch stuff down
            memset ( pbyZerosLoc, 0, nZeros );      //clear the compressed zeros
        }

        //validation of ipv4 subspace ::ffff:x.x
        if ( bIPv4Detected )
        {
            static const unsigned char abyPfx[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
            if ( 0 != memcmp ( abyAddrLocal, abyPfx, sizeof(abyPfx) ) )
                return 0;
        }

        //close bracket
        if ( NULL != pchOpenBracket )
        {
            if ( ']' != **ppszText )
                return 0;
            ++(*ppszText);
        }

        if ( ':' == **ppszText && NULL != pnPort )  //have port part, and we want it
        {
            const char* pszTextBefore;
            unsigned int nVal;
            unsigned short usPortNetwork;   //save value in network order
            ++(*ppszText);  //past the colon
            pszTextBefore = *ppszText;
            pszTextBefore = *ppszText;
            nVal =_parseDecimal ( ppszText );
            if ( nVal > 65535 || pszTextBefore == *ppszText )
                return 0;
            ((unsigned char*)&usPortNetwork)[0] = ( nVal & 0xff00 ) >> 8;
            ((unsigned char*)&usPortNetwork)[1] = ( nVal & 0xff );
            *pnPort = usPortNetwork;
            return 1;
        }
        else    //finished just with ip address
        {
            if ( NULL != pnPort )
                *pnPort = 0;    //indicate we have no port part
            return 1;
        }
    }

}

//simple version if we want don't care about knowing how much we ate
int ParseIPv4OrIPv6_2 ( const char* pszText,
        unsigned char* abyAddr, int* pnPort, int* pbIsIPv6 )
{
    const char* pszTextLocal = pszText;
    return ParseIPv4OrIPv6 ( &pszTextLocal, abyAddr, pnPort, pbIsIPv6);
}


Parse an IP Address

Solution:
from ipaddress import ip_address
from urllib.parse import urlparse

tests = [
    "127.0.0.1",
    "127.0.0.1:80",
    "::1",
    "[::1]:80",
    "::192.168.0.1",
    "2605:2700:0:3::4713:93e3",
    "[2605:2700:0:3::4713:93e3]:80" ]

def parse_ip_port(netloc):
    try:
        ip = ip_address(netloc)
        port = None
    except ValueError:
        parsed = urlparse('//{}'.format(netloc))
        ip = ip_address(parsed.hostname)
        port = parsed.port
    return ip, port

for address in tests:
    ip, port = parse_ip_port(address)
    hex_ip = {4:'{:08X}', 6:'{:032X}'}[ip.version].format(int(ip))
    print("{:39s}  {:>32s}  IPv{}  port={}".format(
        str(ip), hex_ip, ip.version, port ))


Parsing/RPN calculator algorithm

;Task:
Create a stack-based evaluator for an expression in   reverse Polish notation (RPN)   that also shows the changes in the stack as each individual token is processed ''as a table''.

* Assume an input of a correct, space separated, string of tokens of an RPN expression
* Test with the RPN expression generated from the   [[Parsing/Shunting-yard algorithm]]   task:
         3 4 2 * 1 5 - 2 3 ^ ^ / +
* Print or display the output here

;Notes:
*    '''^'''    means exponentiation in the expression above.
*    '''/'''    means division.

;See also:
*   [[Parsing/Shunting-yard algorithm]] for a method of generating an RPN from an infix expression.
*   Several solutions to [[24 game/Solve]] make use of RPN evaluators (although tracing how they work is not a part of that task).
*   [[Parsing/RPN to infix conversion]].
*   [[Arithmetic evaluation]].

Solution:
#include
#include
#include
#include

void die(const char *msg)
{
	fprintf(stderr, "%s", msg);
	abort();
}

#define MAX_D 256
double stack[MAX_D];
int depth;

void push(double v)
{
	if (depth >= MAX_D) die("stack overflow\n");
	stack[depth++] = v;
}

double pop()
{
	if (!depth) die("stack underflow\n");
	return stack[--depth];
}

double rpn(char *s)
{
	double a, b;
	int i;
	char *e, *w = " \t\n\r\f";

	for (s = strtok(s, w); s; s = strtok(0, w)) {
		a = strtod(s, &e);
		if (e > s)		printf(" :"), push(a);
#define binop(x) printf("%c:", *s), b = pop(), a = pop(), push(x)
		else if (*s == '+')	binop(a + b);
		else if (*s == '-')	binop(a - b);
		else if (*s == '*')	binop(a * b);
		else if (*s == '/')	binop(a / b);
		else if (*s == '^')	binop(pow(a, b));
#undef binop
		else {
			fprintf(stderr, "'%c': ", *s);
			die("unknown oeprator\n");
		}
		for (i = depth; i-- || 0 * putchar('\n'); )
			printf(" %g", stack[i]);
	}

	if (depth != 1) die("stack leftover\n");

	return pop();
}

int main(void)
{
	char s[] = " 3 4 2 * 1 5 - 2 3 ^ ^ / + ";
	printf("%g\n", rpn(s));
	return 0;
}


Parsing/RPN calculator algorithm

Solution:
const e = '3 4 2 * 1 5 - 2 3 ^ ^ / +';
const s = [], tokens = e.split(' ');
for (const t of tokens) {
  const n = Number(t);
  if (!isNaN(n)) {
    s.push(n);
  } else {
    if (s.length < 2) {
      throw new Error(`${t}: ${s}: insufficient operands.`);
    }
    const o2 = s.pop(), o1 = s.pop();
    switch (t) {
      case '+': s.push(o1 + o2); break;
      case '-': s.push(o1 - o2); break;
      case '*': s.push(o1 * o2); break;
      case '/': s.push(o1 / o2); break;
      case '^': s.push(Math.pow(o1, o2)); break;
      default: throw new Error(`Unrecognized operator: [${t}]`);
    }
  }
  console.log(`${t}: ${s}`);
}

if (s.length > 1) {
  throw new Error(`${s}: insufficient operators.`);
}


Parsing/RPN calculator algorithm

Solution:
def op_pow(stack):
    b = stack.pop(); a = stack.pop()
    stack.append( a ** b )
def op_mul(stack):
    b = stack.pop(); a = stack.pop()
    stack.append( a * b )
def op_div(stack):
    b = stack.pop(); a = stack.pop()
    stack.append( a / b )
def op_add(stack):
    b = stack.pop(); a = stack.pop()
    stack.append( a + b )
def op_sub(stack):
    b = stack.pop(); a = stack.pop()
    stack.append( a - b )
def op_num(stack, num):
    stack.append( num )

ops = {
 '^': op_pow,
 '*': op_mul,
 '/': op_div,
 '+': op_add,
 '-': op_sub,
 }

def get_input(inp = None):
    'Inputs an expression and returns list of tokens'

    if inp is None:
        inp = input('expression: ')
    tokens = inp.strip().split()
    return tokens

def rpn_calc(tokens):
    stack = []
    table = ['TOKEN,ACTION,STACK'.split(',')]
    for token in tokens:
        if token in ops:
            action = 'Apply op to top of stack'
            ops[token](stack)
            table.append( (token, action, ' '.join(str(s) for s in stack)) )
        else:
            action = 'Push num onto top of stack'
            op_num(stack, eval(token))
            table.append( (token, action, ' '.join(str(s) for s in stack)) )
    return table

if __name__ == '__main__':
    rpn = '3 4 2 * 1 5 - 2 3 ^ ^ / +'
    print( 'For RPN expression: %r\n' % rpn )
    rp = rpn_calc(get_input(rpn))
    maxcolwidths = [max(len(y) for y in x) for x in zip(*rp)]
    row = rp[0]
    print( ' '.join('{cell:^{width}}'.format(width=width, cell=cell) for (width, cell) in zip(maxcolwidths, row)))
    for row in rp[1:]:
        print( ' '.join('{cell:<{width}}'.format(width=width, cell=cell) for (width, cell) in zip(maxcolwidths, row)))

    print('\n The final output value is: %r' % rp[-1][2])


Parsing/RPN to infix conversion

;Task:
Create a program that takes an infix notation.

* Assume an input of a correct, space separated, string of tokens
* Generate a space separated output string representing the same expression in infix notation
* Show how the major datastructure of your algorithm changes with each new token parsed.
* Test with the following input RPN strings then print and display the output here.
:::::{| class="wikitable"
! RPN input !! sample output
|- || align="center"
| 3 4 2 * 1 5 - 2 3 ^ ^ / +|| 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
|- || align="center"
| 1 2 + 3 4 + ^ 5 6 + ^|| ( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )
|}

* Operator precedence and operator associativity is given in this table:
::::::::{| class="wikitable"

! operator !! associativity !! operation
|- || align="center"
|                    ^   ||  4  ||  right  ||  exponentiation
|- || align="center"
|                    *   ||  3  ||   left  ||  multiplication
|- || align="center"
|                    /   ||  3  ||   left  ||     division
|- || align="center"
|                    +   ||  2  ||   left  ||     addition
|- || align="center"
|                    -   ||  2  ||   left  ||   subtraction
|}

;See also:
*   [[Parsing/Shunting-yard algorithm]]   for a method of generating an RPN from an infix expression.
*   [[Parsing/RPN calculator algorithm]]   for a method of calculating a final value from this output RPN expression.
*   [http://www.rubyquiz.com/quiz148.html Postfix to infix]   from the RubyQuiz site.

Solution:
#include
#include
#include

char** components;
int counter = 0;

typedef struct elem{
	char data[10];
	struct elem* left;
	struct elem* right;
}node;

typedef node* tree;

int precedenceCheck(char oper1,char oper2){
	return (oper1==oper2)? 0:(oper1=='^')? 1:(oper2=='^')? 2:(oper1=='/')? 1:(oper2=='/')? 2:(oper1=='*')? 1:(oper2=='*')? 2:(oper1=='+')? 1:(oper2=='+')? 2:(oper1=='-')? 1:2;
}

int isOperator(char c){
	return (c=='+'||c=='-'||c=='*'||c=='/'||c=='^');
}

void inorder(tree t){
	if(t!=NULL){
		if(t->left!=NULL && isOperator(t->left->data[0])==1 && (precedenceCheck(t->data[0],t->left->data[0])==1 || (precedenceCheck(t->data[0],t->left->data[0])==0 && t->data[0]=='^'))){
			printf("(");
			inorder(t->left);
			printf(")");
		}
		else
			inorder(t->left);

		printf(" %s ",t->data);

		if(t->right!=NULL && isOperator(t->right->data[0])==1 && (precedenceCheck(t->data[0],t->right->data[0])==1 || (precedenceCheck(t->data[0],t->right->data[0])==0 && t->data[0]!='^'))){
			printf("(");
			inorder(t->right);
			printf(")");
		}
		else
			inorder(t->right);
	}
}

char* getNextString(){
	if(counter<0){
		printf("\nInvalid RPN !");
		exit(0);
	}
	return components[counter--];
}

tree buildTree(char* obj,char* trace){
	tree t = (tree)malloc(sizeof(node));

	strcpy(t->data,obj);

	t->right = (isOperator(obj[0])==1)?buildTree(getNextString(),trace):NULL;
	t->left = (isOperator(obj[0])==1)?buildTree(getNextString(),trace):NULL;

	if(trace!=NULL){
			printf("\n");
			inorder(t);
	}

	return t;
}

int checkRPN(){
	int i, operSum = 0, numberSum = 0;

	if(isOperator(components[counter][0])==0)
		return 0;

	for(i=0;i<=counter;i++)
		(isOperator(components[i][0])==1)?operSum++:numberSum++;

	return (numberSum - operSum == 1);
}

void buildStack(char* str){
	int i;
	char* token;

	for(i=0;str[i]!=00;i++)
		if(str[i]==' ')
			counter++;

	components = (char**)malloc((counter + 1)*sizeof(char*));

	token = strtok(str," ");

	i = 0;

	while(token!=NULL){
		components[i] = (char*)malloc(strlen(token)*sizeof(char));
		strcpy(components[i],token);
		token = strtok(NULL," ");
		i++;
	}
}

int main(int argC,char* argV[]){
	int i;
	tree t;

	if(argC==1)
		printf("Usage : %s  ",argV[0]);
	else{
		buildStack(argV[1]);

		if(checkRPN()==0){
			printf("\nInvalid RPN !");
			return 0;
		}

		t = buildTree(getNextString(),argV[2]);

		printf("\nFinal infix expression : ");
		inorder(t);
	}

	return 0;
}


Parsing/RPN to infix conversion

Solution:
const Associativity = {
    /** a / b / c = (a / b) / c */
    left: 0,
    /** a ^ b ^ c = a ^ (b ^ c) */
    right: 1,
    /** a + b + c = (a + b) + c = a + (b + c) */
    both: 2,
};
const operators = {
    '+': { precedence: 2, associativity: Associativity.both },
    '-': { precedence: 2, associativity: Associativity.left },
    '*': { precedence: 3, associativity: Associativity.both },
    '/': { precedence: 3, associativity: Associativity.left },
    '^': { precedence: 4, associativity: Associativity.right },
};
class NumberNode {
    constructor(text) { this.text = text; }
    toString() { return this.text; }
}
class InfixNode {
    constructor(fnname, operands) {
        this.fnname = fnname;
        this.operands = operands;
    }
    toString(parentPrecedence = 0) {
        const op = operators[this.fnname];
        const leftAdd = op.associativity === Associativity.right ? 0.01 : 0;
        const rightAdd = op.associativity === Associativity.left ? 0.01 : 0;
        if (this.operands.length !== 2) throw Error("invalid operand count");
        const result = this.operands[0].toString(op.precedence + leftAdd)
            +` ${this.fnname} ${this.operands[1].toString(op.precedence + rightAdd)}`;
        if (parentPrecedence > op.precedence) return `( ${result} )`;
        else return result;
    }
}
function rpnToTree(tokens) {
    const stack = [];
    console.log(`input = ${tokens}`);
    for (const token of tokens.split(" ")) {
        if (token in operators) {
            const op = operators[token], arity = 2; // all of these operators take 2 arguments
            if (stack.length < arity) throw Error("stack error");
            stack.push(new InfixNode(token, stack.splice(stack.length - arity)));
        }
        else stack.push(new NumberNode(token));
        console.log(`read ${token}, stack = [${stack.join(", ")}]`);
    }
    if (stack.length !== 1) throw Error("stack error " + stack);
    return stack[0];
}
const tests = [
    ["3 4 2 * 1 5 - 2 3 ^ ^ / +", "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3"],
    ["1 2 + 3 4 + ^ 5 6 + ^", "( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )"],
    ["1 2 3 + +", "1 + 2 + 3"] // test associativity (1+(2+3)) == (1+2+3)
];
for (const [inp, oup] of tests) {
    const realOup = rpnToTree(inp).toString();
    console.log(realOup === oup ? "Correct!" : "Incorrect!");
}


Parsing/RPN to infix conversion

Solution:
"""
>>> # EXAMPLE USAGE
>>> result = rpn_to_infix('3 4 2 * 1 5 - 2 3 ^ ^ / +', VERBOSE=True)
TOKEN  STACK
3      ['3']
4      ['3', '4']
2      ['3', '4', '2']
*      ['3', Node('2','*','4')]
1      ['3', Node('2','*','4'), '1']
5      ['3', Node('2','*','4'), '1', '5']
-      ['3', Node('2','*','4'), Node('5','-','1')]
2      ['3', Node('2','*','4'), Node('5','-','1'), '2']
3      ['3', Node('2','*','4'), Node('5','-','1'), '2', '3']
^      ['3', Node('2','*','4'), Node('5','-','1'), Node('3','^','2')]
^      ['3', Node('2','*','4'), Node(Node('3','^','2'),'^',Node('5','-','1'))]
/      ['3', Node(Node(Node('3','^','2'),'^',Node('5','-','1')),'/',Node('2','*','4'))]
+      [Node(Node(Node(Node('3','^','2'),'^',Node('5','-','1')),'/',Node('2','*','4')),'+','3')]
"""

prec_dict =  {'^':4, '*':3, '/':3, '+':2, '-':2}
assoc_dict = {'^':1, '*':0, '/':0, '+':0, '-':0}

class Node:
    def __init__(self,x,op,y=None):
        self.precedence = prec_dict[op]
        self.assocright = assoc_dict[op]
        self.op = op
        self.x,self.y = x,y

    def __str__(self):
        """
        Building an infix string that evaluates correctly is easy.
        Building an infix string that looks pretty and evaluates
        correctly requires more effort.
        """
        # easy case, Node is unary
        if self.y == None:
            return '%s(%s)'%(self.op,str(self.x))

        # determine left side string
        str_y = str(self.y)
        if  self.y < self or \
            (self.y == self and self.assocright) or \
            (str_y[0] is '-' and self.assocright):

            str_y = '(%s)'%str_y
        # determine right side string and operator
        str_x = str(self.x)
        str_op = self.op
        if self.op is '+' and not isinstance(self.x, Node) and str_x[0] is '-':
            str_x = str_x[1:]
            str_op = '-'
        elif self.op is '-' and not isinstance(self.x, Node) and str_x[0] is '-':
            str_x = str_x[1:]
            str_op = '+'
        elif self.x < self or \
             (self.x == self and not self.assocright and \
              getattr(self.x, 'op', 1) != getattr(self, 'op', 2)):

            str_x = '(%s)'%str_x
        return ' '.join([str_y, str_op, str_x])

    def __repr__(self):
        """
        >>> repr(Node('3','+','4')) == repr(eval(repr(Node('3','+','4'))))
        True
        """
        return 'Node(%s,%s,%s)'%(repr(self.x), repr(self.op), repr(self.y))

    def __lt__(self, other):
        if isinstance(other, Node):
            return self.precedence < other.precedence
        return self.precedence < prec_dict.get(other,9)

    def __gt__(self, other):
        if isinstance(other, Node):
            return self.precedence > other.precedence
        return self.precedence > prec_dict.get(other,9)

    def __eq__(self, other):
        if isinstance(other, Node):
            return self.precedence == other.precedence
        return self.precedence > prec_dict.get(other,9)

def rpn_to_infix(s, VERBOSE=False):
    """

    converts rpn notation to infix notation for string s

    """
    if VERBOSE : print('TOKEN  STACK')

    stack=[]
    for token in s.replace('^','^').split():
        if token in prec_dict:
            stack.append(Node(stack.pop(),token,stack.pop()))
        else:
            stack.append(token)

        # can't use \t in order to make global docstring pass doctest
        if VERBOSE : print(token+' '*(7-len(token))+repr(stack))

    return str(stack[0])

strTest = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
strResult = rpn_to_infix(strTest, VERBOSE=False)
print ("Input: ",strTest)
print ("Output:",strResult)

print()

strTest = "1 2 + 3 4 + ^ 5 6 + ^"
strResult = rpn_to_infix(strTest, VERBOSE=False)
print ("Input: ",strTest)
print ("Output:",strResult)


Parsing/Shunting-yard algorithm

;Task:
Given the operator characteristics and input from the Shunting-yard algorithm page and tables, use the algorithm to show the changes in the operator stack and RPN output
as each individual token is processed.

* Assume an input of a correct, space separated, string of tokens representing an infix expression
* Generate a space separated output string representing the RPN
* Test with the input string:
::::  3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
* print and display the output here.
* Operator precedence is given in this table:
:{| class="wikitable"

! operator !! associativity !! operation
|- || align="center"
|                     ^   ||  4  ||  right  ||  exponentiation
|- || align="center"
|                     *   ||  3  ||  left   ||  multiplication
|- || align="center"
|                     /   ||  3  ||  left   ||  division
|- || align="center"
|                     +   ||  2  ||  left   ||  addition
|- || align="center"
|                     -   ||  2  ||  left   ||  subtraction
|}

;Extra credit
Add extra text explaining the actions and an optional comment for the action on receipt of each token.

;Note
The handling of functions and arguments is not required.

;See also:
* [[Parsing/RPN calculator algorithm]] for a method of calculating a final value from this output RPN expression.
* [[Parsing/RPN to infix conversion]].

Solution:
#include
#include
#include

typedef struct {
	const char *s;
	int len, prec, assoc;
} str_tok_t;

typedef struct {
	const char * str;
	int assoc, prec;
	regex_t re;
} pat_t;

enum assoc { A_NONE, A_L, A_R };
pat_t pat_eos = {"", A_NONE, 0};

pat_t pat_ops[] = {
	{"^\\)",	A_NONE, -1},
	{"^\\*\\*",	A_R, 3},
	{"^\\^",	A_R, 3},
	{"^\\*",	A_L, 2},
	{"^/",		A_L, 2},
	{"^\\+",	A_L, 1},
	{"^-",		A_L, 1},
	{0}
};

pat_t pat_arg[] = {
	{"^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?"},
	{"^[a-zA-Z_][a-zA-Z_0-9]*"},
	{"^\\(", A_L, -1},
	{0}
};

str_tok_t stack[256]; /* assume these are big enough */
str_tok_t queue[256];
int l_queue, l_stack;
#define qpush(x) queue[l_queue++] = x
#define spush(x) stack[l_stack++] = x
#define spop()   stack[--l_stack]

void display(const char *s)
{
	int i;
	printf("\033[1;1H\033[JText | %s", s);
	printf("\nStack| ");
	for (i = 0; i < l_stack; i++)
		printf("%.*s ", stack[i].len, stack[i].s); // uses C99 format strings
	printf("\nQueue| ");
	for (i = 0; i < l_queue; i++)
		printf("%.*s ", queue[i].len, queue[i].s);
	puts("\n\n");
	getchar();
}

int prec_booster;

#define fail(s1, s2) {fprintf(stderr, "[Error %s] %s\n", s1, s2); return 0;}

int init(void)
{
	int i;
	pat_t *p;

	for (i = 0, p = pat_ops; p[i].str; i++)
		if (regcomp(&(p[i].re), p[i].str, REG_NEWLINE|REG_EXTENDED))
			fail("comp", p[i].str);

	for (i = 0, p = pat_arg; p[i].str; i++)
		if (regcomp(&(p[i].re), p[i].str, REG_NEWLINE|REG_EXTENDED))
			fail("comp", p[i].str);

	return 1;
}

pat_t* match(const char *s, pat_t *p, str_tok_t * t, const char **e)
{
	int i;
	regmatch_t m;

	while (*s == ' ') s++;
	*e = s;

	if (!*s) return &pat_eos;

	for (i = 0; p[i].str; i++) {
		if (regexec(&(p[i].re), s, 1, &m, REG_NOTEOL))
			continue;
		t->s = s;
		*e = s + (t->len = m.rm_eo - m.rm_so);
		return p + i;
	}
	return 0;
}

int parse(const char *s) {
	pat_t *p;
	str_tok_t *t, tok;

	prec_booster = l_queue = l_stack = 0;
	display(s);
	while (*s) {
		p = match(s, pat_arg, &tok, &s);
		if (!p || p == &pat_eos) fail("parse arg", s);

		/* Odd logic here. Don't actually stack the parens: don't need to. */
		if (p->prec == -1) {
			prec_booster += 100;
			continue;
		}
		qpush(tok);
		display(s);

re_op:		p = match(s, pat_ops, &tok, &s);
		if (!p) fail("parse op", s);

		tok.assoc = p->assoc;
		tok.prec = p->prec;

		if (p->prec > 0)
			tok.prec = p->prec + prec_booster;
		else if (p->prec == -1) {
			if (prec_booster < 100)
				fail("unmatched )", s);
			tok.prec = prec_booster;
		}

		while (l_stack) {
			t = stack + l_stack - 1;
			if (!(t->prec == tok.prec && t->assoc == A_L)
					&& t->prec <= tok.prec)
				break;
			qpush(spop());
			display(s);
		}

		if (p->prec == -1) {
			prec_booster -= 100;
			goto re_op;
		}

		if (!p->prec) {
			display(s);
			if (prec_booster)
				fail("unmatched (", s);
			return 1;
		}

		spush(tok);
		display(s);
	}

	if (p->prec > 0)
		fail("unexpected eol", s);

	return 1;
}

int main()
{
	int i;
	const char *tests[] = {
		"3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3",	/* RC mandated: OK */
		"123",					/* OK */
		"3+4 * 2 / ( 1 - 5 ) ^ 2 ^ 3.14",	/* OK */
		"(((((((1+2+3**(4 + 5))))))",		/* bad parens */
		"a^(b + c/d * .1e5)!",			/* unknown op */
		"(1**2)**3",				/* OK */
		"2 + 2 *",				/* unexpected eol */
		0
	};

	if (!init()) return 1;
	for (i = 0; tests[i]; i++) {
		printf("Testing string `%s'   \n", tests[i]);
		getchar();

		printf("string `%s': %s\n\n", tests[i],
			parse(tests[i]) ? "Ok" : "Error");
	}

	return 0;
}


Parsing/Shunting-yard algorithm

Solution:
function Stack() {
  this.dataStore = [];
  this.top = 0;
  this.push = push;
  this.pop = pop;
  this.peek = peek;
  this.length = length;
}

function push(element) {
  this.dataStore[this.top++] = element;
}

function pop() {
  return this.dataStore[--this.top];
}

function peek() {
  return this.dataStore[this.top-1];
}

function length() {
  return this.top;
}

var infix = "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3";
infix = infix.replace(/\s+/g, ''); // remove spaces, so infix[i]!=" "

var s = new Stack();
var ops = "-+/*^";
var precedence = {"^":4, "*":3, "/":3, "+":2, "-":2};
var associativity = {"^":"Right", "*":"Left", "/":"Left", "+":"Left", "-":"Left"};
var token;
var postfix = "";
var o1, o2;

for (var i = 0; i < infix.length; i++) {
  token = infix[i];
  if (token >= "0" && token <= "9") { // if token is operand (here limited to 0 <= x <= 9)
    postfix += token + " ";
  }
  else if (ops.indexOf(token) != -1) { // if token is an operator
    o1 = token;
    o2 = s.peek();
    while (ops.indexOf(o2)!=-1 && ( // while operator token, o2, on top of the stack
      // and o1 is left-associative and its precedence is less than or equal to that of o2
      (associativity[o1] == "Left" && (precedence[o1] <= precedence[o2]) ) ||
      // the algorithm on wikipedia says: or o1 precedence < o2 precedence, but I think it should be
      // or o1 is right-associative and its precedence is less than that of o2
      (associativity[o1] == "Right" && (precedence[o1] < precedence[o2]))
      )){
        postfix += o2 + " "; // add o2 to output queue
        s.pop(); // pop o2 of the stack
        o2 = s.peek(); // next round
    }
    s.push(o1); // push o1 onto the stack
  }
  else if (token == "(") { // if token is left parenthesis
    s.push(token); // then push it onto the stack
  }
  else if (token == ")") { // if token is right parenthesis
    while (s.peek() != "("){ // until token at top is (
      postfix += s.pop() + " ";
    }
    s.pop(); // pop (, but not onto the output queue
  }
}
postfix += s.dataStore.reverse().join(" ");
print(postfix);


Parsing/Shunting-yard algorithm

Solution:
from collections import namedtuple
from pprint import pprint as pp

OpInfo = namedtuple('OpInfo', 'prec assoc')
L, R = 'Left Right'.split()

ops = {
 '^': OpInfo(prec=4, assoc=R),
 '*': OpInfo(prec=3, assoc=L),
 '/': OpInfo(prec=3, assoc=L),
 '+': OpInfo(prec=2, assoc=L),
 '-': OpInfo(prec=2, assoc=L),
 '(': OpInfo(prec=9, assoc=L),
 ')': OpInfo(prec=0, assoc=L),
 }

NUM, LPAREN, RPAREN = 'NUMBER ( )'.split()

def get_input(inp = None):
    'Inputs an expression and returns list of (TOKENTYPE, tokenvalue)'

    if inp is None:
        inp = input('expression: ')
    tokens = inp.strip().split()
    tokenvals = []
    for token in tokens:
        if token in ops:
            tokenvals.append((token, ops[token]))
        #elif token in (LPAREN, RPAREN):
        #    tokenvals.append((token, token))
        else:
            tokenvals.append((NUM, token))
    return tokenvals

def shunting(tokenvals):
    outq, stack = [], []
    table = ['TOKEN,ACTION,RPN OUTPUT,OP STACK,NOTES'.split(',')]
    for token, val in tokenvals:
        note = action = ''
        if token is NUM:
            action = 'Add number to output'
            outq.append(val)
            table.append( (val, action, ' '.join(outq), ' '.join(s[0] for s in stack), note) )
        elif token in ops:
            t1, (p1, a1) = token, val
            v = t1
            note = 'Pop ops from stack to output'
            while stack:
                t2, (p2, a2) = stack[-1]
                if (a1 == L and p1 <= p2) or (a1 == R and p1 < p2):
                    if t1 != RPAREN:
                        if t2 != LPAREN:
                            stack.pop()
                            action = '(Pop op)'
                            outq.append(t2)
                        else:
                            break
                    else:
                        if t2 != LPAREN:
                            stack.pop()
                            action = '(Pop op)'
                            outq.append(t2)
                        else:
                            stack.pop()
                            action = '(Pop & discard "(")'
                            table.append( (v, action, ' '.join(outq), ' '.join(s[0] for s in stack), note) )
                            break
                    table.append( (v, action, ' '.join(outq), ' '.join(s[0] for s in stack), note) )
                    v = note = ''
                else:
                    note = ''
                    break
                note = ''
            note = ''
            if t1 != RPAREN:
                stack.append((token, val))
                action = 'Push op token to stack'
            else:
                action = 'Discard ")"'
            table.append( (v, action, ' '.join(outq), ' '.join(s[0] for s in stack), note) )
    note = 'Drain stack to output'
    while stack:
        v = ''
        t2, (p2, a2) = stack[-1]
        action = '(Pop op)'
        stack.pop()
        outq.append(t2)
        table.append( (v, action, ' '.join(outq), ' '.join(s[0] for s in stack), note) )
        v = note = ''
    return table

if __name__ == '__main__':
    infix = '3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3'
    print( 'For infix expression: %r\n' % infix )
    rp = shunting(get_input(infix))
    maxcolwidths = [len(max(x, key=len)) for x in zip(*rp)]
    row = rp[0]
    print( ' '.join('{cell:^{width}}'.format(width=width, cell=cell) for (width, cell) in zip(maxcolwidths, row)))
    for row in rp[1:]:
        print( ' '.join('{cell:<{width}}'.format(width=width, cell=cell) for (width, cell) in zip(maxcolwidths, row)))

    print('\n The final output RPN is: %r' % rp[-1][2])


Pascal's triangle/Puzzle

This puzzle involves a [http://xunor.free.fr/en/riddles/auto/pyramidnb.php Pascals Triangle], also known as a [http://xunor.free.fr/en/riddles/auto/pyramidnb.php Pyramid of Numbers].

           [ 151]
          [  ][  ]
        [40][  ][  ]
      [  ][  ][  ][  ]
    [ X][11][ Y][ 4][ Z]

Each brick of the pyramid is the sum of the two bricks situated below it.
Of the three missing numbers at the base of the pyramid,
the middle one is the sum of the other two (that is, Y = X + Z).

;Task:
Write a program to find a solution to this puzzle.

Solution:
/* Pascal's pyramid solver
 *
 *               [top]
 *            [   ] [   ]
 *         [mid] [   ] [   ]
 *      [   ] [   ] [   ] [   ]
 *   [ x ] [ a ] [ y ] [ b ] [ z ]
 *             x + z = y
 *
 * This solution makes use of a little bit of mathematical observation,
 * such as the fact that top = 4(a+b) + 7(x+z) and mid = 2x + 2a + z.
 */

#include
#include

void pascal(int a, int b, int mid, int top, int* x, int* y, int* z)
{
    double ytemp = (top - 4 * (a + b)) / 7.;
    if(fmod(ytemp, 1.) >= 0.0001)
    {
        x = 0;
        return;
    }
    *y = ytemp;
    *x = mid - 2 * a - *y;
    *z = *y - *x;
}
int main()
{
    int a = 11, b = 4, mid = 40, top = 151;
    int x, y, z;
    pascal(a, b, mid, top, &x, &y, &z);
    if(x != 0)
        printf("x: %d, y: %d, z: %d\n", x, y, z);
    else printf("No solution\n");

    return 0;
}


Pascal's triangle/Puzzle

Solution:
# Pyramid solver
#            [151]
#         [   ] [   ]
#      [ 40] [   ] [   ]
#   [   ] [   ] [   ] [   ]
#[ X ] [ 11] [ Y ] [ 4 ] [ Z ]
#  X -Y + Z = 0

def combine( snl, snr ):

	cl = {}
	if isinstance(snl, int):
		cl['1'] = snl
	elif isinstance(snl, string):
		cl[snl] = 1
	else:
		cl.update( snl)

	if isinstance(snr, int):
		n = cl.get('1', 0)
		cl['1'] = n + snr
	elif isinstance(snr, string):
		n = cl.get(snr, 0)
		cl[snr] = n + 1
	else:
		for k,v in snr.items():
			n = cl.get(k, 0)
			cl[k] = n+v
	return cl

def constrain(nsum, vn ):
	nn = {}
	nn.update(vn)
	n = nn.get('1', 0)
	nn['1'] = n - nsum
	return nn

def makeMatrix( constraints ):
	vmap = set()
	for c in constraints:
		vmap.update( c.keys())
	vmap.remove('1')
	nvars = len(vmap)
	vmap = sorted(vmap)		# sort here so output is in sorted order
	mtx = []
	for c in constraints:
		row = []
		for vv in vmap:
			row.append(float(c.get(vv, 0)))
		row.append(-float(c.get('1',0)))
		mtx.append(row)

	if len(constraints) == nvars:
		print 'System appears solvable'
	elif len(constraints) < nvars:
		print 'System is not solvable - needs more constraints.'
	return mtx, vmap

def SolvePyramid( vl, cnstr ):

	vl.reverse()
	constraints = [cnstr]
	lvls = len(vl)
	for lvln in range(1,lvls):
		lvd = vl[lvln]
		for k in range(lvls - lvln):
			sn = lvd[k]
			ll = vl[lvln-1]
			vn = combine(ll[k], ll[k+1])
			if sn is None:
				lvd[k] = vn
			else:
				constraints.append(constrain( sn, vn ))

	print 'Constraint Equations:'
	for cstr in constraints:
		fset = ('%d*%s'%(v,k) for k,v in cstr.items() )
		print ' + '.join(fset), ' = 0'

	mtx,vmap = makeMatrix(constraints)

	MtxSolve(mtx)

	d = len(vmap)
	for j in range(d):
		print vmap[j],'=', mtx[j][d]

def MtxSolve(mtx):
	# Simple Matrix solver...

	mDim = len(mtx)			# dimension---
	for j in range(mDim):
		rw0= mtx[j]
		f = 1.0/rw0[j]
		for k in range(j, mDim+1):
			rw0[k] *= f

		for l in range(1+j,mDim):
			rwl = mtx[l]
			f = -rwl[j]
			for k in range(j, mDim+1):
				rwl[k] += f * rw0[k]

	# backsolve part ---
	for j1 in range(1,mDim):
		j = mDim - j1
		rw0= mtx[j]
		for l in range(0, j):
			rwl = mtx[l]
			f = -rwl[j]
			rwl[j]    += f * rw0[j]
			rwl[mDim] += f * rw0[mDim]

	return mtx

p = [ [151], [None,None], [40,None,None], [None,None,None,None], ['X', 11, 'Y', 4, 'Z'] ]
addlConstraint = { 'X':1, 'Y':-1, 'Z':1, '1':0 }
SolvePyramid( p, addlConstraint)


Pascal matrix generation

A pascal matrix is a two-dimensional square matrix holding numbers from   binomial coefficients   and which can be shown as    nCr.

Shown below are truncated   5-by-5   matrices   M[i, j]   for   i,j   in range   0..4.

A Pascal upper-triangular matrix that is populated with   jCi:

[[1, 1, 1, 1, 1],
 [0, 1, 2, 3, 4],
 [0, 0, 1, 3, 6],
 [0, 0, 0, 1, 4],
 [0, 0, 0, 0, 1]]

A Pascal lower-triangular matrix that is populated with   iCj   (the transpose of the upper-triangular matrix):

[[1, 0, 0, 0, 0],
 [1, 1, 0, 0, 0],
 [1, 2, 1, 0, 0],
 [1, 3, 3, 1, 0],
 [1, 4, 6, 4, 1]]

A Pascal symmetric matrix that is populated with   i+jCi:

[[1, 1, 1, 1, 1],
 [1, 2, 3, 4, 5],
 [1, 3, 6, 10, 15],
 [1, 4, 10, 20, 35],
 [1, 5, 15, 35, 70]]

;Task:
Write functions capable of generating each of the three forms of   n-by-n   matrices.

Use those functions to display upper, lower, and symmetric Pascal   5-by-5   matrices on this page.

The output should distinguish between different matrices and the rows of each matrix   (no showing a list of 25 numbers assuming the reader should split it into rows).

;Note:
The   [[Cholesky decomposition]]   of a Pascal symmetric matrix is the Pascal lower-triangle matrix of the same size.

Solution:
#include
#include

void pascal_low(int **mat, int n) {
    int i, j;

    for (i = 0; i < n; ++i)
        for (j = 0; j < n; ++j)
            if (i < j)
                mat[i][j] = 0;
            else if (i == j || j == 0)
                mat[i][j] = 1;
            else
                mat[i][j] = mat[i - 1][j - 1] + mat[i - 1][j];
}

void pascal_upp(int **mat, int n) {
    int i, j;

    for (i = 0; i < n; ++i)
        for (j = 0; j < n; ++j)
            if (i > j)
                mat[i][j] = 0;
            else if (i == j || i == 0)
                mat[i][j] = 1;
            else
                mat[i][j] = mat[i - 1][j - 1] + mat[i][j - 1];
}

void pascal_sym(int **mat, int n) {
    int i, j;

    for (i = 0; i < n; ++i)
        for (j = 0; j < n; ++j)
            if (i == 0 || j == 0)
                mat[i][j] = 1;
            else
                mat[i][j] = mat[i - 1][j] + mat[i][j - 1];
}

int main(int argc, char * argv[]) {
    int **mat;
    int i, j, n;

    /* Input size of the matrix */
    n = 5;

    /* Matrix allocation */
    mat = calloc(n, sizeof(int *));
    for (i = 0; i < n; ++i)
        mat[i] = calloc(n, sizeof(int));

    /* Matrix computation */
    printf("=== Pascal upper matrix ===\n");
    pascal_upp(mat, n);
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            printf("%4d%c", mat[i][j], j < n - 1 ? ' ' : '\n');

    printf("=== Pascal lower matrix ===\n");
    pascal_low(mat, n);
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            printf("%4d%c", mat[i][j], j < n - 1 ? ' ' : '\n');

    printf("=== Pascal symmetric matrix ===\n");
    pascal_sym(mat, n);
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            printf("%4d%c", mat[i][j], j < n - 1 ? ' ' : '\n');

    return 0;
}


Pascal matrix generation

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

    // -------------------PASCAL MATRIX--------------------

    // pascalMatrix :: ((Int, Int) -> (Int, Int)) ->
    // Int -> [Int]
    const pascalMatrix = f =>
        n => map(compose(binomialCoefficient, f))(
            range([0, 0], [n - 1, n - 1])
        );

    // binomialCoefficient :: (Int, Int) -> Int
    const binomialCoefficient = nk => {
        const [n, k] = Array.from(nk);
        return enumFromThenTo(k)(
            pred(k)
        )(1).reduceRight((a, x) => quot(
            a * succ(n - x)
        )(x), 1);
    };

    // ------------------------TEST------------------------
    // main :: IO ()
    const main = () => {
        const matrixSize = 5;
        console.log(intercalate('\n\n')(
            zipWith(
                k => xs => k + ':\n' + showMatrix(matrixSize)(xs)
            )(['Lower', 'Upper', 'Symmetric'])(
                apList(
                    map(pascalMatrix)([
                        identity, //              Lower
                        swap, //                  Upper
                        ([a, b]) => [a + b, b] // Symmetric
                    ])
                )([matrixSize])
            )
        ));
    };

    // ----------------------DISPLAY-----------------------

    // showMatrix :: Int -> [Int] -> String
    const showMatrix = n =>
        xs => {
            const
                ks = map(str)(xs),
                w = maximum(map(length)(ks));
            return unlines(
                map(unwords)(chunksOf(n)(
                    map(justifyRight(w)(' '))(ks)
                ))
            );
        };

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

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

    // apList (<*>) :: [(a -> b)] -> [a] -> [b]
    const apList = fs =>
        // The sequential application of each of a list
        // of functions to each of a list of values.
        xs => fs.flatMap(
            f => xs.map(f)
        );

    // chunksOf :: Int -> [a] -> [[a]]
    const chunksOf = n =>
        xs => enumFromThenTo(0)(n)(
            xs.length - 1
        ).reduce(
            (a, i) => a.concat([xs.slice(i, (n + i))]),
            []
        );

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (...fs) =>
        x => fs.reduceRight((a, f) => f(a), x);

    // concat :: [[a]] -> [a]
    // concat :: [String] -> String
    const concat = xs =>
        0 < xs.length ? (
            xs.every(x => 'string' === typeof x) ? (
                ''
            ) : []
        ).concat(...xs) : xs;

    // cons :: a -> [a] -> [a]
    const cons = x =>
        xs => [x].concat(xs);

    // enumFromThenTo :: Int -> Int -> Int -> [Int]
    const enumFromThenTo = x1 =>
        x2 => y => {
            const d = x2 - x1;
            return Array.from({
                length: Math.floor(y - x2) / d + 2
            }, (_, i) => x1 + (d * i));
        };

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

    // fst :: (a, b) -> a
    const fst = tpl =>
        // First member of a pair.
        tpl[0];

    // identity :: a -> a
    const identity = x =>
        // The identity function. (`id`, in Haskell)
        x;

    // intercalate :: String -> [String] -> String
    const intercalate = s =>
        // The concatenation of xs
        // interspersed with copies of s.
        xs => xs.join(s);

    // justifyRight :: Int -> Char -> String -> String
    const justifyRight = n =>
        // The string s, preceded by enough padding (with
        // the character c) to reach the string length n.
        c => s => n > s.length ? (
            s.padStart(n, c)
        ) : s;

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

    // liftA2List :: (a -> b -> c) -> [a] -> [b] -> [c]
    const liftA2List = f => xs => ys =>
        // The binary operator f lifted to a function over two
        // lists. f applied to each pair of arguments in the
        // cartesian product of xs and ys.
        xs.flatMap(
            x => ys.map(f(x))
        );

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

    // maximum :: Ord a => [a] -> a
    const maximum = xs =>
        // The largest value in a non-empty list.
        0 < xs.length ? (
            xs.slice(1).reduce(
                (a, x) => x > a ? (
                    x
                ) : a, xs[0]
            )
        ) : undefined;

    // pred :: Enum a => a -> a
    const pred = x =>
        x - 1;

    // quot :: Int -> Int -> Int
    const quot = n => m => Math.floor(n / m);

    // The list of values in the subrange defined by a bounding pair.

    // range([0, 2]) -> [0,1,2]
    // range([[0,0], [2,2]])
    //  -> [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]
    // range([[0,0,0],[1,1,1]])
    //  -> [[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]

    // range :: Ix a => (a, a) -> [a]
    function range() {
        const
            args = Array.from(arguments),
            ab = 1 !== args.length ? (
                args
            ) : args[0],
            [as, bs] = [ab[0], ab[1]].map(
                x => Array.isArray(x) ? (
                    x
                ) : (undefined !== x.type) &&
                (x.type.startsWith('Tuple')) ? (
                    Array.from(x)
                ) : [x]
            ),
            an = as.length;
        return (an === bs.length) ? (
            1 < an ? (
                traverseList(x => x)(
                    as.map((_, i) => enumFromTo(as[i])(bs[i]))
                )
            ) : enumFromTo(as[0])(bs[0])
        ) : [];
    };

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

    // str :: a -> String
    const str = x => x.toString();

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

    // swap :: (a, b) -> (b, a)
    const swap = ab =>
        // The pair ab with its order reversed.
        Tuple(ab[1])(
            ab[0]
        );

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = n =>
        // The first n elements of a list,
        // string of characters, or stream.
        xs => xs.slice(0, n);

    // traverseList :: (Applicative f) => (a -> f b) -> [a] -> f [b]
    const traverseList = f =>
        // Collected results of mapping each element
        // of a structure to an action, and evaluating
        // these actions from left to right.
        xs => 0 < xs.length ? (() => {
            const
                vLast = f(xs.slice(-1)[0]),
                t = vLast.type || 'List';
            return xs.slice(0, -1).reduceRight(
                (ys, x) => liftA2List(cons)(f(x))(ys),
                liftA2List(cons)(vLast)([
                    []
                ])
            );
        })() : [
            []
        ];

    // unlines :: [String] -> String
    const unlines = xs =>
        // A single string formed by the intercalation
        // of a list of strings with the newline character.
        xs.join('\n');

    // unwords :: [String] -> String
    const unwords = xs =>
        // A space-separated string derived
        // from a list of words.
        xs.join(' ');

    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f =>
        // A list constructed by zipping with a
        // custom function, rather than with the
        // default tuple constructor.
        xs => ys => {
            const
                lng = Math.min(length(xs), length(ys)),
                vs = take(lng)(ys);
            return take(lng)(xs)
                .map((x, i) => f(x)(vs[i]));
        };

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


Pascal matrix generation

Solution:
from pprint import pprint as pp

def pascal_upp(n):
    s = [[0] * n for _ in range(n)]
    s[0] = [1] * n
    for i in range(1, n):
        for j in range(i, n):
            s[i][j] = s[i-1][j-1] + s[i][j-1]
    return s

def pascal_low(n):
    # transpose of pascal_upp(n)
    return [list(x) for x in zip(*pascal_upp(n))]

def pascal_sym(n):
    s = [[1] * n for _ in range(n)]
    for i in range(1, n):
        for j in range(1, n):
            s[i][j] = s[i-1][j] + s[i][j-1]
    return s

if __name__ == "__main__":
    n = 5
    print("\nUpper:")
    pp(pascal_upp(n))
    print("\nLower:")
    pp(pascal_low(n))
    print("\nSymmetric:")
    pp(pascal_sym(n))


Password generator

Create a password generation program which will generate passwords containing random ASCII characters from the following groups:
          lower-case letters:  a ──► z
          upper-case letters:  A ──► Z
                      digits:  0 ──► 9
  other printable characters:  !"#$%&'()*+,-./:;<=>?@[]^_{|}~
  (the above character list excludes white-space, backslash and grave)

The generated password(s) must include   ''at least one''   (of each of the four groups):
    lower-case letter,
    upper-case letter,
    digit  (numeral),   and
    one  "other"  character.

The user must be able to specify the password length and the number of passwords to generate.

The passwords should be displayed or written to a file, one per line.

The randomness should be from a system source or library.

The program should implement a help option or button which should describe the program and options when invoked.

You may also allow the user to specify a seed value, and give the option of excluding visually similar characters.

For example:            Il1     O0     5S     2Z            where the characters are:
::::*   capital eye, lowercase ell, the digit one
::::*   capital oh, the digit zero
::::*   the digit five, capital ess
::::*   the digit two, capital zee

Solution:
#include
#include
#include

#define DEFAULT_LENGTH 4
#define DEFAULT_COUNT 1

char* symbols[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", "0123456789", "!\"#$%&'()*+,-./:;<=>?@[]^_{|}~"};
int length = DEFAULT_LENGTH;
int count = DEFAULT_COUNT;
unsigned seed;
char exSymbols = 0;

void GetPassword () {
    //create an array of values that determine the number of characters from each category
    int lengths[4] = {1, 1, 1, 1};
    int count = 4;
    while (count < length) {
        lengths[rand()%4]++;
        count++;
    }

    //loop through the array of lengths and set the characters in password
    char password[length + 1];
    for (int i = 0; i < length; ) {
        //pick which string to read from
        int str = rand()%4;
        if (!lengths[str])continue;   //if the number of characters for that string have been reached, continue to the next interation

        char c;
        switch (str) {
            case 2:
                c = symbols[str][rand()%10];
                while (exSymbols && (c == 'I' || c == 'l' || c == '1' || c == 'O' || c == '0' || c == '5' || c == 'S' || c == '2' || c == 'Z'))
                    c = symbols[str][rand()%10];
                password[i] = c;
            break;

            case 3:
                c = symbols[str][rand()%30];
                while (exSymbols && (c == 'I' || c == 'l' || c == '1' || c == 'O' || c == '0' || c == '5' || c == 'S' || c == '2' || c == 'Z'))
                    c = symbols[str][rand()%30];
                password[i] = c;
            break;

            default:
                c = symbols[str][rand()%26];
                while (exSymbols && (c == 'I' || c == 'l' || c == '1' || c == 'O' || c == '0' || c == '5' || c == 'S' || c == '2' || c == 'Z'))
                    c = symbols[str][rand()%26];
                password[i] = c;
            break;
        }

        i++;
        lengths[str]--;
    }

    password [length] = '\0';
    printf ("%s\n", password);
}

int main (int argc, char* argv[]) {
    seed = (unsigned)time(NULL);

    //handle user input from the command line
    for (int i = 1; i < argc; i++) {
        switch (argv[i][1]) {
            case 'l':
                if (sscanf (argv[i+1], "%d", &length) != 1) {
                    puts ("Unrecognized input. Syntax: -l [integer]");
                    return -1;
                }

                if (length < 4) {
                    puts ("Password length must be at least 4 characters.");
                    return -1;
                }
                i++;
            break;

            case 'c':
                if (sscanf (argv[i+1], "%d", &count) != 1) {
                    puts ("Unrecognized input. Syntax: -c [integer]");
                    return -1;
                }

                if (count <= 0) {
                    puts ("Count must be at least 1.");
                    return -1;
                }
                i++;
            break;

            case 's':
                if (sscanf (argv[i+1], "%d", &seed) != 1) {
                    puts ("Unrecognized input. Syntax: -s [integer]");
                    return -1;
                }
                i++;
            break;

            case 'e':
                exSymbols = 1;
            break;

            default:
                help:
                printf ("Help:\nThis program generates a random password.\n"
                "Commands:"
                   "Set password length: -l [integer]\n"
                   "Set password count: -c [integer]\n"
                   "Set seed: -s [integer]\n"
                   "Exclude similiar characters: -e\n"
                   "Display help: -h");
                return 0;
            break;
        }
    }

    srand (seed);

    for (int i = 0; i < count; i++)
        GetPassword();

    return 0;
}