Negative base numbers

Negative base numbers are an alternate way to encode numbers without the need for a minus sign. Various negative bases may be used including negadecimal (base -10), negabinary (-2) and negaternary (-3).Negabinary on Wolfram MathworldNegative base on Wikipedia

;Task:

*Encode the decimal number 10 as negabinary (expect 11110)
*Encode the decimal number 146 as negaternary (expect 21102)
*Encode the decimal number 15 as negadecimal (expect 195)
*In each of the above cases, convert the encoded number back to decimal.

;extra credit:

* supply an integer, that when encoded to base   -62   (or something "higher"),   expresses the name of the language being used   (with correct capitalization).   If the computer language has non-alphanumeric characters,   try to encode them into the negatory numerals,   or use other characters instead.

Solution:
package main

import (
    "fmt"
    "log"
    "strings"
)

const digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

func reverse(bs []byte) []byte {
    for i, j := 0, len(bs)-1; i < len(bs)/2; i, j = i+1, j-1 {
        bs[i], bs[j] = bs[j], bs[i]
    }
    return bs
}

func encodeNegBase(n, b int64) (string, error) {
    if b < -62 || b > -1 {
        return "", fmt.Errorf("base must be between -62 and -1 inclusive")
    }
    if n == 0 {
        return "0", nil
    }
    var out []byte
    for n != 0 {
        rem := n % b
        n /= b
        if rem < 0 {
            n++
            rem -= b
        }
        out = append(out, digits[int(rem)])
    }
    reverse(out)
    return string(out), nil
}

func decodeNegBase(ns string, b int64) (int64, error) {
    if b < -62 || b > -1 {
        return 0, fmt.Errorf("base must be between -62 and -1 inclusive")
    }
    if ns == "0" {
        return 0, nil
    }
    total := int64(0)
    bb := int64(1)
    bs := []byte(ns)
    reverse(bs)
    for _, c := range bs {
        total += int64(strings.IndexByte(digits, c)) * bb
        bb *= b
    }
    return total, nil
}

func main() {
    numbers := []int64{10, 146, 15, -942, 1488588316238}
    bases := []int64{-2, -3, -10, -62, -62}
    for i := 0; i < len(numbers); i++ {
        n := numbers[i]
        b := bases[i]
        ns, err := encodeNegBase(n, b)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("%13d encoded in base %-3d = %s\n", n, b, ns)
        n, err = decodeNegBase(ns, b)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("%13s decoded in base %-3d = %d\n\n", ns, b, n)
    }
}


Nested function

In many languages, functions can be nested, resulting in outer functions and inner functions. The inner function can access variables from the outer function. In most languages, the inner function can also modify variables in the outer function.

;Task:
Write a program consisting of two nested functions that prints the following text.

 1. first
 2. second
 3. third

The outer function (called MakeList or equivalent) is responsible for creating the list as a whole and is given the separator ". " as argument. It also defines a counter variable to keep track of the item number. This demonstrates how the inner function can influence the variables in the outer function.

The inner function (called MakeItem or equivalent) is responsible for creating a list item. It accesses the separator from the outer function and modifies the counter.

;References:
:* Nested function

Solution:
package main
import "fmt"

func makeList(separator string) string {
    counter := 1

    makeItem := func(item string) string {
        result := fmt.Sprintf("%d%s%s\n", counter, separator, item)
        counter += 1
        return result
    }

    return makeItem("first") + makeItem("second") + makeItem("third")
}

func main() {
    fmt.Print(makeList(". "))
}


Nested templated data

A template for data is an arbitrarily nested tree of integer indices.

Data payloads are given as a separate mapping, array or other simpler, flat,
association of indices to individual items of data, and are strings.
The idea is to create a data structure with the templates' nesting, and the
payload corresponding to each index appearing at the position of each index.

Answers using simple string replacement or regexp are to be avoided. The idea is
to use the native, or usual implementation of lists/tuples etc of the language
and to hierarchically traverse the template to generate the output.

;Task Detail:
Given the following input template t  and list of payloads p:
# Square brackets are used here to denote nesting but may be changed for other,
# clear, visual representations of nested data appropriate to ones programming
# language.
t = [
    [[1, 2],
     [3, 4, 1],
     5]]

p = 'Payload#0' ... 'Payload#6'

The correct output should have the following structure, (although spacing and
linefeeds may differ, the nesting and order should follow):
[[['Payload#1', 'Payload#2'],
  ['Payload#3', 'Payload#4', 'Payload#1'],
  'Payload#5']]

1. Generate the output for the above template, t.

;Optional Extended tasks:
2. Show which payloads remain unused.
3. Give some indication/handling of indices without a payload.

''Show output on this page.''

Solution:
package main

import (
    "fmt"
    "os"
    "sort"
    "strings"
    "text/template"
)

func main() {
    const t = `[[[{{index .P 1}}, {{index .P 2}}],
  [{{index .P 3}}, {{index .P 4}}, {{index .P 1}}],
  {{index .P 5}}]]
`
    type S struct {
        P map[int]string
    }

    var s S
    s.P = map[int]string{
        0: "'Payload#0'", 1: "'Payload#1'", 2: "'Payload#2'", 3: "'Payload#3'",
        4: "'Payload#4'", 5: "'Payload#5'", 6: "'Payload#6'",
    }
    tmpl := template.Must(template.New("").Parse(t))
    tmpl.Execute(os.Stdout, s)

    var unused []int
    for k, _ := range s.P {
        if !strings.Contains(t, fmt.Sprintf("{{index .P %d}}", k)) {
            unused = append(unused, k)
        }
    }
    sort.Ints(unused)
    fmt.Println("\nThe unused payloads have indices of :", unused)
}


Next highest int from digits

Given a zero or positive integer, the task is to generate the next largest
integer using only the given digits*1.

*   Numbers will not be padded to the left with zeroes.
*   Use all given digits, with their given multiplicity. (If a digit appears twice in the input number, it should appear twice in the result).
*   If there is no next highest integer return zero.

:*1   Alternatively phrased as:   "Find the smallest integer larger than the (positive or zero) integer   '''N'''
:: which can be obtained by reordering the (base ten) digits of   '''N'''".

;Algorithm 1:
#   Generate all the permutations of the digits and sort into numeric order.
#   Find the number in the list.
#   Return the next highest number from the list.

The above could prove slow and memory hungry for numbers with large numbers of
digits, but should be easy to reason about its correctness.

;Algorithm 2:
#   Scan right-to-left through the digits of the number until you find a digit with a larger digit somewhere to the right of it.
#   Exchange that digit with the digit on the right that is ''both'' more than it, and closest to it.
#   Order the digits to the right of this position, after the swap; lowest-to-highest, left-to-right. (I.e. so they form the lowest numerical representation)

'''E.g.:'''

    n = 12453

    12_4_53

    12_5_43

    12_5_34

    return: 12534

This second algorithm is faster and more memory efficient, but implementations
may be harder to test.

One method of testing, (as used in developing the task),   is to compare results from both
algorithms for random numbers generated from a range that the first algorithm can handle.

;Task requirements:
Calculate the next highest int from the digits of the following numbers:
:*   0
:*   9
:*   12
:*   21
:*   12453
:*   738440
:*   45072010
:*   95322020

;Optional stretch goal:
:*   9589776899767587796600

Solution:
package main

import (
    "fmt"
    "sort"
)

func permute(s string) []string {
    var res []string
    if len(s) == 0 {
        return res
    }
    b := []byte(s)
    var rc func(int) // recursive closure
    rc = func(np int) {
        if np == 1 {
            res = append(res, string(b))
            return
        }
        np1 := np - 1
        pp := len(b) - np1
        rc(np1)
        for i := pp; i > 0; i-- {
            b[i], b[i-1] = b[i-1], b[i]
            rc(np1)
        }
        w := b[0]
        copy(b, b[1:pp+1])
        b[pp] = w
    }
    rc(len(b))
    return res
}

func algorithm1(nums []string) {
    fmt.Println("Algorithm 1")
    fmt.Println("-----------")
    for _, num := range nums {
        perms := permute(num)
        le := len(perms)
        if le == 0 { // ignore blanks
            continue
        }
        sort.Strings(perms)
        ix := sort.SearchStrings(perms, num)
        next := ""
        if ix < le-1 {
            for i := ix + 1; i < le; i++ {
                if perms[i] > num {
                    next = perms[i]
                    break
                }
            }
        }
        if len(next) > 0 {
            fmt.Printf("%29s -> %s\n", commatize(num), commatize(next))
        } else {
            fmt.Printf("%29s -> 0\n", commatize(num))
        }
    }
    fmt.Println()
}

func algorithm2(nums []string) {
    fmt.Println("Algorithm 2")
    fmt.Println("-----------")
outer:
    for _, num := range nums {
        b := []byte(num)
        le := len(b)
        if le == 0 { // ignore blanks
            continue
        }
        max := num[le-1]
        mi := le - 1
        for i := le - 2; i >= 0; i-- {
            if b[i] < max {
                min := max - b[i]
                for j := mi + 1; j < le; j++ {
                    min2 := b[j] - b[i]
                    if min2 > 0 && min2 < min {
                        min = min2
                        mi = j
                    }
                }
                b[i], b[mi] = b[mi], b[i]
                c := (b[i+1:])
                sort.Slice(c, func(i, j int) bool {
                    return c[i] < c[j]
                })
                next := string(b[0:i+1]) + string(c)
                fmt.Printf("%29s -> %s\n", commatize(num), commatize(next))
                continue outer
            } else if b[i] > max {
                max = num[i]
                mi = i
            }
        }
        fmt.Printf("%29s -> 0\n", commatize(num))
    }
}

func commatize(s string) string {
    le := len(s)
    for i := le - 3; i >= 1; i -= 3 {
        s = s[0:i] + "," + s[i:]
    }
    return s
}

func main() {
    nums := []string{"0", "9", "12", "21", "12453", "738440", "45072010", "95322020", "9589776899767587796600"}
    algorithm1(nums[:len(nums)-1]) // exclude the last one
    algorithm2(nums)               // include the last one
}


Nim game

Nim is a simple game where the second player-if they know the trick-will always win.

The game has only 3 rules:
::*   start with   '''12'''   tokens
::*   each player takes    '''1,  2,  or  3'''   tokens in turn
::*  the player who takes the last token wins.

To win every time,   the second player simply takes 4 minus the number the first player took.   So if the first player takes 1,   the second takes 3; if the first player takes 2,   the second should take 2; and if the first player takes 3,   the second player will take 1.

;Task:
Design a simple Nim game where the human player goes first, and the computer always wins. The game should enforce the rules.

Solution:
package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
)

func showTokens(tokens int) {
    fmt.Println("Tokens remaining", tokens, "\n")
}

func main() {
    tokens := 12
    scanner := bufio.NewScanner(os.Stdin)
    for {
        showTokens(tokens)
        fmt.Print("  How many tokens 1, 2 or 3? ")
        scanner.Scan()
        if scerr := scanner.Err(); scerr != nil {
            fmt.Println("Error reading standard input:", scerr)
            return
        }
        t, err := strconv.Atoi(scanner.Text())
        if err != nil || t < 1 || t > 3 {
            fmt.Println("\nMust be a number between 1 and 3, try again.\n")
        } else {
            ct := 4 - t
            s := "s"
            if ct == 1 {
                s = ""
            }
            fmt.Print("  Computer takes ", ct, " token", s, "\n\n")
            tokens -= 4
        }
        if tokens == 0 {
            showTokens(0)
            fmt.Println("  Computer wins!")
            return
        }
    }
}


Non-transitive dice

Let our dice select numbers on their faces with equal probability, i.e. fair dice.
Dice may have more or less than six faces. (The possibility of there being a
3D physical shape that has that many "faces" that allow them to be fair dice,
is ignored for this task - a die with 3 or 33 defined sides is defined by the
number of faces and the numbers on each face).

Throwing dice will randomly select a face on each die with equal probability.
To show which die of dice thrown multiple times is more likely to win over the
others:
# calculate all possible combinations of different faces from each die
# Count how many times each die wins a combination
# Each ''combination'' is equally likely so the die with more winning face combinations is statistically more likely to win against the other dice.

'''If two dice X and Y are thrown against each other then X likely to: win, lose, or break-even against Y can be shown as: X > Y, X < Y, or X = Y respectively.
'''
;Example 1:
If X is the three sided die with 1, 3, 6 on its faces and Y has 2, 3, 4 on its
faces then the equal possibility outcomes from throwing both, and the winners
is:

    X   Y   Winner
    =   =   ======
    1   2   Y
    1   3   Y
    1   4   Y
    3   2   X
    3   3   -
    3   4   Y
    6   2   X
    6   3   X
    6   4   X

    TOTAL WINS: X=4, Y=4

Both die will have the same statistical probability of winning, i.e.their comparison can be written as X = Y

;Transitivity:
In mathematics transitivity are rules like:
    if a op b and b op c then a op c
If, for example, the op, (for operator), is the familiar less than, <, and it's applied to integers
we get the familiar if a < b and b < c then a < c

;Non-transitive dice
These are an ordered list of dice where the '>' operation between successive
dice pairs applies but a comparison between the first and last of the list
yields the opposite result, '<'.
''(Similarly '<' successive list comparisons with a final '>' between first and last is also non-transitive).''

Three dice S, T, U with appropriate face values could satisfy

    S < T, T < U and yet S > U

To be non-transitive.

;Notes:

* The order of numbers on the faces of a die is not relevant. For example, three faced die described with face numbers of 1, 2, 3 or 2, 1, 3 or any other permutation are equivalent. For the purposes of the task '''show only the permutation in lowest-first sorted order i.e. 1, 2, 3''' (and remove any of its perms).
* A die can have more than one instance of the same number on its faces, e.g. 2, 3, 3, 4
* '''Rotations''': Any rotation of non-transitive dice from an answer is also an answer. You may ''optionally'' compute and show only one of each such rotation sets, ideally the first when sorted in a natural way. If this option is used then prominently state in the output that rotations of results are also solutions.

;Task:
;====
Find all the ordered lists of ''three'' non-transitive dice S, T, U of the form
S < T, T < U and yet S > U; where the dice are selected from all ''four-faced die''
, (unique w.r.t the notes), possible by having selections from the integers
''one to four'' on any dies face.

Solution can be found by generating all possble individual die then testing all
possible permutations, (permutations are ordered), of three dice for
non-transitivity.

;Optional stretch goal:
Find lists of '''four''' non-transitive dice selected from the same possible dice from the non-stretch goal.

Show the results here, on this page.

;References:
* The Most Powerful Dice - Numberphile Video.
* Nontransitive dice - Wikipedia.

Solution:
package main

import (
    "fmt"
    "sort"
)

func fourFaceCombs() (res [][4]int) {
    found := make([]bool, 256)
    for i := 1; i <= 4; i++ {
        for j := 1; j <= 4; j++ {
            for k := 1; k <= 4; k++ {
                for l := 1; l <= 4; l++ {
                    c := [4]int{i, j, k, l}
                    sort.Ints(c[:])
                    key := 64*(c[0]-1) + 16*(c[1]-1) + 4*(c[2]-1) + (c[3] - 1)
                    if !found[key] {
                        found[key] = true
                        res = append(res, c)
                    }
                }
            }
        }
    }
    return
}

func cmp(x, y [4]int) int {
    xw := 0
    yw := 0
    for i := 0; i < 4; i++ {
        for j := 0; j < 4; j++ {
            if x[i] > y[j] {
                xw++
            } else if y[j] > x[i] {
                yw++
            }
        }
    }
    if xw < yw {
        return -1
    } else if xw > yw {
        return 1
    }
    return 0
}

func findIntransitive3(cs [][4]int) (res [][3][4]int) {
    var c = len(cs)
    for i := 0; i < c; i++ {
        for j := 0; j < c; j++ {
            for k := 0; k < c; k++ {
                first := cmp(cs[i], cs[j])
                if first == -1 {
                    second := cmp(cs[j], cs[k])
                    if second == -1 {
                        third := cmp(cs[i], cs[k])
                        if third == 1 {
                            res = append(res, [3][4]int{cs[i], cs[j], cs[k]})
                        }
                    }
                }
            }
        }
    }
    return
}

func findIntransitive4(cs [][4]int) (res [][4][4]int) {
    c := len(cs)
    for i := 0; i < c; i++ {
        for j := 0; j < c; j++ {
            for k := 0; k < c; k++ {
                for l := 0; l < c; l++ {
                    first := cmp(cs[i], cs[j])
                    if first == -1 {
                        second := cmp(cs[j], cs[k])
                        if second == -1 {
                            third := cmp(cs[k], cs[l])
                            if third == -1 {
                                fourth := cmp(cs[i], cs[l])
                                if fourth == 1 {
                                    res = append(res, [4][4]int{cs[i], cs[j], cs[k], cs[l]})
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return
}

func main() {
    combs := fourFaceCombs()
    fmt.Println("Number of eligible 4-faced dice", len(combs))
    it3 := findIntransitive3(combs)
    fmt.Printf("\n%d ordered lists of 3 non-transitive dice found, namely:\n", len(it3))
    for _, a := range it3 {
        fmt.Println(a)
    }
    it4 := findIntransitive4(combs)
    fmt.Printf("\n%d ordered lists of 4 non-transitive dice found, namely:\n", len(it4))
    for _, a := range it4 {
        fmt.Println(a)
    }
}


Nonoblock

Nonogram puzzle.

;Given:
* The number of cells in a row.
* The size of each, (space separated), connected block of cells to fit in the row, in left-to right order.

;Task:
* show all possible positions.
* show the number of positions of the blocks for the following cases within the row.
* show all output on this page.
* use a "neat" diagram of the block positions.

;Enumerate the following configurations:
#   '''5'''   cells   and   '''[2, 1]'''   blocks
#   '''5'''   cells   and   '''[]'''   blocks   (no blocks)
#   '''10'''   cells   and   '''[8]'''   blocks
#   '''15'''   cells   and   '''[2, 3, 2, 3]'''   blocks
#   '''5'''   cells   and   '''[2, 3]'''   blocks   (should give some indication of this not being possible)

;Example:
Given a row of five cells and a block of two cells followed by a block of one cell - in that order, the example could be shown as:

    |_|_|_|_|_| # 5 cells and [2, 1] blocks

And would expand to the following 3 possible rows of block positions:

    |A|A|_|B|_|
    |A|A|_|_|B|
    |_|A|A|_|B|

Note how the sets of blocks are always separated by a space.

Note also that it is not necessary for each block to have a separate letter.
Output approximating

This:
                        |#|#|_|#|_|
                        |#|#|_|_|#|
                        |_|#|#|_|#|

This would also work:
                        ##.#.
                        ##..#
                       .##.#

;An algorithm:
* Find the minimum space to the right that is needed to legally hold all but the leftmost block of cells (with a space between blocks remember).
* The leftmost cell can legitimately be placed in all positions from the LHS up to a RH position that allows enough room for the rest of the blocks.
* for each position of the LH block recursively compute the position of the rest of the blocks in the ''remaining'' space to the right of the current placement of the LH block.

(This is the algorithm used in the [[Nonoblock#Python]] solution).

;Reference:
* The blog post Nonogram puzzle solver (part 1) Inspired this task and donated its [[Nonoblock#Python]] solution.

Solution:
package main

import (
    "fmt"
    "strings"
)

func printBlock(data string, le int) {
    a := []byte(data)
    sumBytes := 0
    for _, b := range a {
        sumBytes += int(b - 48)
    }
    fmt.Printf("\nblocks %c, cells %d\n", a, le)
    if le-sumBytes <= 0 {
        fmt.Println("No solution")
        return
    }
    prep := make([]string, len(a))
    for i, b := range a {
        prep[i] = strings.Repeat("1", int(b-48))
    }
    for _, r := range genSequence(prep, le-sumBytes+1) {
        fmt.Println(r[1:])
    }
}

func genSequence(ones []string, numZeros int) []string {
    if len(ones) == 0 {
        return []string{strings.Repeat("0", numZeros)}
    }
    var result []string
    for x := 1; x < numZeros-len(ones)+2; x++ {
        skipOne := ones[1:]
        for _, tail := range genSequence(skipOne, numZeros-x) {
            result = append(result, strings.Repeat("0", x)+ones[0]+tail)
        }
    }
    return result
}

func main() {
    printBlock("21", 5)
    printBlock("", 5)
    printBlock("8", 10)
    printBlock("2323", 15)
    printBlock("23", 5)
}


Nonogram solver

nonogram is a puzzle that provides
numeric clues used to fill in a grid of cells,
establishing for each cell whether it is filled or not.
The puzzle solution is typically a picture of some kind.

Each row and column of a rectangular grid is annotated with the lengths
of its distinct runs of occupied cells.
Using only these lengths you should find one valid configuration
of empty and occupied cells, or show a failure message.

;Example
Problem:                 Solution:

. . . . . . . .  3       . # # # . . . .  3
. . . . . . . .  2 1     # # . # . . . .  2 1
. . . . . . . .  3 2     . # # # . . # #  3 2
. . . . . . . .  2 2     . . # # . . # #  2 2
. . . . . . . .  6       . . # # # # # #  6
. . . . . . . .  1 5     # . # # # # # .  1 5
. . . . . . . .  6       # # # # # # . .  6
. . . . . . . .  1       . . . . # . . .  1
. . . . . . . .  2       . . . # # . . .  2
1 3 1 7 5 3 4 3          1 3 1 7 5 3 4 3
2 1 5 1                  2 1 5 1
The problem above could be represented by two lists of lists:
x = [[3], [2,1], [3,2], [2,2], [6], [1,5], [6], [1], [2]]
y = [[1,2], [3,1], [1,5], [7,1], [5], [3], [4], [3]]
A more compact representation of the same problem uses strings,
where the letters represent the numbers, A=1, B=2, etc:
x = "C BA CB BB F AE F A B"
y = "AB CA AE GA E C D C"

;Task
For this task, try to solve the 4 problems below, read from a "nonogram_problems.txt" file that has this content
(the blank lines are separators):
C BA CB BB F AE F A B
AB CA AE GA E C D C

F CAC ACAC CN AAA AABB EBB EAA ECCC HCCC
D D AE CD AE A DA BBB CC AAB BAA AAB DA AAB AAA BAB AAA CD BBA DA

CA BDA ACC BD CCAC CBBAC BBBBB BAABAA ABAD AABB BBH BBBD ABBAAA CCEA AACAAB BCACC ACBH DCH ADBE ADBB DBE ECE DAA DB CC
BC CAC CBAB BDD CDBDE BEBDF ADCDFA DCCFB DBCFC ABDBA BBF AAF BADB DBF AAAAD BDG CEF CBDB BBB FC

E BCB BEA BH BEK AABAF ABAC BAA BFB OD JH BADCF Q Q R AN AAN EI H G
E CB BAB AAA AAA AC BB ACC ACCA AGB AIA AJ AJ ACE AH BAF CAG DAG FAH FJ GJ ADK ABK BL CM

'''Extra credit''': generate nonograms with unique solutions, of desired height and width.

This task is the problem n.98 of the "99 Prolog Problems" by Werner Hett (also thanks to Paul Singleton for the idea and the examples).

; Related tasks
* [[Nonoblock]].

;See also
* Arc Consistency Algorithm
* http://www.haskell.org/haskellwiki/99_questions/Solutions/98 (Haskell)
* http://twanvl.nl/blog/haskell/Nonograms (Haskell)
* http://picolisp.com/5000/!wiki?99p98 (PicoLisp)

Solution:
package main

import (
    "fmt"
    "strings"
)

type BitSet []bool

func (bs BitSet) and(other BitSet) {
    for i := range bs {
        if bs[i] && other[i] {
            bs[i] = true
        } else {
            bs[i] = false
        }
    }
}

func (bs BitSet) or(other BitSet) {
    for i := range bs {
        if bs[i] || other[i] {
            bs[i] = true
        } else {
            bs[i] = false
        }
    }
}

func iff(cond bool, s1, s2 string) string {
    if cond {
        return s1
    }
    return s2
}

func newPuzzle(data [2]string) {
    rowData := strings.Fields(data[0])
    colData := strings.Fields(data[1])
    rows := getCandidates(rowData, len(colData))
    cols := getCandidates(colData, len(rowData))

    for {
        numChanged := reduceMutual(cols, rows)
        if numChanged == -1 {
            fmt.Println("No solution")
            return
        }
        if numChanged == 0 {
            break
        }
    }

    for _, row := range rows {
        for i := 0; i < len(cols); i++ {
            fmt.Printf(iff(row[0][i], "# ", ". "))
        }
        fmt.Println()
    }
    fmt.Println()
}

// collect all possible solutions for the given clues
func getCandidates(data []string, le int) [][]BitSet {
    var result [][]BitSet
    for _, s := range data {
        var lst []BitSet
        a := []byte(s)
        sumBytes := 0
        for _, b := range a {
            sumBytes += int(b - 'A' + 1)
        }
        prep := make([]string, len(a))
        for i, b := range a {
            prep[i] = strings.Repeat("1", int(b-'A'+1))
        }
        for _, r := range genSequence(prep, le-sumBytes+1) {
            bits := []byte(r[1:])
            bitset := make(BitSet, len(bits))
            for i, b := range bits {
                bitset[i] = b == '1'
            }
            lst = append(lst, bitset)
        }
        result = append(result, lst)
    }
    return result
}

func genSequence(ones []string, numZeros int) []string {
    le := len(ones)
    if le == 0 {
        return []string{strings.Repeat("0", numZeros)}
    }
    var result []string
    for x := 1; x < numZeros-le+2; x++ {
        skipOne := ones[1:]
        for _, tail := range genSequence(skipOne, numZeros-x) {
            result = append(result, strings.Repeat("0", x)+ones[0]+tail)
        }
    }
    return result
}

/* If all the candidates for a row have a value in common for a certain cell,
   then it's the only possible outcome, and all the candidates from the
   corresponding column need to have that value for that cell too. The ones
   that don't, are removed. The same for all columns. It goes back and forth,
   until no more candidates can be removed or a list is empty (failure).
*/

func reduceMutual(cols, rows [][]BitSet) int {
    countRemoved1 := reduce(cols, rows)
    if countRemoved1 == -1 {
        return -1
    }
    countRemoved2 := reduce(rows, cols)
    if countRemoved2 == -1 {
        return -1
    }
    return countRemoved1 + countRemoved2
}

func reduce(a, b [][]BitSet) int {
    countRemoved := 0
    for i := 0; i < len(a); i++ {
        commonOn := make(BitSet, len(b))
        for j := 0; j < len(b); j++ {
            commonOn[j] = true
        }
        commonOff := make(BitSet, len(b))

        // determine which values all candidates of a[i] have in common
        for _, candidate := range a[i] {
            commonOn.and(candidate)
            commonOff.or(candidate)
        }

        // remove from b[j] all candidates that don't share the forced values
        for j := 0; j < len(b); j++ {
            fi, fj := i, j
            for k := len(b[j]) - 1; k >= 0; k-- {
                cnd := b[j][k]
                if (commonOn[fj] && !cnd[fi]) || (!commonOff[fj] && cnd[fi]) {
                    lb := len(b[j])
                    copy(b[j][k:], b[j][k+1:])
                    b[j][lb-1] = nil
                    b[j] = b[j][:lb-1]
                    countRemoved++
                }
            }
            if len(b[j]) == 0 {
                return -1
            }
        }
    }
    return countRemoved
}

func main() {
    p1 := [2]string{"C BA CB BB F AE F A B", "AB CA AE GA E C D C"}

    p2 := [2]string{
        "F CAC ACAC CN AAA AABB EBB EAA ECCC HCCC",
        "D D AE CD AE A DA BBB CC AAB BAA AAB DA AAB AAA BAB AAA CD BBA DA",
    }

    p3 := [2]string{
        "CA BDA ACC BD CCAC CBBAC BBBBB BAABAA ABAD AABB BBH " +
            "BBBD ABBAAA CCEA AACAAB BCACC ACBH DCH ADBE ADBB DBE ECE DAA DB CC",
        "BC CAC CBAB BDD CDBDE BEBDF ADCDFA DCCFB DBCFC ABDBA BBF AAF BADB DBF " +
            "AAAAD BDG CEF CBDB BBB FC",
    }

    p4 := [2]string{
        "E BCB BEA BH BEK AABAF ABAC BAA BFB OD JH BADCF Q Q R AN AAN EI H G",
        "E CB BAB AAA AAA AC BB ACC ACCA AGB AIA AJ AJ " +
            "ACE AH BAF CAG DAG FAH FJ GJ ADK ABK BL CM",
    }

    for _, puzzleData := range [][2]string{p1, p2, p3, p4} {
        newPuzzle(puzzleData)
    }
}


Numbers with equal rises and falls

When a number is written in base 10,   adjacent digits may "rise" or "fall" as the number is read   (usually from left to right).

;Definition:
Given the decimal digits of the number are written as a series   d:
:*   A   ''rise''         is an index   i   such that    d(i)  <  d(i+1)
:*   A   ''fall''    is an index   i   such that    d(i)  >  d(i+1)

;Examples:
:*   The number          '''726,169'''   has   '''3'''   rises and   '''2'''   falls,   so it isn't in the sequence.
:*   The number     '''83,548'''    has   '''2'''   rises and   '''2'''   falls,   so it   is   in the sequence.

;Task:
:*   Print the first   '''200'''    numbers in the sequence
:*   Show that the   '''10 millionth'''   (10,000,000th)   number in the sequence is   '''41,909,002'''

;See also:
*   OEIS Sequence  A296712   describes numbers whose digit sequence in base 10 have equal "rises" and "falls".

;Related tasks:
*   Esthetic numbers

Solution:
package main

import "fmt"

func risesEqualsFalls(n int) bool {
    if n < 10 {
        return true
    }
    rises := 0
    falls := 0
    prev := -1
    for n > 0 {
        d := n % 10
        if prev >= 0 {
            if d < prev {
                rises = rises + 1
            } else if d > prev {
                falls = falls + 1
            }
        }
        prev = d
        n /= 10
    }
    return rises == falls
}

func main() {
    fmt.Println("The first 200 numbers in the sequence are:")
    count := 0
    n := 1
    for {
        if risesEqualsFalls(n) {
            count++
            if count <= 200 {
                fmt.Printf("%3d ", n)
                if count%20 == 0 {
                    fmt.Println()
                }
            }
            if count == 1e7 {
                fmt.Println("\nThe 10 millionth number in the sequence is ", n)
                break
            }
        }
        n++
    }
}


Numeric error propagation

If   '''f''',   '''a''',   and   '''b'''   are values with uncertainties   sf,   sa,   and   sb,   and   '''c'''   is a constant;
then if   '''f'''   is derived from   '''a''',   '''b''',   and   '''c'''   in the following ways,
then   sf   can be calculated as follows:

:;Addition/Subtraction
:* If   f = a +- c,   or   f = c +- a   then   '''sf = sa'''
:* If   f = a +- b   then   '''sf2 = sa2 + sb2'''

:;Multiplication/Division
:* If   f = ca   or   f = ac       then   '''sf = |csa|'''
:* If   f = ab   or   f = a / b              then   '''sf2 = f2( (sa / a)2 + (sb / b)2)'''

:;Exponentiation
:* If   f = ac   then   '''sf = |fc(sa / a)|'''

Caution:
::This implementation of error propagation does not address issues of dependent and independent values.   It is assumed that   '''a'''   and   '''b'''   are independent and so the formula for multiplication should not be applied to   '''a*a'''   for example.   See   the talk page   for some of the implications of this issue.

;Task details:
# Add an uncertain number type to your language that can support addition, subtraction, multiplication, division, and exponentiation between numbers with an associated error term together with 'normal' floating point numbers without an associated error term. Implement enough functionality to perform the following calculations.
# Given coordinates and their errors:x1 = 100 +- 1.1y1 =  50 +- 1.2x2 = 200 +- 2.2y2 = 100 +- 2.3 if point p1 is located at (x1, y1) and p2 is at (x2, y2); calculate the distance between the two points using the classic Pythagorean formula:   d =    (x1 - x2)2   +   (y1 - y2)2
# Print and display both    '''d'''    and its error.

;References:
* A Guide to Error Propagation B. Keeney, 2005.
* Propagation of uncertainty Wikipedia.

;Related task:
*   [[Quaternion type]]

Solution:
package main

import (
    "fmt"
    "math"
)

// "uncertain number type"
// a little optimization is to represent the error term with its square.
// this saves some taking of square roots in various places.
type unc struct {
    n float64 // the number
    s float64 // *square* of one sigma error term
}

// constructor, nice to have so it can handle squaring of error term
func newUnc(n, s float64) *unc {
    return &unc{n, s * s}
}

// error term accessor method, nice to have so it can handle recovering
// (non-squared) error term from internal (squared) representation
func (z *unc) errorTerm() float64 {
    return math.Sqrt(z.s)
}

// Arithmetic methods are modeled on the Go big number package.
// The basic scheme is to pass all operands as method arguments, compute
// the result into the method receiver, and then return the receiver as
// the result of the method.  This has an advantage of letting the programer
// determine allocation and use of temporary objects, reducing garbage;
// and has the convenience and efficiency of allowing operations to be chained.

// addition/subtraction
func (z *unc) addC(a *unc, c float64) *unc {
    *z = *a
    z.n += c
    return z
}

func (z *unc) subC(a *unc, c float64) *unc {
    *z = *a
    z.n -= c
    return z
}

func (z *unc) addU(a, b *unc) *unc {
    z.n = a.n + b.n
    z.s = a.s + b.s
    return z
}
func (z *unc) subU(a, b *unc) *unc {
    z.n = a.n - b.n
    z.s = a.s + b.s
    return z
}

// multiplication/division
func (z *unc) mulC(a *unc, c float64) *unc {
    z.n = a.n * c
    z.s = a.s * c * c
    return z
}

func (z *unc) divC(a *unc, c float64) *unc {
    z.n = a.n / c
    z.s = a.s / (c * c)
    return z
}

func (z *unc) mulU(a, b *unc) *unc {
    prod := a.n * b.n
    z.n, z.s = prod, prod*prod*(a.s/(a.n*a.n)+b.s/(b.n*b.n))
    return z
}

func (z *unc) divU(a, b *unc) *unc {
    quot := a.n / b.n
    z.n, z.s = quot, quot*quot*(a.s/(a.n*a.n)+b.s/(b.n*b.n))
    return z
}

// exponentiation
func (z *unc) expC(a *unc, c float64) *unc {
    f := math.Pow(a.n, c)
    g := f * c / a.n
    z.n = f
    z.s = a.s * g * g
    return z
}

func main() {
    x1 := newUnc(100, 1.1)
    x2 := newUnc(200, 2.2)
    y1 := newUnc(50, 1.2)
    y2 := newUnc(100, 2.3)
    var d, d2 unc
    d.expC(d.addU(d.expC(d.subU(x1, x2), 2), d2.expC(d2.subU(y1, y2), 2)), .5)
    fmt.Println("d:    ", d.n)
    fmt.Println("error:", d.errorTerm())
}


Numerical and alphabetical suffixes

This task is about expressing numbers with an attached (abutted) suffix multiplier(s),   the suffix(es) could be:
::*   an alphabetic (named) multiplier which could be abbreviated
::*    metric  multiplier(s) which can be specified multiple times
::*        "binary"      multiplier(s) which can be specified multiple times
::*   explanation marks ('''!''') which indicate a factorial or multifactorial

The (decimal) numbers can be expressed generally as:
              {+-}   {digits}   {'''.'''}   {digits}
                                  ------ or ------
              {+-}   {digits}   {'''.'''}   {digits}   {'''E''' or '''e'''}   {+-}   {digits}

where:
::*   numbers won't have embedded blanks   (contrary to the expaciated examples above where whitespace was used for readability)
::*   this task will only be dealing with decimal numbers,   both in the   ''mantissa''   and   ''exponent''
::*   +-   indicates an optional plus or minus sign   ('''+'''   or   '''-''')
::*   digits are the decimal digits   ('''0''' --> '''9''')
::*   the digits can have comma(s) interjected to separate the   ''periods''   (thousands)   such as:   '''12,467,000'''
::*   '''.'''   is the decimal point, sometimes also called a   ''dot''
::*   '''e'''   or   '''E'''   denotes the use of decimal exponentiation   (a number multiplied by raising ten to some power)

This isn't a pure or perfect definition of the way we express decimal numbers,   but it should convey the intent for this task.

The use of the word   ''periods''   (thousands) is not meant to confuse, that word (as used above) is what the '''comma''' separates;
the groups of decimal digits are called ''periods'',   and in almost all cases, are groups of three decimal digits.

If an   '''e'''   or   '''E'''   is specified, there must be a legal number expressed before it,   and there must be a legal (exponent) expressed after it.

Also, there must be some digits expressed in all cases,   not just a sign and/or decimal point.

Superfluous signs, decimal points, exponent numbers, and zeros   need not be preserved.

I.E.:
'''+7'''   '''007'''   '''7.00'''   '''7E-0'''   '''7E000'''   '''70e-1'''     could all be expressed as '''7'''

All numbers to be "expanded" can be assumed to be valid and there won't be a requirement to verify their validity.

;Abbreviated alphabetic suffixes to be supported   (where the capital letters signify the minimum abbreation that can be used):
      '''PAIRs'''         multiply the number by  '''2'''         (as in pairs of shoes or pants)
      '''SCOres'''        multiply the number by  '''20'''        (as '''3score''' would be '''60''')
      '''DOZens'''        multiply the number by  '''12'''
      '''GRoss'''         multiply the number by  '''144'''       (twelve dozen)
      '''GREATGRoss'''    multiply the number by  '''1,728'''     (a dozen gross)
      '''GOOGOLs'''       multiply the number by  '''10^100'''    (ten raised to the 100>th power)

Note that the plurals are supported, even though they're usually used when expressing exact numbers   (She has 2 dozen eggs, and dozens of quavas)

;Metric suffixes to be supported   (whether or not they're officially sanctioned):
      '''K'''     multiply the number by  '''10^3'''              kilo      (1,000)
      '''M'''     multiply the number by  '''10^6'''              mega      (1,000,000)
      '''G'''     multiply the number by  '''10^9'''              giga      (1,000,000,000)
      '''T'''     multiply the number by  '''10^12'''             tera      (1,000,000,000,000)
      '''P'''     multiply the number by  '''10^15'''             peta      (1,000,000,000,000,000)
      '''E'''     multiply the number by  '''10^18'''             exa       (1,000,000,000,000,000,000)
      '''Z'''     multiply the number by  '''10^21'''             zetta     (1,000,000,000,000,000,000,000)
      '''Y'''     multiply the number by  '''10^24'''             yotta     (1,000,000,000,000,000,000,000,000)
      '''X'''     multiply the number by  '''10^27'''             xenta     (1,000,000,000,000,000,000,000,000,000)
      '''W'''     multiply the number by  '''10^30'''             wekta     (1,000,000,000,000,000,000,000,000,000,000)
      '''V'''     multiply the number by  '''10^33'''             vendeka   (1,000,000,000,000,000,000,000,000,000,000,000)
      '''U'''     multiply the number by  '''10^36'''             udekta    (1,000,000,000,000,000,000,000,000,000,000,000,000)

;Binary suffixes to be supported   (whether or not they're officially sanctioned):
      '''Ki'''    multiply the number by  '''2^10'''              kibi      (1,024)
      '''Mi'''    multiply the number by  '''2^20'''              mebi      (1,048,576)
      '''Gi'''    multiply the number by  '''2^30'''              gibi      (1,073,741,824)
      '''Ti'''    multiply the number by  '''2^40'''              tebi      (1,099,571,627,776)
      '''Pi'''    multiply the number by  '''2^50'''              pebi      (1,125,899,906,884,629)
      '''Ei'''    multiply the number by  '''2^60'''              exbi      (1,152,921,504,606,846,976)
      '''Zi'''    multiply the number by  '''2^70'''              zeb1      (1,180,591,620,717,411,303,424)
      '''Yi'''    multiply the number by  '''2^80'''              yobi      (1,208,925,819,614,629,174,706,176)
      '''Xi'''    multiply the number by  '''2^90'''              xebi      (1,237,940,039,285,380,274,899,124,224)
      '''Wi'''    multiply the number by  '''2^100'''             webi      (1,267,650,600,228,229,401,496,703,205,376)
      '''Vi'''    multiply the number by  '''2^110'''             vebi      (1,298,074,214,633,706,907,132,624,082,305,024)
      '''Ui'''    multiply the number by  '''2^120'''             uebi      (1,329,227,995,784,915,872,903,807,060,280,344,576)

All of the metric and binary suffixes can be expressed in   lowercase,   uppercase,   ''or''   mixed case.

All of the metric and binary suffixes can be   ''stacked''   (expressed multiple times),   and also be intermixed:
I.E.:       '''123k'''   '''123K'''   '''123GKi'''   '''12.3GiGG'''   '''12.3e-7T'''   '''.78E100e'''

;Factorial suffixes to be supported:
      '''!'''      compute the (regular) factorial product:   '''5!'''   is  '''5''' x '''4''' x '''3''' x '''2''' x '''1'''  =  '''120'''
      '''!!'''     compute the  double   factorial product:   '''8!'''   is  '''8''' x '''6''' x '''4''' x '''2'''      =  '''384'''
      '''!!!'''    compute the  triple   factorial product:   '''8!'''   is  '''8''' x '''5''' x '''2'''          =   '''80'''
      '''!!!!'''   compute the quadruple factorial product:   '''8!'''   is  '''8''' x '''4'''              =   '''32'''
      '''!!!!!'''  compute the quintuple factorial product:   '''8!'''   is  '''8''' x '''3'''              =   '''24'''
      *** the number of factorial symbols that can be specified is to be unlimited   (as per what can be entered/typed) ***

Factorial suffixes aren't, of course, the usual type of multipliers, but are used here in a similar vein.

Multifactorials aren't to be confused with   ''super-factorials''     where   '''(4!)!'''   would be   '''(24)!'''.

;Task:
::*   Using the test cases (below),   show the "expanded" numbers here, on this page.
::*   For each list, show the input on one line,   and also show the output on one line.
::*   When showing the input line, keep the spaces (whitespace) and case (capitalizations) as is.
::*   For each result (list) displayed on one line, separate each number with two blanks.
::*   Add commas to the output numbers were appropriate.

;Test cases:
     2greatGRo   24Gros  288Doz  1,728pairs  172.8SCOre
     1,567      +1.567k    0.1567e-2m
     25.123kK    25.123m   2.5123e-00002G
     25.123kiKI  25.123Mi  2.5123e-00002Gi  +.25123E-7Ei
     -.25123e-34Vikki      2e-77gooGols
     9!   9!!   9!!!   9!!!!   9!!!!!   9!!!!!!   9!!!!!!!   9!!!!!!!!   9!!!!!!!!!

where the last number for the factorials has nine factorial symbols   ('''!''')   after the   '''9'''

;Related tasks:
*   [[Multifactorial]]                 (which has a clearer and more succinct definition of multifactorials.)
*   [[Factorial]]

Solution:
package main

import (
    "fmt"
    "math"
    "math/big"
    "strconv"
    "strings"
)

type minmult struct {
    min  int
    mult float64
}

var abbrevs = map[string]minmult{
    "PAIRs": {4, 2}, "SCOres": {3, 20}, "DOZens": {3, 12},
    "GRoss": {2, 144}, "GREATGRoss": {7, 1728}, "GOOGOLs": {6, 1e100},
}

var metric = map[string]float64{
    "K": 1e3, "M": 1e6, "G": 1e9, "T": 1e12, "P": 1e15, "E": 1e18,
    "Z": 1e21, "Y": 1e24, "X": 1e27, "W": 1e30, "V": 1e33, "U": 1e36,
}

var binary = map[string]float64{
    "Ki": b(10), "Mi": b(20), "Gi": b(30), "Ti": b(40), "Pi": b(50), "Ei": b(60),
    "Zi": b(70), "Yi": b(80), "Xi": b(90), "Wi": b(100), "Vi": b(110), "Ui": b(120),
}

func b(e float64) float64 {
    return math.Pow(2, e)
}

func googol() *big.Float {
    g1 := new(big.Float).SetPrec(500)
    g1.SetInt64(10000000000)
    g := new(big.Float)
    g.Set(g1)
    for i := 2; i <= 10; i++ {
        g.Mul(g, g1)
    }
    return g
}

func fact(num string, d int) int {
    prod := 1
    n, _ := strconv.Atoi(num)
    for i := n; i > 0; i -= d {
        prod *= i
    }
    return prod
}

func parse(number string) *big.Float {
    bf := new(big.Float).SetPrec(500)
    t1 := new(big.Float).SetPrec(500)
    t2 := new(big.Float).SetPrec(500)
    // find index of last digit
    var i int
    for i = len(number) - 1; i >= 0; i-- {
        if '0' <= number[i] && number[i] <= '9' {
            break
        }
    }
    num := number[:i+1]
    num = strings.Replace(num, ",", "", -1) // get rid of any commas
    suf := strings.ToUpper(number[i+1:])
    if suf == "" {
        bf.SetString(num)
        return bf
    }
    if suf[0] == '!' {
        prod := fact(num, len(suf))
        bf.SetInt64(int64(prod))
        return bf
    }
    for k, v := range abbrevs {
        kk := strings.ToUpper(k)
        if strings.HasPrefix(kk, suf) && len(suf) >= v.min {
            t1.SetString(num)
            if k != "GOOGOLs" {
                t2.SetFloat64(v.mult)
            } else {
                t2 = googol() // for greater accuracy
            }
            bf.Mul(t1, t2)
            return bf
        }
    }
    bf.SetString(num)
    for k, v := range metric {
        for j := 0; j < len(suf); j++ {
            if k == suf[j:j+1] {
                if j < len(suf)-1 && suf[j+1] == 'I' {
                    t1.SetFloat64(binary[k+"i"])
                    bf.Mul(bf, t1)
                    j++
                } else {
                    t1.SetFloat64(v)
                    bf.Mul(bf, t1)
                }
            }
        }
    }
    return bf
}

func commatize(s string) string {
    if len(s) == 0 {
        return ""
    }
    neg := s[0] == '-'
    if neg {
        s = s[1:]
    }
    frac := ""
    if ix := strings.Index(s, "."); ix >= 0 {
        frac = s[ix:]
        s = s[:ix]
    }
    le := len(s)
    for i := le - 3; i >= 1; i -= 3 {
        s = s[0:i] + "," + s[i:]
    }
    if !neg {
        return s + frac
    }
    return "-" + s + frac
}

func process(numbers []string) {
    fmt.Print("numbers =  ")
    for _, number := range numbers {
        fmt.Printf("%s  ", number)
    }
    fmt.Print("\nresults =  ")
    for _, number := range numbers {
        res := parse(number)
        t := res.Text('g', 50)
        fmt.Printf("%s  ", commatize(t))
    }
    fmt.Println("\n")
}

func main() {
    numbers := []string{"2greatGRo", "24Gros", "288Doz", "1,728pairs", "172.8SCOre"}
    process(numbers)

    numbers = []string{"1,567", "+1.567k", "0.1567e-2m"}
    process(numbers)

    numbers = []string{"25.123kK", "25.123m", "2.5123e-00002G"}
    process(numbers)

    numbers = []string{"25.123kiKI", "25.123Mi", "2.5123e-00002Gi", "+.25123E-7Ei"}
    process(numbers)

    numbers = []string{"-.25123e-34Vikki", "2e-77gooGols"}
    process(numbers)

    numbers = []string{"9!", "9!!", "9!!!", "9!!!!", "9!!!!!", "9!!!!!!",
        "9!!!!!!!", "9!!!!!!!!", "9!!!!!!!!!"}
    process(numbers)
}


Odd word problem

Write a program that solves the odd word problem with the restrictions given below.

;Description:
You are promised an input stream consisting of English letters and punctuations.

It is guaranteed that:
* the words (sequence of consecutive letters) are delimited by one and only one punctuation,
* the stream will begin with a word,
* the words will be at least one letter long,   and
* a full stop (a period, [.]) appears after, and only after, the last word.

;Example:
A stream with six words:
:: what,is,the;meaning,of:life.

The task is to reverse the letters in every other word while leaving punctuations intact, producing:
:: what,si,the;gninaem,of:efil.
while observing the following restrictions:
# Only I/O allowed is reading or writing one character at a time, which means: no reading in a string, no peeking ahead, no pushing characters back into the stream, and no storing characters in a global variable for later use;
# You '''are not''' to explicitly save characters in a collection data structure, such as arrays, strings, hash tables, etc, for later reversal;
# You '''are''' allowed to use recursions, closures, continuations, threads, co-routines, etc., even if their use implies the storage of multiple characters.

;Test cases:
Work on both the   "life"   example given above, and also the text:
:: we,are;not,in,kansas;any,more.

Solution:
package main

import (
    "bytes"
    "fmt"
    "io"
    "os"
    "unicode"
)

func main() {
    owp(os.Stdout, bytes.NewBufferString("what,is,the;meaning,of:life."))
    fmt.Println()
    owp(os.Stdout, bytes.NewBufferString("we,are;not,in,kansas;any,more."))
    fmt.Println()
}

func owp(dst io.Writer, src io.Reader) {
    byte_in := func () byte {
        bs := make([]byte, 1)
        src.Read(bs)
        return bs[0]
    }
    byte_out := func (b byte) { dst.Write([]byte{b}) }
    odd := func() byte {
        for {
            b := byte_in()
            if unicode.IsPunct(int(b)) {
                return b
            }
            defer byte_out(b)
        }
        panic("impossible")
    }
    for {
        for {
            b := byte_in()
            byte_out(b)
            if b == '.' {
                return
            }
            if unicode.IsPunct(rune(b)) {
                break
            }
        }
        b := odd()
        byte_out(b)
        if b == '.' {
            return
        }
    }
}


Odd word problem

Solution:
package main

import (
    "bytes"
    "fmt"
    "io"
    "os"
    "unicode"
)

func main() {
    owp(os.Stdout, bytes.NewBufferString("what,is,the;meaning,of:life."))
    fmt.Println()
    owp(os.Stdout, bytes.NewBufferString("we,are;not,in,kansas;any,more."))
    fmt.Println()
}

type Coroutine struct {
    out <-chan Coroutine
    in chan<- byte
}

func owp(dst io.Writer, src io.Reader) {
    byte_in := func () (byte, error) {
        bs := make([]byte, 1)
        _, err := src.Read(bs)
        return bs[0], err
    }
    byte_out := func (b byte) { dst.Write([]byte{b}) }

    var f, r Coroutine

    f = func () Coroutine {
        out := make(chan Coroutine)
	in := make(chan byte)
        var fwd func (byte) byte
        fwd = func (c byte) (z byte) {
            if unicode.IsLetter(rune(c)) {
                byte_out(c)
                out <- f
                z = fwd(<- in)
            } else {
                z = c
            }
            return
        }
        go func () {
            for {
                x, ok := <- in
                if !ok { break }
                byte_out(fwd(x))
                out <- r
            }
        } ()
        return Coroutine{ out, in }
    } ()
    r = func () Coroutine {
        out := make(chan Coroutine)
	in := make(chan byte)
        var rev func (byte) byte
        rev = func (c byte) (z byte) {
            if unicode.IsLetter(rune(c)) {
                out <- r
                z = rev(<- in)
                byte_out(c)
            } else {
                z = c
            }
            return
        }
        go func () {
            for {
                x, ok := <- in
                if !ok { break }
                byte_out(rev(x))
                out <- f
            }
        } ()
        return Coroutine{ out, in }
    } ()

    for coro := f; ; coro = <- coro.out {
        c, err := byte_in()
        if err != nil { break }
        coro.in <- c
    }
    close(f.in)
    close(r.in)
}


Old Russian measure of length

Write a program to perform a conversion of the old Russian measures of length to the metric system   (and vice versa).

It is an example of a linear transformation of several variables.

The program should accept a single value in a selected unit of measurement, and convert and return it to the other units:
''vershoks'', ''arshins'', ''sazhens'', ''versts'', ''meters'', ''centimeters'' and ''kilometers''.

;Also see:
:*   Old Russian measure of length

Solution:
package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
    "strings"
)

func main() {
    units := []string{
        "tochka", "liniya", "dyuim", "vershok", "piad", "fut",
        "arshin", "sazhen", "versta", "milia",
        "centimeter", "meter", "kilometer",
    }

    convs := []float32{
        0.0254, 0.254, 2.54, 4.445, 17.78, 30.48,
        71.12, 213.36, 10668, 74676,
        1, 100, 10000,
    }

    scanner := bufio.NewScanner(os.Stdin)
    for {
        for i, u := range units {
            fmt.Printf("%2d %s\n", i+1, u)
        }
        fmt.Println()
        var unit int
        var err error
        for {
            fmt.Print("Please choose a unit 1 to 13 : ")
            scanner.Scan()
            unit, err = strconv.Atoi(scanner.Text())
            if err == nil && unit >= 1 && unit <= 13 {
                break
            }
        }
        unit--
        var value float64
        for {
            fmt.Print("Now enter a value in that unit : ")
            scanner.Scan()
            value, err = strconv.ParseFloat(scanner.Text(), 32)
            if err == nil && value >= 0 {
                break
            }
        }
        fmt.Println("\nThe equivalent in the remaining units is:\n")
        for i, u := range units {
            if i == unit {
                continue
            }
            fmt.Printf(" %10s : %g\n", u, float32(value)*convs[unit]/convs[i])
        }
        fmt.Println()
        yn := ""
        for yn != "y" && yn != "n" {
            fmt.Print("Do another one y/n : ")
            scanner.Scan()
            yn = strings.ToLower(scanner.Text())
        }
        if yn == "n" {
            return
        }
    }
}


Old lady swallowed a fly

Present a program which emits the lyrics to the song   ''I Knew an Old Lady Who Swallowed a Fly'',   taking advantage of the repetitive structure of the song's lyrics.

This song has multiple versions with slightly different lyrics, so all these programs might not emit identical output.

Solution:
package main

import "fmt"

var name, lyric, animals = 0, 1, [][]string{
	{"fly", "I don't know why she swallowed a fly. Perhaps she'll die."},
	{"spider", "That wiggled and jiggled and tickled inside her."},
	{"bird", "How absurd, to swallow a bird."},
	{"cat", "Imagine that, she swallowed a cat."},
	{"dog", "What a hog, to swallow a dog."},
	{"goat", "She just opened her throat and swallowed that goat."},
	{"cow", "I don't know how she swallowed that cow."},
	{"horse", "She's dead, of course."},
}

func main() {
	for i, animal := range animals {
		fmt.Printf("There was an old lady who swallowed a %s,\n",
			animal[name])

		if i > 0 {
			fmt.Println(animal[lyric])
		}

		// Swallowing the last animal signals her death, cutting the
		//  lyrics short.
		if i+1 == len(animals) {
			break
		}

		for ; i > 0; i-- {
			fmt.Printf("She swallowed the %s to catch the %s,\n",
				animals[i][name], animals[i-1][name])
		}

		fmt.Println(animals[0][lyric] + "\n")
	}
}


One-time pad

One-time pad, for encrypting and decrypting messages.
To keep it simple, we will be using letters only.

;Sub-Tasks:
* '''Generate''' the data for a One-time pad (user needs to specify a filename and length)
: The important part is to get "true random" numbers, e.g. from /dev/random
* '''encryption / decryption''' ( basically the same operation, much like [[Rot-13]] )
: For this step, much of [[Vigenere cipher]] could be reused,with the key to be read from the file containing the One-time pad.
* optional: '''management''' of One-time pads: list, mark as used, delete, etc.
: Somehow, the users needs to keep track which pad to use for which partner.

To support the management of pad-files:
* Such files have a file-extension ".1tp"
* Lines starting with "#" may contain arbitary meta-data (i.e. comments)
* Lines starting with "-" count as "used"
* Whitespace within the otp-data is ignored

For example, here is the data from Wikipedia:

# Example data - Wikipedia - 2014-11-13
-ZDXWWW EJKAWO FECIFE WSNZIP PXPKIY URMZHI JZTLBC YLGDYJ
-HTSVTV RRYYEG EXNCGA GGQVRF FHZCIB EWLGGR BZXQDQ DGGIAK
 YHJYEQ TDLCQT HZBSIZ IRZDYS RBYJFZ AIRCWI UCVXTW YKPQMK
 CKHVEX VXYVCS WOGAAZ OUVVON GCNEVR LMBLYB SBDCDC PCGVJX
 QXAUIP PXZQIJ JIUWYH COVWMJ UZOJHL DWHPER UBSRUJ HGAAPR
 CRWVHI FRNTQW AJVWRT ACAKRD OZKIIB VIQGBK IJCWHF GTTSSE
 EXFIPJ KICASQ IOUQTP ZSGXGH YTYCTI BAZSTN JKMFXI RERYWE

;See also
* one time pad encryption in Python
* snapfractalpop -  One-Time-Pad Command-Line-Utility (C).
* Crypt-OTP-2.00 on CPAN (Perl)

Solution:
package main

import (
    "bufio"
    "crypto/rand"
    "fmt"
    "io/ioutil"
    "log"
    "math/big"
    "os"
    "strconv"
    "strings"
    "unicode"
)

const (
    charsPerLine = 48
    chunkSize    = 6
    cols         = 8
    demo         = true // would normally be set to false
)

type fileType int

const (
    otp fileType = iota
    enc
    dec
)

var scnr = bufio.NewScanner(os.Stdin)

func check(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

func toAlpha(s string) string {
    var filtered []rune
    for _, r := range s {
        if unicode.IsUpper(r) {
            filtered = append(filtered, r)
        }
    }
    return string(filtered)
}

func isOtpRelated(s string) bool {
    return strings.HasSuffix(s, ".1tp") || strings.HasSuffix(s, "1tp_cpy") ||
        strings.HasSuffix(s, ".1tp_enc") || strings.HasSuffix(s, "1tp_dec")
}

func makePad(nLines int) string {
    nChars := nLines * charsPerLine
    bytes := make([]byte, nChars)
    /* generate random upper case letters */
    max := big.NewInt(26)
    for i := 0; i < nChars; i++ {
        n, err := rand.Int(rand.Reader, max)
        check(err)
        bytes[i] = byte(65 + n.Uint64())
    }
    return inChunks(string(bytes), nLines, otp)
}

func vigenere(text, key string, encrypt bool) string {
    bytes := make([]byte, len(text))
    var ci byte
    for i, c := range text {
        if encrypt {
            ci = (byte(c) + key[i] - 130) % 26
        } else {
            ci = (byte(c) + 26 - key[i]) % 26
        }
        bytes[i] = ci + 65
    }
    temp := len(bytes) % charsPerLine
    if temp > 0 { // pad with random characters so each line is a full one
        max := big.NewInt(26)
        for i := temp; i < charsPerLine; i++ {
            n, err := rand.Int(rand.Reader, max)
            check(err)
            bytes = append(bytes, byte(65+n.Uint64()))
        }
    }
    ft := enc
    if !encrypt {
        ft = dec
    }
    return inChunks(string(bytes), len(bytes)/charsPerLine, ft)
}

func inChunks(s string, nLines int, ft fileType) string {
    nChunks := len(s) / chunkSize
    remainder := len(s) % chunkSize
    chunks := make([]string, nChunks)
    for i := 0; i < nChunks; i++ {
        chunks[i] = s[i*chunkSize : (i+1)*chunkSize]
    }
    if remainder > 0 {
        chunks = append(chunks, s[nChunks*chunkSize:])
    }
    var sb strings.Builder
    for i := 0; i < nLines; i++ {
        j := i * cols
        sb.WriteString(" " + strings.Join(chunks[j:j+cols], " ") + "\n")
    }
    ss := " file\n" + sb.String()
    switch ft {
    case otp:
        return "# OTP" + ss
    case enc:
        return "# Encrypted" + ss
    default: // case dec:
        return "# Decrypted" + ss
    }
}

func menu() int {
    fmt.Println(`
1. Create one time pad file.

2. Delete one time pad file.

3. List one time pad files.

4. Encrypt plain text.

5. Decrypt cipher text.

6. Quit program.
`)
    choice := 0
    for choice < 1 || choice > 6 {
        fmt.Print("Your choice (1 to 6) : ")
        scnr.Scan()
        choice, _ = strconv.Atoi(scnr.Text())
        check(scnr.Err())
    }
    return choice
}

func main() {
    for {
        choice := menu()
        fmt.Println()
        switch choice {
        case 1: // Create OTP
            fmt.Println("Note that encrypted lines always contain 48 characters.\n")
            fmt.Print("OTP file name to create (without extension) : ")
            scnr.Scan()
            fileName := scnr.Text() + ".1tp"
            nLines := 0
            for nLines < 1 || nLines > 1000 {
                fmt.Print("Number of lines in OTP (max 1000) : ")
                scnr.Scan()
                nLines, _ = strconv.Atoi(scnr.Text())
            }
            check(scnr.Err())
            key := makePad(nLines)
            file, err := os.Create(fileName)
            check(err)
            _, err = file.WriteString(key)
            check(err)
            file.Close()
            fmt.Printf("\n'%s' has been created in the current directory.\n", fileName)
            if demo {
                // a copy of the OTP file would normally be on a different machine
                fileName2 := fileName + "_cpy" // copy for decryption
                file, err := os.Create(fileName2)
                check(err)
                _, err = file.WriteString(key)
                check(err)
                file.Close()
                fmt.Printf("'%s' has been created in the current directory.\n", fileName2)
                fmt.Println("\nThe contents of these files are :\n")
                fmt.Println(key)
            }
        case 2: // Delete OTP
            fmt.Println("Note that this will also delete ALL associated files.\n")
            fmt.Print("OTP file name to delete (without extension) : ")
            scnr.Scan()
            toDelete1 := scnr.Text() + ".1tp"
            check(scnr.Err())
            toDelete2 := toDelete1 + "_cpy"
            toDelete3 := toDelete1 + "_enc"
            toDelete4 := toDelete1 + "_dec"
            allToDelete := []string{toDelete1, toDelete2, toDelete3, toDelete4}
            deleted := 0
            fmt.Println()
            for _, name := range allToDelete {
                if _, err := os.Stat(name); !os.IsNotExist(err) {
                    err = os.Remove(name)
                    check(err)
                    deleted++
                    fmt.Printf("'%s' has been deleted from the current directory.\n", name)
                }
            }
            if deleted == 0 {
                fmt.Println("There are no files to delete.")
            }
        case 3: // List OTPs
            fmt.Println("The OTP (and related) files in the current directory are:\n")
            files, err := ioutil.ReadDir(".") // already sorted by file name
            check(err)
            for _, fi := range files {
                name := fi.Name()
                if !fi.IsDir() && isOtpRelated(name) {
                    fmt.Println(name)
                }
            }
        case 4: // Encrypt
            fmt.Print("OTP file name to use (without extension) : ")
            scnr.Scan()
            keyFile := scnr.Text() + ".1tp"
            if _, err := os.Stat(keyFile); !os.IsNotExist(err) {
                file, err := os.Open(keyFile)
                check(err)
                bytes, err := ioutil.ReadAll(file)
                check(err)
                file.Close()
                lines := strings.Split(string(bytes), "\n")
                le := len(lines)
                first := le
                for i := 0; i < le; i++ {
                    if strings.HasPrefix(lines[i], " ") {
                        first = i
                        break
                    }
                }
                if first == le {
                    fmt.Println("\nThat file has no unused lines.")
                    continue
                }
                lines2 := lines[first:] // get rid of comments and used lines

                fmt.Println("Text to encrypt :-\n")
                scnr.Scan()
                text := toAlpha(strings.ToUpper(scnr.Text()))
                check(scnr.Err())
                tl := len(text)
                nLines := tl / charsPerLine
                if tl%charsPerLine > 0 {
                    nLines++
                }
                if len(lines2) >= nLines {
                    key := toAlpha(strings.Join(lines2[0:nLines], ""))
                    encrypted := vigenere(text, key, true)
                    encFile := keyFile + "_enc"
                    file2, err := os.Create(encFile)
                    check(err)
                    _, err = file2.WriteString(encrypted)
                    check(err)
                    file2.Close()
                    fmt.Printf("\n'%s' has been created in the current directory.\n", encFile)
                    for i := first; i < first+nLines; i++ {
                        lines[i] = "-" + lines[i][1:]
                    }
                    file3, err := os.Create(keyFile)
                    check(err)
                    _, err = file3.WriteString(strings.Join(lines, "\n"))
                    check(err)
                    file3.Close()
                    if demo {
                        fmt.Println("\nThe contents of the encrypted file are :\n")
                        fmt.Println(encrypted)
                    }
                } else {
                    fmt.Println("Not enough lines left in that file to do encryption.")
                }
            } else {
                fmt.Println("\nThat file does not exist.")
            }
        case 5: // Decrypt
            fmt.Print("OTP file name to use (without extension) : ")
            scnr.Scan()
            keyFile := scnr.Text() + ".1tp_cpy"
            check(scnr.Err())
            if _, err := os.Stat(keyFile); !os.IsNotExist(err) {
                file, err := os.Open(keyFile)
                check(err)
                bytes, err := ioutil.ReadAll(file)
                check(err)
                file.Close()
                keyLines := strings.Split(string(bytes), "\n")
                le := len(keyLines)
                first := le
                for i := 0; i < le; i++ {
                    if strings.HasPrefix(keyLines[i], " ") {
                        first = i
                        break
                    }
                }
                if first == le {
                    fmt.Println("\nThat file has no unused lines.")
                    continue
                }
                keyLines2 := keyLines[first:] // get rid of comments and used lines

                encFile := keyFile[0:len(keyFile)-3] + "enc"
                if _, err := os.Stat(encFile); !os.IsNotExist(err) {
                    file2, err := os.Open(encFile)
                    check(err)
                    bytes, err := ioutil.ReadAll(file2)
                    check(err)
                    file2.Close()
                    encLines := strings.Split(string(bytes), "\n")[1:] // exclude comment line
                    nLines := len(encLines)
                    if len(keyLines2) >= nLines {
                        encrypted := toAlpha(strings.Join(encLines, ""))
                        key := toAlpha(strings.Join(keyLines2[0:nLines], ""))
                        decrypted := vigenere(encrypted, key, false)
                        decFile := keyFile[0:len(keyFile)-3] + "dec"
                        file3, err := os.Create(decFile)
                        check(err)
                        _, err = file3.WriteString(decrypted)
                        check(err)
                        file3.Close()
                        fmt.Printf("\n'%s' has been created in the current directory.\n", decFile)
                        for i := first; i < first+nLines; i++ {
                            keyLines[i] = "-" + keyLines[i][1:]
                        }
                        file4, err := os.Create(keyFile)
                        check(err)
                        _, err = file4.WriteString(strings.Join(keyLines, "\n"))
                        check(err)
                        file4.Close()
                        if demo {
                            fmt.Println("\nThe contents of the decrypted file are :\n")
                            fmt.Println(decrypted)
                        }
                    }
                } else {
                    fmt.Println("Not enough lines left in that file to do decryption.")
                }
            } else {
                fmt.Println("\nThat file does not exist.")
            }
        case 6: // Quit program
            return
        }
    }
}


One of n lines in a file

A method of choosing a line randomly from a file:
::* Without reading the file more than once
::* When substantial parts of the file cannot be held in memory
::* Without knowing how many lines are in the file
Is to:
::* keep the first line of the file as a possible choice, then
::* Read the second line of the file if possible and make it the possible choice if a uniform random value between zero and one is less than 1/2.
::* Read the third line of the file if possible and make it the possible choice if a uniform random value between zero and one is less than 1/3.
::* ...
::* Read the Nth line of the file if possible and make it the possible choice if a uniform random value between zero and one is less than 1/N

::* Return the computed possible choice when no further lines exist in the file.

;Task:
# Create a function/method/routine called one_of_n that given n, the number of actual lines in a file, follows the algorithm above to return an integer - the line number of the line chosen from the file. The number returned can vary, randomly, in each run.
# Use one_of_n in a ''simulation'' to find what would be the chosen line of a 10-line file simulated 1,000,000 times.
# Print and show how many times each of the 10 lines is chosen as a rough measure of how well the algorithm works.

Note: You may choose a smaller number of repetitions if necessary, but mention this up-front.

Note: This is a specific version of a Reservoir Sampling algorithm: https://en.wikipedia.org/wiki/Reservoir_sampling

Solution:
package main

import (
    "bufio"
    "fmt"
    "io"
    "math/rand"
    "time"
)

// choseLineRandomly implements the method described in the task.
// input is a an io.Reader, which could be an os.File, for example.
// Or, to implement a simulation, it could be anything else that implements
// io.Reader.  The method as described suggests saving and returning
// lines, but the rest of the task requires line numbers.  This function
// thus returns both.
func choseLineRandomly(r io.Reader) (s string, ln int, err error) {
    br := bufio.NewReader(r)
    s, err = br.ReadString('\n')
    if err != nil {
        return
    }
    ln = 1
    lnLast := 1.
    var sLast string
    for {
        // note bufio.ReadString used here.  This effectively defines a
        // line of the file as zero or more bytes followed by a newline.
        sLast, err = br.ReadString('\n')
        if err == io.EOF {
            return s, ln, nil // normal return
        }
        if err != nil {
            break
        }
        lnLast++
        if rand.Float64() < 1/lnLast {
            s = sLast
            ln = int(lnLast)
        }
    }
    return // error return
}

// oneOfN function required for task item 1.  Specified to take a number
// n, the number of lines in a file, but the method (above) specified to
// to be used does not need n, but rather the file itself.  This function
// thus takes both, ignoring n and passing the file to choseLineRandomly.
func oneOfN(n int, file io.Reader) int {
    _, ln, err := choseLineRandomly(file)
    if err != nil {
        panic(err)
    }
    return ln
}

// simulated file reader for task item 2
type simReader int

func (r *simReader) Read(b []byte) (int, error) {
    if *r <= 0 {
        return 0, io.EOF
    }
    b[0] = '\n'
    *r--
    return 1, nil
}

func main() {
    // task item 2 simulation consists of accumulating frequency statistic
    // on 1,000,000 calls of oneOfN on simulated file.
    n := 10
    freq := make([]int, n)
    rand.Seed(time.Now().UnixNano())
    for times := 0; times < 1e6; times++ {
        sr := simReader(n)
        freq[oneOfN(n, &sr)-1]++
    }

    // task item 3.  show frequencies.
    fmt.Println(freq)
}


OpenWebNet password

Calculate the password requested by ethernet gateways from the Legrand / Bticino MyHome OpenWebNet home automation system when the user's ip address is not in the gateway's whitelist

'''Note:''' Factory default password is '12345'. Changing it is highly recommended !

conversation goes as follows

- *#*1##
- *99*0##
- *#603356072##

at which point a password should be sent back, calculated from the "password open" that is set in the gateway, and the nonce that was just sent

- *#25280520##
- *#*1##

Solution:
package main

import (
    "fmt"
    "strconv"
)

func ownCalcPass(password, nonce string) uint32 {
    start := true
    num1 := uint32(0)
    num2 := num1
    i, _ := strconv.Atoi(password)
    pwd := uint32(i)
    for _, c := range nonce {
        if c != '0' {
            if start {
                num2 = pwd
            }
            start = false
        }
        switch c {
        case '1':
            num1 = (num2 & 0xFFFFFF80) >> 7
            num2 = num2 << 25
        case '2':
            num1 = (num2 & 0xFFFFFFF0) >> 4
            num2 = num2 << 28
        case '3':
            num1 = (num2 & 0xFFFFFFF8) >> 3
            num2 = num2 << 29
        case '4':
            num1 = num2 << 1
            num2 = num2 >> 31
        case '5':
            num1 = num2 << 5
            num2 = num2 >> 27
        case '6':
            num1 = num2 << 12
            num2 = num2 >> 20
        case '7':
            num3 := num2 & 0x0000FF00
            num4 := ((num2 & 0x000000FF) << 24) | ((num2 & 0x00FF0000) >> 16)
            num1 = num3 | num4
            num2 = (num2 & 0xFF000000) >> 8
        case '8':
            num1 = (num2&0x0000FFFF)<<16 | (num2 >> 24)
            num2 = (num2 & 0x00FF0000) >> 8
        case '9':
            num1 = ^num2
        default:
            num1 = num2
        }

        num1 &= 0xFFFFFFFF
        num2 &= 0xFFFFFFFF
        if c != '0' && c != '9' {
            num1 |= num2
        }
        num2 = num1
    }
    return num1
}

func testPasswordCalc(password, nonce string, expected uint32) {
    res := ownCalcPass(password, nonce)
    m := fmt.Sprintf("%s  %s  %-10d  %-10d", password, nonce, res, expected)
    if res == expected {
        fmt.Println("PASS", m)
    } else {
        fmt.Println("FAIL", m)
    }
}

func main() {
    testPasswordCalc("12345", "603356072", 25280520)
    testPasswordCalc("12345", "410501656", 119537670)
    testPasswordCalc("12345", "630292165", 4269684735)
}


Operator precedence

Operators in C and C++}}

;Task:
Provide a list of   [[wp:order of operations|precedence   and   associativity   of all the operators and constructs that the language utilizes in descending order of precedence such that an operator which is listed on some row will be evaluated prior to any operator that is listed on a row further below it.

Operators that are in the same cell (there may be several rows of operators listed in a cell) are evaluated with the same level of precedence, in the given direction.

State whether arguments are passed by value or by reference.

Solution:
{| class="wikitable"
! Precedence
! Operators
|-
| Highest
| Unary operators: +, -, !, ^, *, &, <-
|-
| 5
| *,  /,  %,  <<,  >>,  &,  &^
|-
| 4
| +,  -,  <nowiki>|</nowiki>,  ^
|-
| 3
| ==,  !=,  <,  <=,  >,  >=
|-
| 2
| &&
|-
| 1
| <nowiki>||</nowiki>
|}
Binary operators of the same precedence associate from left to right.
Associativity has no meaning for unary operators.

Syntactic elements not in the list are not considered operators in Go; if they present ambiguity in order of evaluation, the ambiguity is resolved by other rules specific to those elements.


Padovan n-step number sequences

As the [[Fibonacci sequence]] expands to the [[Fibonacci n-step number sequences]]; We similarly expand the [[Padovan sequence]] to form these Padovan n-step number sequences.

The Fibonacci-like sequences can be defined like this:

    For n == 2:
        start:      1, 1
        Recurrence: R(n, x) = R(n, x-1) + R(n, x-2); for n == 2
    For n == N:
        start:      First N terms of R(N-1, x)
        Recurrence: R(N, x) = sum(R(N, x-1) + R(N, x-2) + ... R(N, x-N))

For this task we similarly define terms of the first 2..n-step Padovan sequences as:

    For n == 2:
        start:      1, 1, 1
        Recurrence: R(n, x) = R(n, x-2) + R(n, x-3); for n == 2
    For n == N:
        start:      First N + 1 terms of R(N-1, x)
        Recurrence: R(N, x) = sum(R(N, x-2) + R(N, x-3) + ... R(N, x-N-1))

The initial values of the sequences are:
:: {| style="text-align: left;" border="4" cellpadding="2" cellspacing="2"
|+ Padovan n-step sequences
|- style="background-color: rgb(255, 204, 255);"
! n !! Values !! OEIS Entry
|-
|  2 || 1,1,1,2,2,3,4,5,7,9,12,16,21,28,37, ... || A134816:  'Padovan's spiral numbers'
|-
|  3 || 1,1,1,2,3,4,6,9,13,19,28,41,60,88,129, ... || A000930:  'Narayana's cows sequence'
|-
|  4 || 1,1,1,2,3,5,7,11,17,26,40,61,94,144,221, ... || A072465:  'A Fibonacci-like model in which each pair of rabbits dies after the birth of their 4th litter'
|-
|  5 || 1,1,1,2,3,5,8,12,19,30,47,74,116,182,286, ... || A060961:  'Number of compositions (ordered partitions) of n into 1's, 3's and 5's'
|-
|  6 || 1,1,1,2,3,5,8,13,20,32,51,81,129,205,326, ... ||
|-
|  7 || 1,1,1,2,3,5,8,13,21,33,53,85,136,218,349, ... || A117760:  'Expansion of 1/(1 - x - x^3 - x^5 - x^7)'
|-
|  8 || 1,1,1,2,3,5,8,13,21,34,54,87,140,225,362, ... ||
|-
|}

;Task:
# Write a function to generate the first t terms, of the first 2..max_n Padovan n-step number sequences as defined above.
# Use this to print and show here at least the first t=15 values of the first 2..8 n-step sequences. (The OEIS column in the table above should be omitted).

Solution:
package main

import "fmt"

func padovanN(n, t int) []int {
    if n < 2 || t < 3 {
        ones := make([]int, t)
        for i := 0; i < t; i++ {
            ones[i] = 1
        }
        return ones
    }
    p := padovanN(n-1, t)
    for i := n + 1; i < t; i++ {
        p[i] = 0
        for j := i - 2; j >= i-n-1; j-- {
            p[i] += p[j]
        }
    }
    return p
}

func main() {
    t := 15
    fmt.Println("First", t, "terms of the Padovan n-step number sequences:")
    for n := 2; n <= 8; n++ {
        fmt.Printf("%d: %3d\n", n, padovanN(n, t))
    }
}


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:
* The Plastic Ratio - Numberphile video.

Solution:
package main

import (
    "fmt"
    "math"
    "math/big"
    "strings"
)

func padovanRecur(n int) []int {
    p := make([]int, n)
    p[0], p[1], p[2] = 1, 1, 1
    for i := 3; i < n; i++ {
        p[i] = p[i-2] + p[i-3]
    }
    return p
}

func padovanFloor(n int) []int {
    var p, s, t, u = new(big.Rat), new(big.Rat), new(big.Rat), new(big.Rat)
    p, _ = p.SetString("1.324717957244746025960908854")
    s, _ = s.SetString("1.0453567932525329623")
    f := make([]int, n)
    pow := new(big.Rat).SetInt64(1)
    u = u.SetFrac64(1, 2)
    t.Quo(pow, p)
    t.Quo(t, s)
    t.Add(t, u)
    v, _ := t.Float64()
    f[0] = int(math.Floor(v))
    for i := 1; i < n; i++ {
        t.Quo(pow, s)
        t.Add(t, u)
        v, _ = t.Float64()
        f[i] = int(math.Floor(v))
        pow.Mul(pow, p)
    }
    return f
}

type LSystem struct {
    rules         map[string]string
    init, current string
}

func step(lsys *LSystem) string {
    var sb strings.Builder
    if lsys.current == "" {
        lsys.current = lsys.init
    } else {
        for _, c := range lsys.current {
            sb.WriteString(lsys.rules[string(c)])
        }
        lsys.current = sb.String()
    }
    return lsys.current
}

func padovanLSys(n int) []string {
    rules := map[string]string{"A": "B", "B": "C", "C": "AB"}
    lsys := &LSystem{rules, "A", ""}
    p := make([]string, n)
    for i := 0; i < n; i++ {
        p[i] = step(lsys)
    }
    return p
}

// assumes lists are same length
func areSame(l1, l2 []int) bool {
    for i := 0; i < len(l1); i++ {
        if l1[i] != l2[i] {
            return false
        }
    }
    return true
}

func main() {
    fmt.Println("First 20 members of the Padovan sequence:")
    fmt.Println(padovanRecur(20))
    recur := padovanRecur(64)
    floor := padovanFloor(64)
    same := areSame(recur, floor)
    s := "give"
    if !same {
        s = "do not give"
    }
    fmt.Println("\nThe recurrence and floor based functions", s, "the same results for 64 terms.")

    p := padovanLSys(32)
    lsyst := make([]int, 32)
    for i := 0; i < 32; i++ {
        lsyst[i] = len(p[i])
    }
    fmt.Println("\nFirst 10 members of the Padovan L-System:")
    fmt.Println(p[:10])
    fmt.Println("\nand their lengths:")
    fmt.Println(lsyst[:10])

    same = areSame(recur[:32], lsyst)
    s = "give"
    if !same {
        s = "do not give"
    }
    fmt.Println("\nThe recurrence and L-system based functions", s, "the same results for 32 terms.")


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:
package main

import (
    "fmt"
    "time"
)

func reverse(s string) string {
    chars := []rune(s)
    for i, j := 0, len(chars)-1; i < j; i, j = i+1, j-1 {
        chars[i], chars[j] = chars[j], chars[i]
    }
    return string(chars)
}

func main() {
    const (
        layout  = "20060102"
        layout2 = "2006-01-02"
    )
    fmt.Println("The next 15 palindromic dates in yyyymmdd format after 20200202 are:")
    date := time.Date(2020, 2, 2, 0, 0, 0, 0, time.UTC)
    count := 0
    for count < 15 {
        date = date.AddDate(0, 0, 1)
        s := date.Format(layout)
        r := reverse(s)
        if r == s {
            fmt.Println(date.Format(layout2))
            count++
        }
    }
}


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:
:*   palindrome detection.
:*   gapful numbers.

;Also see:
:*   The OEIS entry:   A108343 gapful numbers.

Solution:
package main

import "fmt"

func reverse(s uint64) uint64 {
    e := uint64(0)
    for s > 0 {
        e = e*10 + (s % 10)
        s /= 10
    }
    return e
}

func commatize(n uint) string {
    s := fmt.Sprintf("%d", n)
    le := len(s)
    for i := le - 3; i >= 1; i -= 3 {
        s = s[0:i] + "," + s[i:]
    }
    return s
}

func ord(n uint) string {
    var suffix string
    if n > 10 && ((n-11)%100 == 0 || (n-12)%100 == 0 || (n-13)%100 == 0) {
        suffix = "th"
    } else {
        switch n % 10 {
        case 1:
            suffix = "st"
        case 2:
            suffix = "nd"
        case 3:
            suffix = "rd"
        default:
            suffix = "th"
        }
    }
    return fmt.Sprintf("%s%s", commatize(n), suffix)
}

func main() {
    const max = 10_000_000
    data := [][3]uint{{1, 20, 7}, {86, 100, 8}, {991, 1000, 10}, {9995, 10000, 12}, {1e5, 1e5, 14},
        {1e6, 1e6, 16}, {1e7, 1e7, 18}}
    results := make(map[uint][]uint64)
    for _, d := range data {
        for i := d[0]; i <= d[1]; i++ {
            results[i] = make([]uint64, 9)
        }
    }
    var p uint64
outer:
    for d := uint64(1); d < 10; d++ {
        count := uint(0)
        pow := uint64(1)
        fl := d * 11
        for nd := 3; nd < 20; nd++ {
            slim := (d + 1) * pow
            for s := d * pow; s < slim; s++ {
                e := reverse(s)
                mlim := uint64(1)
                if nd%2 == 1 {
                    mlim = 10
                }
                for m := uint64(0); m < mlim; m++ {
                    if nd%2 == 0 {
                        p = s*pow*10 + e
                    } else {
                        p = s*pow*100 + m*pow*10 + e
                    }
                    if p%fl == 0 {
                        count++
                        if _, ok := results[count]; ok {
                            results[count][d-1] = p
                        }
                        if count == max {
                            continue outer
                        }
                    }
                }
            }
            if nd%2 == 1 {
                pow *= 10
            }
        }
    }

    for _, d := range data {
        if d[0] != d[1] {
            fmt.Printf("%s to %s palindromic gapful numbers (> 100) ending with:\n", ord(d[0]), ord(d[1]))
        } else {
            fmt.Printf("%s palindromic gapful number (> 100) ending with:\n", ord(d[0]))
        }
        for i := 1; i <= 9; i++ {
            fmt.Printf("%d: ", i)
            for j := d[0]; j <= d[1]; j++ {
                fmt.Printf("%*d ", d[2], results[j][i-1])
            }
            fmt.Println()
        }
        fmt.Println()
    }
}


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
# Bill Gates and the pancake problem
# A058986

Solution:
package main

import "fmt"

func pancake(n int) int {
    gap, sum, adj := 2, 2, -1
    for sum < n {
        adj++
        gap = gap*2 - 1
        sum += gap
    }
    return n + adj
}

func main() {
    for i := 0; i < 4; i++ {
        for j := 1; j < 6; j++ {
            n := i*5 + j
            fmt.Printf("p(%2d) = %2d  ", n, pancake(n))
        }
        fmt.Println()
    }
}


Pancake numbers

Solution:
package main

import (
    "fmt"
    "strconv"
    "strings"
    "time"
)

type assoc map[string]int

// Converts a string of the form "[1 2]" into a slice of ints: {1, 2}
func asSlice(s string) []int {
    split := strings.Split(s[1:len(s)-1], " ")
    le := len(split)
    res := make([]int, le)
    for i := 0; i < le; i++ {
        res[i], _ = strconv.Atoi(split[i])
    }
    return res
}

// Merges two assocs into one. If the same key is present in both assocs
// its value will be the one in the second assoc.
func merge(m1, m2 assoc) assoc {
    m3 := make(assoc)
    for k, v := range m1 {
        m3[k] = v
    }
    for k, v := range m2 {
        m3[k] = v
    }
    return m3
}

// Finds the maximum value in 'dict' and returns the first key
// it finds (iteration order is undefined) with that value.
func findMax(dict assoc) string {
    max := -1
    maxKey := ""
    for k, v := range dict {
        if v > max {
            max = v
            maxKey = k
        }
    }
    return maxKey
}

// Creates a new slice of ints by reversing an existing one.
func reverse(s []int) []int {
    le := len(s)
    rev := make([]int, le)
    for i := 0; i < le; i++ {
        rev[i] = s[le-1-i]
    }
    return rev
}

func pancake(n int) (string, int) {
    numStacks := 1
    gs := make([]int, n)
    for i := 0; i < n; i++ {
        gs[i] = i + 1
    }
    goalStack := fmt.Sprintf("%v", gs)
    stacks := assoc{goalStack: 0}
    newStacks := assoc{goalStack: 0}
    for i := 1; i <= 1000; i++ {
        nextStacks := assoc{}
        for key := range newStacks {
            arr := asSlice(key)
            for pos := 2; pos <= n; pos++ {
                t := append(reverse(arr[0:pos]), arr[pos:len(arr)]...)
                newStack := fmt.Sprintf("%v", t)
                if _, ok := stacks[newStack]; !ok {
                    nextStacks[newStack] = i
                }
            }
        }
        newStacks = nextStacks
        stacks = merge(stacks, newStacks)
        perms := len(stacks)
        if perms == numStacks {
            return findMax(stacks), i - 1
        }
        numStacks = perms
    }
    return "", 0
}

func main() {
    start := time.Now()
    fmt.Println("The maximum number of flips to sort a given number of elements is:")
    for i := 1; i <= 10; i++ {
        example, steps := pancake(i)
        fmt.Printf("pancake(%2d) = %-2d  example: %s\n", i, steps, example)
    }
    fmt.Printf("\nTook %s\n", time.Since(start))
}


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:
:*   determine if a string has all the same characters
:*   determine if a string has all unique characters

Solution:
package main

import "fmt"

func main() {
    for _, s := range []string{
        "The quick brown fox jumps over the lazy dog.",
        `Watch "Jeopardy!", Alex Trebek's fun TV quiz game.`,
        "Not a pangram.",
    } {
        if pangram(s) {
            fmt.Println("Yes:", s)
        } else {
            fmt.Println("No: ", s)
        }
    }
}

func pangram(s string) bool {
	var missing uint32 = (1 << 26) - 1
	for _, c := range s {
		var index uint32
		if 'a' <= c && c <= 'z' {
			index = uint32(c - 'a')
		} else if 'A' <= c && c <= 'Z' {
			index = uint32(c - 'A')
		} else {
			continue
		}

		missing &^= 1 << index
		if missing == 0 {
			return true
		}
	}
	return false
}