Spelling of ordinal numbers

'''Ordinal numbers'''   (as used in this Rosetta Code task),   are numbers that describe the   ''position''   of something in a list.

It is this context that ordinal numbers will be used, using an English-spelled name of an ordinal number.

The ordinal numbers are   (at least, one form of them):
   1st  2nd  3rd  4th  5th  6th  7th  ***  99th  100th  ***  1000000000th  ***  etc

sometimes expressed as:
   1st  2nd  3rd  4th  5th  6th  7th  ***  99th  100th  ***  1000000000th  ***

For this task, the following (English-spelled form) will be used:
   first second third fourth fifth sixth seventh ninety-nineth one hundredth one billionth

Furthermore, the American version of numbers will be used here   (as opposed to the British).

'''2,000,000,000'''   is two billion,   ''not''   two milliard.

;Task:
Write a driver and a function (subroutine/routine ***) that returns the English-spelled ordinal version of a specified number   (a positive integer).

Optionally, try to support as many forms of an integer that can be expressed:   '''123'''   '''00123.0'''   '''1.23e2'''   all are forms of the same integer.

Show all output here.

;Test cases:
Use (at least) the test cases of:
   1  2  3  4  5  11  65  100  101  272  23456  8007006005004003

;Related tasks:
*   [[Number names]]
*   [[N'th]]

Solution:
// version 1.1.4-3

typealias IAE = IllegalArgumentException

val names = mapOf(
    1 to "one",
    2 to "two",
    3 to "three",
    4 to "four",
    5 to "five",
    6 to "six",
    7 to "seven",
    8 to "eight",
    9 to "nine",
    10 to "ten",
    11 to "eleven",
    12 to "twelve",
    13 to "thirteen",
    14 to "fourteen",
    15 to "fifteen",
    16 to "sixteen",
    17 to "seventeen",
    18 to "eighteen",
    19 to "nineteen",
    20 to "twenty",
    30 to "thirty",
    40 to "forty",
    50 to "fifty",
    60 to "sixty",
    70 to "seventy",
    80 to "eighty",
    90 to "ninety"
)
val bigNames = mapOf(
    1_000L to "thousand",
    1_000_000L to "million",
    1_000_000_000L to "billion",
    1_000_000_000_000L to "trillion",
    1_000_000_000_000_000L to "quadrillion",
    1_000_000_000_000_000_000L to "quintillion"
)

val irregOrdinals = mapOf(
    "one" to "first",
    "two" to "second",
    "three" to "third",
    "five" to "fifth",
    "eight" to "eighth",
    "nine" to "ninth",
    "twelve" to "twelfth"
)

fun String.toOrdinal(): String {
    val splits = this.split(' ', '-')
    var last = splits[splits.lastIndex]
    return if (irregOrdinals.containsKey(last)) this.dropLast(last.length) + irregOrdinals[last]!!
           else if (last.endsWith("y")) this.dropLast(1) + "ieth"
           else this + "th"
}

fun numToOrdinalText(n: Long, uk: Boolean = false): String {
    if (n == 0L) return "zeroth"  // or alternatively 'zeroeth'
    val neg = n < 0L
    val maxNeg = n == Long.MIN_VALUE
    var nn = if (maxNeg) -(n + 1) else if (neg) -n else n
    val digits3 = IntArray(7)
    for (i in 0..6) {  // split number into groups of 3 digits from the right
        digits3[i] = (nn % 1000).toInt()
        nn /= 1000
    }

    fun threeDigitsToText(number: Int) : String {
        val sb = StringBuilder()
        if (number == 0) return ""
        val hundreds = number / 100
        val remainder = number % 100
        if (hundreds > 0) {
            sb.append(names[hundreds], " hundred")
            if (remainder > 0) sb.append(if (uk) " and " else " ")
        }
        if (remainder > 0) {
            val tens = remainder / 10
            val units = remainder % 10
            if (tens > 1) {
                sb.append(names[tens * 10])
                if (units > 0) sb.append("-", names[units])
            }
            else sb.append(names[remainder])
        }
        return sb.toString()
    }

    val strings = Array<String>(7) { threeDigitsToText(digits3[it]) }
    var text = strings[0]
    var andNeeded = uk && digits3[0] in 1..99
    var big = 1000L
    for (i in 1..6) {
        if (digits3[i] > 0) {
            var text2 = strings[i] + " " + bigNames[big]
            if (text.length > 0) {
                text2 += if (andNeeded) " and " else ", "
                andNeeded = false
            }
            else andNeeded = uk && digits3[i] in 1..99
            text = text2 + text
        }
        big *= 1000
    }
    if (maxNeg) text = text.dropLast(5) + "eight"
    if (neg) text = "minus " + text
    return text.toOrdinal()
}

fun numToOrdinalText(s: String, uk: Boolean = false): String {
    val d = s.toDoubleOrNull() ?: throw IAE("String is not numeric")
    if (d !in Long.MIN_VALUE.toDouble() .. Long.MAX_VALUE.toDouble())
        throw IAE("Double is outside the range of a Long Integer")
    val n = d.toLong()
    if (n.toDouble() != d) throw IAE("String does not represent a Long Integer")
    return numToOrdinalText(n, uk)
}

fun main(args: Array<String>) {
    val la = longArrayOf(1, 2, 3, 4, 5, 11, 65, 100, 101, 272, 23456, 8007006005004003)
    println("Using US representation:")
    for (i in la) println("${"%16d".format(i)} = ${numToOrdinalText(i)}")
    val sa = arrayOf("123", "00123.0", "1.23e2")
    for (s in sa) println("${"%16s".format(s)} = ${numToOrdinalText(s)}")
}


Split a character string based on change of character

Split a (character) string into comma (plus a blank) delimited
strings based on a change of character   (left to right).

Show the output here   (use the 1st example below).

Blanks should be treated as any other character   (except
they are problematic to display clearly).   The same applies
to commas.

For instance, the string:
  gHHH5YY++///\
should be split and show:
  g, HHH, 5, YY, ++, ///, \

Solution:
// version 1.0.6

fun splitOnChange(s: String): String {
    if (s.length < 2) return s
    var t = s.take(1)
    for (i in 1 until s.length)
        if (t.last() == s[i]) t += s[i]
        else t += ", " + s[i]
    return t
}

fun main(args: Array<String>) {
    val s = """gHHH5YY++///\"""
    println(splitOnChange(s))
}


Square-free integers

Write a function to test if a number is   ''square-free''.

A   ''square-free''   is an integer which is divisible by no perfect square other
than   '''1'''   (unity).

For this task, only positive square-free numbers will be used.

Show here (on this page) all square-free integers (in a horizontal format) that are between:
::*   '''1'''            --->   '''145'''                        (inclusive)
::*   '''1''' trillion   --->   '''1''' trillion + '''145'''     (inclusive)

(One trillion = 1,000,000,000,000)

Show here (on this page) the count of square-free integers from:
::*   '''1'''            --->   one hundred                      (inclusive)
::*   '''1'''            --->   one thousand                     (inclusive)
::*   '''1'''            --->   ten thousand                     (inclusive)
::*   '''1'''            --->   one hundred thousand             (inclusive)
::*   '''1'''            --->   one million                      (inclusive)

;See also:
:*   the Wikipedia entry:   square-free integer

Solution:
// Version 1.2.50

import kotlin.math.sqrt

fun sieve(limit: Long): List<Long> {
    val primes = mutableListOf(2L)
    val c = BooleanArray(limit.toInt() + 1) // composite = true
    // no need to process even numbers > 2
    var p = 3
    while (true) {
        val p2 = p * p
        if (p2 > limit) break
        for (i in p2..limit step 2L * p) c[i.toInt()] = true
        do { p += 2 } while (c[p])
    }
    for (i in 3..limit step 2)
        if (!c[i.toInt()])
            primes.add(i)

    return primes
}

fun squareFree(r: LongProgression): List<Long> {
    val primes = sieve(sqrt(r.last.toDouble()).toLong())
    val results = mutableListOf<Long>()
    outer@ for (i in r) {
        for (p in primes) {
            val p2 = p * p
            if (p2 > i) break
            if (i % p2 == 0L) continue@outer
        }
        results.add(i)
    }
    return results
}

fun printResults(r: LongProgression, c: Int, f: Int) {
    println("Square-free integers from ${r.first} to ${r.last}:")
    squareFree(r).chunked(c).forEach {
        println()
        it.forEach { print("%${f}d".format(it)) }
    }
    println('\n')
}

const val TRILLION = 1000000_000000L

fun main(args: Array<String>) {
    printResults(1..145L, 20, 4)
    printResults(TRILLION..TRILLION + 145L, 5, 14)

    println("Number of square-free integers:\n")
    longArrayOf(100, 1000, 10000, 100000, 1000000).forEach {
        j -> println("  from 1 to $j = ${squareFree(1..j).size}")
    }
}


Square but not cube

Show the first   '''30'''   positive integers which are squares but not cubes of such integers.

Optionally, show also the first   '''3'''   positive integers which are both squares and cubes,   and mark them as such.

Solution:
// Version 1.2.60

fun main(args: Array<String>) {
    var n = 1
    var count = 0
    while (count < 30) {
        val sq = n * n
        val cr = Math.cbrt(sq.toDouble()).toInt()
        if (cr * cr * cr != sq) {
            count++
            println(sq)
        }
        else {
            println("$sq is square and cube")
        }
        n++
    }
}


Stair-climbing puzzle

From Chung-Chieh Shan (LtU):

Your stair-climbing robot has a very simple low-level API: the "step" function takes no argument and attempts to climb one step as a side effect. Unfortunately, sometimes the attempt fails and the robot clumsily falls one step instead. The "step" function detects what happens and returns a boolean flag: true on success, false on failure.

Write a function "step_up" that climbs one step up [from the initial position] (by repeating "step" attempts if necessary). Assume that the robot is not already at the top of the stairs, and neither does it ever reach the bottom of the stairs. How small can you make "step_up"? Can you avoid using variables (even immutable ones) and numbers?

Here's a pseudo-code of a simple recursive solution without using variables:

func step_up()
{
    if not step() {
        step_up();
        step_up();
    }
}

Inductive proof that step_up() steps up one step, if it terminates:
* Base case (if the step() call returns true): it stepped up one step. QED
* Inductive case (if the step() call returns false): Assume that recursive calls to step_up() step up one step. It stepped down one step (because step() returned false), but now we step up two steps using two step_up() calls. QED

The second (tail) recursion above can be turned into an iteration, as follows:

func step_up()
{
    while not step() {
        step_up();
    }
}

Solution:
// version 1.2.0

import java.util.Random

val rand = Random(6321L) // generates short repeatable sequence
var position = 0

fun step(): Boolean {
    val r = rand.nextBoolean()
    if (r)
        println("Climbed up to ${++position}")
    else
        println("Fell down to ${--position}")
    return r
}

fun stepUp() {
    while (!step()) stepUp()
}

fun main(args: Array<String>) {
    stepUp()
}


Start from a main routine

Some languages (like Gambas and Visual Basic) support two startup modes.   Applications written in these languages start with an open window that waits for events, and it is necessary to do some trickery to cause a main procedure to run instead.   Data driven or event driven languages may also require similar trickery to force a startup procedure to run.

;Task:
Demonstrate the steps involved in causing the application to run a main procedure, rather than an event driven window at startup.

Languages that always run from main() can be omitted from this task.

Solution: The version of Kotlin which targets the JVM always starts from the main(args: Array<String>) function unless it is running in REPL mode when it simply executes lines of executable code in the order presented. The REPL is started by typing, kotlinc, without any parameters at the command prompt. For example:


Statistics/Normal distribution

The derive normally distributed random numbers from a uniform generator.

;The task:
# Take a uniform random number generator and create a large (you decide how large) set of numbers that follow a normal (Gaussian) distribution.  Calculate the dataset's mean and standard deviation, and show a histogram of the data.
# Mention any native language support for the generation of normally distributed random numbers.

;Reference:
* You may refer to code in [[Statistics/Basic]] if available.

Solution:
// version 1.1.2

val rand = java.util.Random()

fun normalStats(sampleSize: Int) {
    if (sampleSize < 1) return
    val r = DoubleArray(sampleSize)
    val h = IntArray(12) // all zero by default
    /*
       Generate 'sampleSize' normally distributed random numbers with mean 0.5 and SD 0.25
       and calculate in which box they will fall when drawing the histogram
    */
    for (i in 0 until sampleSize) {
        r[i] = 0.5 + rand.nextGaussian() / 4.0
        when {
            r[i] <  0.0 -> h[0]++
            r[i] >= 1.0 -> h[11]++
            else        -> h[1 + (r[i] * 10).toInt()]++
        }
    }

    // adjust one of the h[] values if necessary to ensure they sum to sampleSize
    val adj = sampleSize - h.sum()
    if (adj != 0) {
        for (i in 0..11) {
            h[i] += adj
            if (h[i] >= 0) break
            h[i] -= adj
        }
    }

    val mean = r.average()
    val sd = Math.sqrt(r.map { (it - mean) * (it - mean) }.average())

    // Draw a histogram of the data with interval 0.1
    var numStars: Int
    // If sample size > 300 then normalize histogram to 300
    val scale = if (sampleSize <= 300) 1.0 else 300.0 / sampleSize
    println("Sample size $sampleSize\n")
    println("  Mean ${"%1.6f".format(mean)}  SD ${"%1.6f".format(sd)}\n")
    for (i in 0..11) {
        when (i) {
            0    -> print("< 0.00 : ")
            11   -> print(">=1.00 : ")
            else -> print("  %1.2f : ".format(i / 10.0))
        }
        print("%5d ".format(h[i]))
        numStars = (h[i] * scale + 0.5).toInt()
        println("*".repeat(numStars))
    }
    println()
}

fun main(args: Array<String>) {
    val sampleSizes = intArrayOf(100, 1_000, 10_000, 100_000)
    for (sampleSize in sampleSizes) normalStats(sampleSize)
}


Stern-Brocot sequence

For this task, the Stern-Brocot sequence is to be generated by an algorithm similar to that employed in generating the [[Fibonacci sequence]].

# The first and second members of the sequence are both 1:
#*     1, 1
# Start by considering the second member of the sequence
# Sum the considered member of the sequence and its precedent, (1 + 1) = 2, and append it to the end of the sequence:
#*     1, 1, 2
# Append the considered member of the sequence to the end of the sequence:
#*     1, 1, 2, 1
# Consider the next member of the series, (the third member i.e. 2)
# GOTO 3
#*
#*         --- Expanding another loop we get: ---
#*
# Sum the considered member of the sequence and its precedent, (2 + 1) = 3, and append it to the end of the sequence:
#*     1, 1, 2, 1, 3
# Append the considered member of the sequence to the end of the sequence:
#*     1, 1, 2, 1, 3, 2
# Consider the next member of the series, (the fourth member i.e. 1)

;The task is to:
* Create a function/method/subroutine/procedure/... to generate the Stern-Brocot sequence of integers using the method outlined above.
* Show the first fifteen members of the sequence. (This should be: 1, 1, 2, 1, 3, 2, 3, 1, 4, 3, 5, 2, 5, 3, 4)
* Show the (1-based) index of where the numbers 1-to-10 first appear in the sequence.
* Show the (1-based) index of where the number 100 first appears in the sequence.
* Check that the greatest common divisor of all the two consecutive members of the series up to the 1000th member, is always one.

Show your output on this page.

;Related tasks:
:*   [[Fusc sequence]].
:*   [[Continued fraction/Arithmetic]]

;Ref:
* Infinite Fractions - Numberphile (Video).
* Trees, Teeth, and Time: The mathematics of clock making.
* A002487 The On-Line Encyclopedia of Integer Sequences.

Solution:
// version 1.1.0

val sbs = mutableListOf(1, 1)

fun sternBrocot(n: Int, fromStart: Boolean = true) {
    if (n < 4 || (n % 2 != 0)) throw IllegalArgumentException("n must be >= 4 and even")
    var consider = if (fromStart) 1 else n / 2 - 1
    while (true) {
        val sum = sbs[consider] + sbs[consider - 1]
        sbs.add(sum)
        sbs.add(sbs[consider])
        if (sbs.size == n) break
        consider++
    }
}

fun gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)

fun main(args: Array<String>) {
    var n = 16  // needs to be even to ensure 'considered' number is added
    println("First 15 members of the Stern-Brocot sequence")
    sternBrocot(n)
    println(sbs.take(15))

    val firstFind = IntArray(11)  // all zero by default
    firstFind[0] = -1 // needs to be non-zero for subsequent test
    for ((i, v) in sbs.withIndex())
        if (v <= 10 && firstFind[v] == 0) firstFind[v] = i + 1
    loop@ while (true) {
        n += 2
        sternBrocot(n, false)
        val vv = sbs.takeLast(2)
        var m = n - 1
        for (v in vv) {
            if (v <= 10 && firstFind[v] == 0) firstFind[v] = m
            if (firstFind.all { it != 0 }) break@loop
            m++
        }
    }
    println("\nThe numbers 1 to 10 first appear at the following indices:")
    for (i in 1..10) println("${"%2d".format(i)} -> ${firstFind[i]}")

    print("\n100 first appears at index ")
    while (true) {
        n += 2
        sternBrocot(n, false)
        val vv = sbs.takeLast(2)
        if (vv[0] == 100) {
            println(n - 1); break
        }
        if (vv[1] == 100) {
            println(n); break
        }
    }

    print("\nThe GCDs of each pair of the series up to the 1000th member are ")
    for (p in 0..998 step 2) {
        if (gcd(sbs[p], sbs[p + 1]) != 1) {
            println("not all one")
            return
        }
    }
    println("all one")
}


Stirling numbers of the first kind

Stirling numbers of the first kind, or Stirling cycle numbers, count permutations according to their number
of cycles (counting fixed points as cycles of length one).

They may be defined directly to be the number of permutations of '''n'''
elements with '''k''' disjoint cycles.

Stirling numbers of the first kind express coefficients of polynomial expansions of falling or rising factorials.

Depending on the application, Stirling numbers of the first kind may be "signed"
or "unsigned". Signed Stirling numbers of the first kind arise when the
polynomial expansion is expressed in terms of falling factorials; unsigned when
expressed in terms of rising factorials. The only substantial difference is that,
for signed Stirling numbers of the first kind, values of S1(n, k) are negative
when n + k is odd.

Stirling numbers of the first kind follow the simple identities:

    S1(0, 0) = 1
    S1(n, 0) = 0 if n > 0
    S1(n, k) = 0 if k > n
    S1(n, k) = S1(n - 1, k - 1) + (n - 1) * S1(n - 1, k) # For unsigned
      ''or''
    S1(n, k) = S1(n - 1, k - 1) - (n - 1) * S1(n - 1, k) # For signed

;Task:

:* Write a routine (function, procedure, whatever) to find '''Stirling numbers of the first kind'''. There are several methods to generate Stirling numbers of the first kind. You are free to choose the most appropriate for your language. If your language has a built-in, or easily, publicly available library implementation, it is acceptable to use that.

:* Using the routine, generate and show here, on this page, a table (or triangle) showing the Stirling numbers of the first kind, '''S1(n, k)''', up to '''S1(12, 12)'''. it is optional to show the row / column for n == 0 and k == 0. It is optional to show places where S1(n, k) == 0 (when k > n). You may choose to show signed or unsigned Stirling numbers of the first kind, just make a note of which was chosen.

:* If your language supports large integers, find and show here, on this page, the maximum value of '''S1(n, k)''' where '''n == 100'''.

;See also:

:* '''Wikipedia - Stirling numbers of the first kind'''
:* '''OEIS:A008275 - Signed Stirling numbers of the first kind'''
:* '''OEIS:A130534 - Unsigned Stirling numbers of the first kind'''

;Related Tasks:

:* '''Stirling numbers of the second kind'''
:* '''Lah numbers'''

Solution:
import java.math.BigInteger

fun main() {
    println("Unsigned Stirling numbers of the first kind:")
    val max = 12
    print("n/k")
    for (n in 0..max) {
        print("%10d".format(n))
    }
    println()
    for (n in 0..max) {
        print("%-3d".format(n))
        for (k in 0..n) {
            print("%10s".format(sterling1(n, k)))
        }
        println()
    }
    println("The maximum value of S1(100, k) = ")
    var previous = BigInteger.ZERO
    for (k in 1..100) {
        val current = sterling1(100, k)
        previous = if (current!! > previous) {
            current
        } else {
            println("$previous\n(${previous.toString().length} digits, k = ${k - 1})")
            break
        }
    }
}

private val COMPUTED: MutableMap<String, BigInteger?> = HashMap()
private fun sterling1(n: Int, k: Int): BigInteger? {
    val key = "$n,$k"
    if (COMPUTED.containsKey(key)) {
        return COMPUTED[key]
    }

    if (n == 0 && k == 0) {
        return BigInteger.valueOf(1)
    }
    if (n > 0 && k == 0) {
        return BigInteger.ZERO
    }
    if (k > n) {
        return BigInteger.ZERO
    }

    val result = sterling1(n - 1, k - 1)!!.add(BigInteger.valueOf(n - 1.toLong()).multiply(sterling1(n - 1, k)))
    COMPUTED[key] = result
    return result
}


Stirling numbers of the second kind

Stirling numbers of the second kind, or Stirling partition numbers, are the
number of ways to partition a set of n objects into k non-empty subsets. They are
closely related to [[Bell numbers]], and may be derived from them.

Stirling numbers of the second kind obey the recurrence relation:

    S2(n, 0) and S2(0, k) = 0 # for n, k > 0
    S2(n, n) = 1
    S2(n + 1, k) = k * S2(n, k) + S2(n, k - 1)

;Task:

:* Write a routine (function, procedure, whatever) to find '''Stirling numbers of the second kind'''. There are several methods to generate Stirling numbers of the second kind. You are free to choose the most appropriate for your language. If your language has a built-in, or easily, publicly available library implementation, it is acceptable to use that.

:* Using the routine, generate and show here, on this page, a table (or triangle) showing the Stirling numbers of the second kind, '''S2(n, k)''', up to '''S2(12, 12)'''. it is optional to show the row / column for n == 0 and k == 0. It is optional to show places where S2(n, k) == 0 (when k > n).

:* If your language supports large integers, find and show here, on this page, the maximum value of '''S2(n, k)''' where '''n == 100'''.

;See also:

:* '''Wikipedia - Stirling numbers of the second kind'''
:* '''OEIS:A008277 - Stirling numbers of the second kind'''

;Related Tasks:

:* '''Stirling numbers of the first kind'''
:* '''Bell numbers'''
:* '''Lah numbers'''

Solution:
import java.math.BigInteger

fun main() {
    println("Stirling numbers of the second kind:")
    val max = 12
    print("n/k")
    for (n in 0..max) {
        print("%10d".format(n))
    }
    println()
    for (n in 0..max) {
        print("%-3d".format(n))
        for (k in 0..n) {
            print("%10s".format(sterling2(n, k)))
        }
        println()
    }
    println("The maximum value of S2(100, k) = ")
    var previous = BigInteger.ZERO
    for (k in 1..100) {
        val current = sterling2(100, k)
        previous = if (current > previous) {
            current
        } else {
            println("%s%n(%d digits, k = %d)".format(previous, previous.toString().length, k - 1))
            break
        }
    }
}

private val COMPUTED: MutableMap<String, BigInteger> = HashMap()
private fun sterling2(n: Int, k: Int): BigInteger {
    val key = "$n,$k"
    if (COMPUTED.containsKey(key)) {
        return COMPUTED[key]!!
    }
    if (n == 0 && k == 0) {
        return BigInteger.valueOf(1)
    }
    if (n > 0 && k == 0 || n == 0 && k > 0) {
        return BigInteger.ZERO
    }
    if (n == k) {
        return BigInteger.valueOf(1)
    }
    if (k > n) {
        return BigInteger.ZERO
    }

    val result = BigInteger.valueOf(k.toLong()) * sterling2(n - 1, k) + sterling2(n - 1, k - 1)
    COMPUTED[key] = result
    return result
}


Stream merge

 2-stream merge
: Read two sorted streams of items from external source (e.g. disk, or network), and write one stream of sorted items to external sink.
: Common algorithm: keep 1 buffered item from each source, select minimal of them, write it, fetch another item from that stream from which the written item was.

; ''N''-stream merge
: The same as above, but reading from    ''N''    sources.
: Common algorithm: same as above, but keep buffered items and their source descriptors in a [[heap]].

Assume streams are very big. You must not suck them whole in the memory, but read them as streams.

Solution:
// version 1.2.21

import java.io.File

fun merge2(inputFile1: String, inputFile2: String, outputFile: String) {
    val file1 = File(inputFile1)
    val file2 = File(inputFile2)
    require(file1.exists() && file2.exists()) { "Both input files must exist" }
    val reader1 = file1.bufferedReader()
    val reader2 = file2.bufferedReader()
    val writer  = File(outputFile).printWriter()
    var line1 = reader1.readLine()
    var line2 = reader2.readLine()
    while (line1 != null && line2 != null) {
        if (line1 <= line2) {
            writer.println(line1)
            line1 = reader1.readLine()
        }
        else {
            writer.println(line2)
            line2 = reader2.readLine()
        }
    }
    while (line1 != null) {
        writer.println(line1)
        line1 = reader1.readLine()
    }
    while (line2 != null) {
        writer.println(line2)
        line2 = reader2.readLine()
    }
    reader1.close()
    reader2.close()
    writer.close()
}

fun mergeN(inputFiles: List<String>, outputFile: String) {
    val files = inputFiles.map { File(it) }
    require(files.all { it.exists() }) { "All input files must exist" }
    val readers = files.map { it.bufferedReader() }
    val writer  = File(outputFile).printWriter()
    var lines = readers.map { it.readLine() }.toMutableList()
    while (lines.any { it != null }) {
        val line = lines.filterNotNull().min()
        val index = lines.indexOf(line)
        writer.println(line)
        lines[index] = readers[index].readLine()
    }
    readers.forEach { it.close() }
    writer.close()
}

fun main(args:Array<String>) {
    val files = listOf("merge1.txt", "merge2.txt", "merge3.txt", "merge4.txt")
    merge2(files[0], files[1], "merged2.txt")
    mergeN(files, "mergedN.txt")
    // check it worked
    println(File("merged2.txt").readText())
    println(File("mergedN.txt").readText())
}


Strip control codes and extended characters from a string.

The solution should demonstrate how to achieve each of the following results:
:*   a string with control codes stripped (but extended characters not stripped)
:*   a string with control codes and extended characters stripped

In ASCII, the control codes have decimal codes 0 through to 31 and 127.

On an ASCII based system, if the control codes are stripped, the resultant string would have all of its characters within the range of 32 to 126 decimal on the ASCII table.

On a non-ASCII based system, we consider characters that do not have a corresponding glyph on the ASCII table (within the ASCII range of 32 to 126 decimal) to be an extended character for the purpose of this task.

Solution:
// version 1.1.2

fun String.strip(extendedChars: Boolean = false): String {
    val sb = StringBuilder()
    for (c in this) {
        val i = c.toInt()
        if (i in 32..126 || (!extendedChars && i >= 128)) sb.append(c)
    }
    return sb.toString()
}

fun main(args: Array<String>) {
    println("Originally:")
    val s = "123\tabc\u0007DEF\u007F+-*/€æŧðłþ"
    println("String = $s  Length = ${s.length}")
    println("\nAfter stripping control characters:")
    val t = s.strip()
    println("String = $t  Length = ${t.length}")
    println("\nAfter stripping control and extended characters:")
    val u = s.strip(true)
    println("String = $u  Length = ${u.length}")
}


Subleq

One-Instruction Set Computer (OISC).

It is named after its only instruction, which is '''SU'''btract and '''B'''ranch if '''L'''ess than or '''EQ'''ual to zero.

;Task
Your task is to create an interpreter which emulates a SUBLEQ machine.

The machine's memory consists of an array of signed integers.   These integers may be interpreted in three ways:
::::*   simple numeric values
::::*   memory addresses
::::*   characters for input or output

Any reasonable word size that accommodates all three of the above uses is fine.

The program should load the initial contents of the emulated machine's memory, set the instruction pointer to the first address (which is defined to be address 0), and begin emulating the machine, which works as follows:
:#   Let '''A''' be the value in the memory location identified by the instruction pointer;   let '''B''' and '''C''' be the values stored in the next two consecutive addresses in memory.
:#   Advance the instruction pointer three words, to point at the address ''after'' the address containing '''C'''.
:#   If '''A''' is   '''-1'''   (negative unity),   then a character is read from the machine's input and its numeric value stored in the address given by '''B'''.   '''C''' is unused.
:#   If '''B''' is   '''-1'''   (negative unity),   then the number contained in the address given by '''A''' is interpreted as a character and written to the machine's output.   '''C''' is unused.
:#   Otherwise, both '''A''' and '''B''' are treated as addresses.   The number contained in address '''A''' is subtracted from the number in address '''B''' (and the difference left in address '''B''').   If the result is positive, execution continues uninterrupted; if the result is zero or negative, the number in '''C''' becomes the new instruction pointer.
:#   If the instruction pointer becomes negative, execution halts.

Your solution may initialize the emulated machine's memory in any convenient manner, but if you accept it as input, it should be a separate input stream from the one fed to the emulated machine once it is running. And if fed as text input, it should be in the form of raw subleq "machine code" - whitespace-separated decimal numbers, with no symbolic names or other assembly-level extensions, to be loaded into memory starting at address   '''0'''   (zero).

For purposes of this task, show the output of your solution when fed the below   "Hello, world!"   program.

As written, this example assumes ASCII or a superset of it, such as any of the Latin-N character sets or Unicode;   you may translate the numbers representing characters (starting with 72=ASCII 'H') into another character set if your implementation runs in a non-ASCII-compatible environment. If 0 is not an appropriate terminator in your character set, the program logic will need some adjustment as well.

15 17 -1 17 -1 -1 16 1 -1 16 3 -1 15 15 0 0 -1 72 101 108 108 111 44 32 119 111 114 108 100 33 10 0

The above "machine code" corresponds to something like this in a hypothetical assembler language for a signed 8-bit version of the machine:

start:
    0f 11 ff subleq (zero), (message), -1
    11 ff ff subleq (message), -1, -1    ; output character at message
    10 01 ff subleq (neg1), (start+1), -1
    10 03 ff subleq (neg1), (start+3), -1
    0f 0f 00 subleq (zero), (zero), start
; useful constants
zero:
    00      .data 0
neg1:
    ff      .data -1
; the message to print
message: .data "Hello, world!\n\0"
    48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 0a 00

Solution:
// version 1.1.2

fun subleq(program: String) {
    val words = program.split(' ').map { it.toInt() }.toTypedArray()
    val sb = StringBuilder()
    var ip = 0
    while (true) {
        val a = words[ip]
        val b = words[ip + 1]
        var c = words[ip + 2]
        ip += 3
        if (a < 0) {
            print("Enter a character : ")
            words[b] = readLine()!![0].toInt()
        }
        else if (b < 0) {
            sb.append(words[a].toChar())
        }
        else {
            words[b] -= words[a]
            if (words[b] <= 0) ip = c
            if (ip < 0) break
        }
    }
    print(sb)
}

fun main(args: Array<String>) {
    val program = "15 17 -1 17 -1 -1 16 1 -1 16 3 -1 15 15 0 0 -1 72 101 108 108 111 44 32 119 111 114 108 100 33 10 0"
    subleq(program)
}


Substring/Top and tail

The task is to demonstrate how to remove the first and last characters from a string.

The solution should demonstrate how to obtain the following results:

* String with first character removed
* String with last character removed
* String with both the first and last characters removed

If the program uses UTF-8 or UTF-16, it must work on any valid Unicode code point, whether in the Basic Multilingual Plane or above it.

The program must reference logical characters (code points), not 8-bit code units for UTF-8 or 16-bit code units for UTF-16.

Programs for other encodings (such as 8-bit ASCII, or EUC-JP) are not required to handle all Unicode characters.

Solution:
// version 1.0.6
fun main(args: Array<String>) {
    val s = "Rosetta"
    println(s.drop(1))
    println(s.dropLast(1))
    println(s.drop(1).dropLast(1))
}


Sum and product puzzle

Solution:
// version 1.1.4-3

data class P(val x: Int, val y: Int, val sum: Int, val prod: Int)

fun main(args: Array<String>) {
    val candidates = mutableListOf<P>()
    for (x in 2..49) {
        for (y in x + 1..100 - x) {
            candidates.add(P(x, y, x + y, x * y))
        }
    }

    val sums = candidates.groupBy { it.sum }
    val prods = candidates.groupBy { it.prod }

    val fact1 = candidates.filter { sums[it.sum]!!.all { prods[it.prod]!!.size > 1 } }
    val fact2 = fact1.filter { prods[it.prod]!!.intersect(fact1).size == 1 }
    val fact3 = fact2.filter { sums[it.sum]!!.intersect(fact2).size == 1 }
    print("The only solution is : ")
    for ((x, y, _, _) in fact3) println("x = $x, y = $y")
}


Sum digits of an integer

Take a   Natural Number   in a given base and return the sum of its digits:
:*   '''1'''10                  sums to   '''1'''
:*   '''1234'''10       sums to   '''10'''
:*   '''fe'''16              sums to   '''29'''
:*   '''f0e'''16           sums to   '''29'''

Solution:
// version 1.1.0

const val digits = "0123456789abcdefghijklmnopqrstuvwxyz"

fun sumDigits(ns: String, base: Int): Int {
    val n = ns.toLowerCase().trim()
    if (base !in 2..36) throw IllegalArgumentException("Base must be between 2 and 36")
    if (n.isEmpty())    throw IllegalArgumentException("Number string can't be blank or empty")
    var sum = 0
    for (digit in n) {
        val index = digits.indexOf(digit)
        if (index == -1 || index >= base) throw IllegalArgumentException("Number string contains an invalid digit")
        sum += index
    }
    return sum
}

fun main(args: Array<String>) {
    val numbers = mapOf("1" to 10, "1234" to 10, "fe" to 16, "f0e" to 16, "1010" to 2, "777" to 8, "16xyz" to 36)
    println("The sum of digits is:")
    for ((number, base) in numbers) println("$number\tbase $base\t-> ${sumDigits(number, base)}")
}


Sum multiples of 3 and 5

The objective is to write a function that finds the sum of all positive multiples of 3 or 5 below ''n''.

Show output for ''n'' = 1000.

This is is the same as Project Euler problem 1.

'''Extra credit:''' do this efficiently for ''n'' = 1e20 or higher.

Solution:
// version 1.1.2

import java.math.BigInteger

val big2  = BigInteger.valueOf(2)
val big3  = BigInteger.valueOf(3)
val big5  = BigInteger.valueOf(5)
val big15 = big3 * big5

fun sum35(n: Int) = (3 until n).filter { it % 3 == 0 || it % 5 == 0}.sum()

fun sum35(n: BigInteger): BigInteger {
    val nn    = n - BigInteger.ONE
    val num3  = nn / big3
    val end3  = num3 * big3
    val sum3  = (big3 + end3) * num3 / big2
    val num5  = nn / big5
    val end5  = num5 * big5
    val sum5  = (big5 + end5) * num5 / big2
    val num15 = nn / big15
    val end15 = num15 * big15
    val sum15 = (big15 + end15) * num15 / big2
    return sum3 + sum5 - sum15
}

fun main(args: Array<String>) {
    println("The sum of multiples of 3 or 5 below 1000 is ${sum35(1000)}")
    val big100k = BigInteger.valueOf(100_000L)
    val e20 = big100k * big100k * big100k * big100k
    println("The sum of multiples of 3 or 5 below 1e20 is ${sum35(e20)}")
}


Sum to 100

Find solutions to the    ''sum to one hundred''    puzzle.

Add (insert) the mathematical
operators      '''+'''    or    '''-'''      (plus
or minus)   before any of the digits in the
decimal numeric string    '''123456789'''    such that the
resulting mathematical expression adds up to a
particular sum    (in this iconic case,   '''100''').

Example:
              123 + 4 - 5 + 67 - 89   =   100

Show all output here.

:*   Show all solutions that sum to    '''100'''
:*   Show the sum that has the maximum   ''number''   of solutions   (from zero to infinity++)
:*   Show the lowest positive sum that   ''can't''   be expressed   (has no solutions),   using the rules for this task
:*   Show the ten highest numbers that can be expressed using the rules for this task   (extra credit)

++   (where   ''infinity''   would be a relatively small   123,456,789)

An example of a sum that can't be expressed   (within the rules of this task)   is:   '''5074'''
(which,   of course,   isn't the lowest positive sum that can't be expressed).

Solution:
// version 1.1.51

class Expression {

    private enum class Op { ADD, SUB, JOIN }
    private val code = Array<Op>(NUMBER_OF_DIGITS) { Op.ADD }

    companion object {
        private const val NUMBER_OF_DIGITS = 9
        private const val THREE_POW_4 = 3 * 3 * 3 * 3
        private const val FMT = "%9d"
        const val NUMBER_OF_EXPRESSIONS = 2 * THREE_POW_4 * THREE_POW_4

        fun print(givenSum: Int) {
            var expression = Expression()
            repeat(Expression.NUMBER_OF_EXPRESSIONS) {
                if (expression.toInt() == givenSum) println("${FMT.format(givenSum)} = $expression")
                expression++
            }
        }
    }

    operator fun inc(): Expression {
        for (i in 0 until code.size) {
            code[i] = when (code[i]) {
                Op.ADD  -> Op.SUB
                Op.SUB  -> Op.JOIN
                Op.JOIN -> Op.ADD
            }
            if (code[i] != Op.ADD) break
        }
        return this
    }

    fun toInt(): Int {
        var value = 0
        var number = 0
        var sign = +1
        for (digit in 1..9) {
            when (code[NUMBER_OF_DIGITS - digit]) {
                Op.ADD  -> { value += sign * number; number = digit; sign = +1 }
                Op.SUB  -> { value += sign * number; number = digit; sign = -1 }
                Op.JOIN -> { number = 10 * number + digit }
            }
        }
        return value + sign * number
    }

    override fun toString(): String {
        val sb = StringBuilder()
        for (digit in 1..NUMBER_OF_DIGITS) {
            when (code[NUMBER_OF_DIGITS - digit]) {
                Op.ADD  -> if (digit > 1) sb.append(" + ")
                Op.SUB  -> sb.append(" - ")
                Op.JOIN -> {}
            }
            sb.append(digit)
        }
        return sb.toString().trimStart()
    }
}

class Stat {

    val countSum = mutableMapOf<Int, Int>()
    val sumCount = mutableMapOf<Int, MutableSet<Int>>()

    init {
        var expression = Expression()
        repeat (Expression.NUMBER_OF_EXPRESSIONS) {
            val sum = expression.toInt()
            countSum.put(sum, 1 + (countSum[sum] ?: 0))
            expression++
        }
        for ((k, v) in countSum) {
            val set = if (sumCount.containsKey(v))
                sumCount[v]!!
            else
                mutableSetOf<Int>()
            set.add(k)
            sumCount.put(v, set)
        }
    }
}

fun main(args: Array<String>) {
    println("100 has the following solutions:\n")
    Expression.print(100)

    val stat = Stat()
    val maxCount = stat.sumCount.keys.max()
    val maxSum = stat.sumCount[maxCount]!!.max()
    println("\n$maxSum has the maximum number of solutions, namely $maxCount")

    var value = 0
    while (stat.countSum.containsKey(value)) value++
    println("\n$value is the lowest positive number with no solutions")

    println("\nThe ten highest numbers that do have solutions are:\n")
    stat.countSum.keys.toIntArray().sorted().reversed().take(10).forEach { Expression.print(it) }
}


Summarize and say sequence

There are several ways to generate a self-referential sequence. One very common one (the [[Look-and-say sequence]]) is to start with a positive integer, then generate the next term by concatenating enumerated groups of adjacent alike digits:
        0, 10, 1110, 3110, 132110, 1113122110, 311311222110 ...
The terms generated grow in length geometrically and never converge.

Another way to generate a self-referential sequence is to summarize the previous term.

Count how many of each alike digit there is, then concatenate the sum and digit for each of the sorted enumerated digits. Note that the first five terms are the same as for the previous sequence.
        0, 10, 1110, 3110, 132110, 13123110, 23124110 ...
Sort the digits largest to smallest. Do not include counts of digits that do not appear in the previous term.

Depending on the seed value, series generated this way always either converge to a stable value or to a short cyclical pattern. (For our purposes, I'll use converge to mean an element matches a previously seen element.) The sequence shown, with a seed value of 0, converges to a stable value of 1433223110 after 11 iterations. The seed value that converges most quickly is 22. It goes stable after the first element. (The next element is 22, which has been seen before.)

;Task:
Find all the positive integer seed values under 1000000, for the above convergent self-referential sequence, that takes the largest number of iterations before converging. Then print out the number of iterations and the sequence they return. Note that different permutations of the digits of the seed will yield the same sequence. For this task, assume leading zeros are not permitted.

Seed Value(s): 9009 9090 9900

Iterations: 21

Sequence: (same for all three seeds except for first element)
9009
2920
192210
19222110
19323110
1923123110
1923224110
191413323110
191433125110
19151423125110
19251413226110
1916151413325110
1916251423127110
191716151413326110
191726151423128110
19181716151413327110
19182716151423129110
29181716151413328110
19281716151423228110
19281716151413427110
19182716152413228110

;Related tasks:
*   [[Fours is the number of letters in the ...]]
*   [[Look-and-say sequence]]
*   [[Number names]]
*   [[Self-describing numbers]]
*   [[Spelling of ordinal numbers]]

;Also see:
*   The On-Line Encyclopedia of Integer Sequences.

Solution:
// version 1.1.2

const val LIMIT = 1_000_000

val sb = StringBuilder()

fun selfRefSeq(s: String): String {
    sb.setLength(0)  // faster than using a local StringBuilder object
    for (d in '9' downTo '0') {
        if (d !in s) continue
        val count = s.count { it == d }
        sb.append("$count$d")
    }
    return sb.toString()
}

fun permute(input: List<Char>): List<List<Char>> {
    if (input.size == 1) return listOf(input)
    val perms = mutableListOf<List<Char>>()
    val toInsert = input[0]
    for (perm in permute(input.drop(1))) {
        for (i in 0..perm.size) {
            val newPerm = perm.toMutableList()
            newPerm.add(i, toInsert)
            perms.add(newPerm)
        }
    }
    return perms
}

fun main(args: Array<String>) {
    val sieve = IntArray(LIMIT) // all zero by default
    val elements = mutableListOf<String>()
    for (n in 1 until LIMIT) {
        if (sieve[n] > 0) continue
        elements.clear()
        var next = n.toString()
        elements.add(next)
        while (true) {
            next = selfRefSeq(next)
            if (next in elements) {
                val size = elements.size
                sieve[n] = size
                if (n > 9) {
                    val perms = permute(n.toString().toList()).distinct()
                    for (perm in perms) {
                        if (perm[0] == '0') continue
                        val k = perm.joinToString("").toInt()
                        sieve[k] = size
                    }
                }
                break
            }
            elements.add(next)
        }
    }
    val maxIterations = sieve.max()!!
    for (n in 1 until LIMIT) {
        if (sieve[n] < maxIterations) continue
        println("$n -> Iterations = $maxIterations")
        var next = n.toString()
        for (i in 1..maxIterations) {
            println(next)
            next = selfRefSeq(next)
        }
        println()
    }
}


Super-d numbers

A super-d number is a positive, decimal (base ten) integer   '''n'''   such that   '''d x nd'''   has at least   '''d'''   consecutive digits   '''d'''   where
    2 <= d <= 9
For instance, 753 is a super-3 number because 3 x 7533 = 1280873331.

'''Super-d'''   numbers are also shown on   '''MathWorld'''(tm)   as   '''super-''d'' '''   or   '''super-''d'''''.

;Task:
:* Write a function/procedure/routine to find super-d numbers.
:* For   '''d=2'''   through   '''d=6''',   use the routine to show the first   '''10'''   super-d numbers.

;Extra credit:
:* Show the first   '''10'''   super-7, super-8, and/or super-9 numbers   (optional).

;See also:
:*   Wolfram MathWorld - Super-d Number.
:*   OEIS: A014569 - Super-3 Numbers.

Solution:
import java.math.BigInteger

fun superD(d: Int, max: Int) {
    val start = System.currentTimeMillis()
    var test = ""
    for (i in 0 until d) {
        test += d
    }

    var n = 0
    var i = 0
    println("First $max super-$d numbers:")
    while (n < max) {
        i++
        val value: Any = BigInteger.valueOf(d.toLong()) * BigInteger.valueOf(i.toLong()).pow(d)
        if (value.toString().contains(test)) {
            n++
            print("$i ")
        }
    }
    val end = System.currentTimeMillis()
    println("\nRun time ${end - start} ms\n")
}

fun main() {
    for (i in 2..9) {
        superD(i, 10)
    }
}


Superellipse

A superellipse is a geometric figure defined as the set of all points (x, y) with

::: \left|\frac{x}{a}\right|^n\! + \left|\frac{y}{b}\right|^n\! = 1,

where ''n'', ''a'', and ''b'' are positive numbers.

;Task
Draw a superellipse with n = 2.5, and a = b = 200

Solution:
// version 1.1.2

import java.awt.*
import java.awt.geom.Path2D
import javax.swing.*
import java.lang.Math.pow

/* assumes a == b */
class SuperEllipse(val n: Double, val a: Int) : JPanel() {
    init {
        require(n > 0.0 && a > 0)
        preferredSize = Dimension(650, 650)
        background = Color.black
    }

    private fun drawEllipse(g: Graphics2D) {
        val points = DoubleArray(a + 1)
        val p = Path2D.Double()
        p.moveTo(a.toDouble(), 0.0)

        // calculate first quadrant
        for (x in a downTo 0) {
            points[x] = pow(pow(a.toDouble(), n) - pow(x.toDouble(), n), 1.0 / n)
            p.lineTo(x.toDouble(), -points[x])
        }

        // mirror to others
        for (x in 0..a) p.lineTo(x.toDouble(), points[x])
        for (x in a downTo 0) p.lineTo(-x.toDouble(), points[x])
        for (x in 0..a) p.lineTo(-x.toDouble(), -points[x])

        with(g) {
            translate(width / 2, height / 2)
            color = Color.yellow
            fill(p)
        }
    }

    override fun paintComponent(gg: Graphics) {
        super.paintComponent(gg)
        val g = gg as Graphics2D
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                           RenderingHints.VALUE_ANTIALIAS_ON)
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                           RenderingHints.VALUE_TEXT_ANTIALIAS_ON)
        drawEllipse(g)
    }
}

fun main(args: Array<String>) {
    SwingUtilities.invokeLater {
        val f = JFrame()
        with (f) {
            defaultCloseOperation = JFrame.EXIT_ON_CLOSE
            title = "Super Ellipse"
            isResizable = false
            add(SuperEllipse(2.5, 200), BorderLayout.CENTER)
            pack()
            setLocationRelativeTo(null)
            isVisible = true
        }
    }
}


Superpermutation minimisation

A superpermutation of N different characters is a string consisting of an arrangement of multiple copies of those N different characters in which every permutation of those characters can be found as a substring.

For example, representing the characters as A..Z, using N=2 we choose to use the first two characters 'AB'.
The permutations of 'AB' are the two, (i.e. two-factorial), strings: 'AB' and 'BA'.

A too obvious method of generating a superpermutation is to just join all the permutations together forming 'ABBA'.

A little thought will produce the shorter (in fact the shortest) superpermutation of 'ABA' - it contains 'AB' at the beginning and contains 'BA' from the middle to the end.

The "too obvious" method of creation generates a string of length N!*N. Using this as a yardstick, the task is to investigate other methods of generating superpermutations of N from 1-to-7 characters, that never generate larger superpermutations.

Show descriptions and comparisons of algorithms used here, and select the "Best" algorithm as being the one generating shorter superpermutations.

The problem of generating the shortest superpermutation for each N ''might'' be NP complete, although the minimal strings for small values of N have been found by brute -force searches.

;Reference:
* The Minimal Superpermutation Problem. by Nathaniel Johnston.
* oeis A180632 gives 0-5 as 0, 1, 3, 9, 33, 153. 6 is thought to be 872.
* Superpermutations - Numberphile. A video
* Superpermutations: the maths problem solved by 4chan - Standupmaths. A video of recent (2018) mathematical progress.
* New Superpermutations Discovered! Standupmaths & Numberphile.

Solution:
// version 1.1.2

const val MAX = 12

var sp = CharArray(0)
val count = IntArray(MAX)
var pos = 0

fun factSum(n: Int): Int {
    var s = 0
    var x = 0
    var f = 1
    while (x < n) {
        f *= ++x
        s += f
    }
    return s
}

fun r(n: Int): Boolean {
    if (n == 0) return false
    val c = sp[pos - n]
    if (--count[n] == 0) {
        count[n] = n
        if (!r(n - 1)) return false
    }
    sp[pos++] = c
    return true
}

fun superPerm(n: Int) {
    pos = n
    val len = factSum(n)
    if (len > 0) sp = CharArray(len)
    for (i in 0..n) count[i] = i
    for (i in 1..n) sp[i - 1] = '0' + i
    while (r(n)) {}
}

fun main(args: Array<String>) {
    for (n in 0 until MAX) {
        superPerm(n)
        println("superPerm(${"%2d".format(n)}) len = ${sp.size}")
    }
}


Tarjan

{{wikipedia|Graph}}

Tarjan's algorithm is an algorithm in graph theory for finding the strongly connected components of a graph.

It runs in linear time, matching the time bound for alternative methods including Kosaraju's algorithm and the path-based strong component algorithm.

Tarjan's Algorithm is named for its discoverer, Robert Tarjan.

;References:
* The article on Wikipedia.

See also: [[Kosaraju]]

Solution:
// version 1.1.3

import java.util.Stack

typealias Nodes = List<Node>

class Node(val n: Int) {
    var index   = -1  // -1 signifies undefined
    var lowLink = -1
    var onStack = false

    override fun toString()  = n.toString()
}

class DirectedGraph(val vs: Nodes, val es: Map<Node, Nodes>)

fun tarjan(g: DirectedGraph): List<Nodes> {
    val sccs = mutableListOf<Nodes>()
    var index = 0
    val s = Stack<Node>()

    fun strongConnect(v: Node) {
        // Set the depth index for v to the smallest unused index
        v.index = index
        v.lowLink = index
        index++
        s.push(v)
        v.onStack = true

        // consider successors of v
        for (w in g.es[v]!!) {
            if (w.index < 0) {
                // Successor w has not yet been visited; recurse on it
                strongConnect(w)
                v.lowLink = minOf(v.lowLink, w.lowLink)
            }
            else if (w.onStack) {
                // Successor w is in stack s and hence in the current SCC
                v.lowLink = minOf(v.lowLink, w.index)
            }
        }

        // If v is a root node, pop the stack and generate an SCC
        if (v.lowLink == v.index) {
            val scc = mutableListOf<Node>()
            do {
                val w = s.pop()
                w.onStack = false
                scc.add(w)
            }
            while (w != v)
            sccs.add(scc)
        }
    }

    for (v in g.vs) if (v.index < 0) strongConnect(v)
    return sccs
}

fun main(args: Array<String>) {
    val vs = (0..7).map { Node(it) }
    val es = mapOf(
        vs[0] to listOf(vs[1]),
        vs[2] to listOf(vs[0]),
        vs[5] to listOf(vs[2], vs[6]),
        vs[6] to listOf(vs[5]),
        vs[1] to listOf(vs[2]),
        vs[3] to listOf(vs[1], vs[2], vs[4]),
        vs[4] to listOf(vs[5], vs[3]),
        vs[7] to listOf(vs[4], vs[7], vs[6])
    )
    val g = DirectedGraph(vs, es)
    val sccs = tarjan(g)
    println(sccs.joinToString("\n"))
}


Temperature conversion

There are quite a number of temperature scales. For this task we will concentrate on four of the perhaps best-known ones:
Rankine.

The Celsius and Kelvin scales have the same magnitude, but different null points.

: 0 degrees Celsius corresponds to 273.15 kelvin.
: 0 kelvin is absolute zero.

The Fahrenheit and Rankine scales also have the same magnitude, but different null points.

: 0 degrees Fahrenheit corresponds to 459.67 degrees Rankine.
: 0 degrees Rankine is absolute zero.

The Celsius/Kelvin and Fahrenheit/Rankine scales have a ratio of 5 : 9.

;Task
Write code that accepts a value of kelvin, converts it to values of the three other scales, and prints the result.

;Example:

K  21.00

C  -252.15

F  -421.87

R  37.80

Solution:
// version 1.1.2

class Kelvin(val degrees: Double) {
    fun toCelsius() = degrees - 273.15

    fun toFahreneit() = (degrees - 273.15) * 1.8 + 32.0

    fun toRankine() = (degrees - 273.15) * 1.8 + 32.0 + 459.67
}

fun main(args: Array<String>) {
    print("Enter the temperature in degrees Kelvin : ")
    val degrees = readLine()!!.toDouble()
    val k = Kelvin(degrees)
    val f = "% 1.2f"
    println()
    println("K  ${f.format(k.degrees)}\n")
    println("C  ${f.format(k.toCelsius())}\n")
    println("F  ${f.format(k.toFahreneit())}\n")
    println("R  ${f.format(k.toRankine())}")
}


Test integerness

{| class="wikitable"
|-
! colspan=2 | Input
! colspan=2 | Output
! rowspan=2 | Comment
|-
! Type
! Value
! exact
! tolerance = 0.00001
|-
| rowspan=3 | decimal
| 25.000000
| colspan=2 | true
|
|-
| 24.999999
| false
| true
|
|-
| 25.000100
| colspan=2 | false
|
|-
| rowspan=4 | floating-point
| -2.1e120
| colspan=2 | true
| This one is tricky, because in most languages it is too large to fit into a native integer type.It is, nonetheless, mathematically an integer, and your code should identify it as such.
|-
| -5e-2
| colspan=2 | false
|
|-
| NaN
| colspan=2 | false
|
|-
| Inf
| colspan=2 | false
| This one is debatable. If your code considers it an integer, that's okay too.
|-
| rowspan=2 | complex
| 5.0+0.0i
| colspan=2 | true
|
|-
| 5-5i
| colspan=2 | false
|
|}

(The types and notations shown in these tables are merely examples - you should use the native data types and number literals of your programming language and standard library. Use a different set of test-cases, if this one doesn't demonstrate all relevant behavior.)

Solution:
// version 1.1.2

import java.math.BigInteger
import java.math.BigDecimal

fun Double.isLong(tolerance: Double = 0.0) =
    (this - Math.floor(this)) <= tolerance || (Math.ceil(this) - this) <= tolerance

fun BigDecimal.isBigInteger() =
    try {
        this.toBigIntegerExact()
        true
    }
    catch (ex: ArithmeticException) {
        false
    }

class Rational(val num: Long, val denom: Long) {
    fun isLong() = num % denom == 0L

    override fun toString() = "$num/$denom"
}

class Complex(val real: Double, val imag: Double) {
    fun isLong() = real.isLong() && imag == 0.0

    override fun toString() =
        if (imag >= 0.0)
            "$real + ${imag}i"
        else
            "$real - ${-imag}i"
}

fun main(args: Array<String>) {
    val da = doubleArrayOf(25.000000, 24.999999, 25.000100)
    for (d in da) {
        val exact = d.isLong()
        println("${"%.6f".format(d)} is ${if (exact) "an" else "not an"} integer")
    }
    val tolerance = 0.00001
    println("\nWith a tolerance of ${"%.5f".format(tolerance)}:")
    for (d in da) {
        val fuzzy = d.isLong(tolerance)
        println("${"%.6f".format(d)} is ${if (fuzzy) "an" else "not an"} integer")
    }

    println()
    val fa = doubleArrayOf(-2.1e120, -5e-2, Double.NaN, Double.POSITIVE_INFINITY)
    for (f in fa) {
        val exact = if (f.isNaN() || f.isInfinite()) false
                    else BigDecimal(f.toString()).isBigInteger()
        println("$f is ${if (exact) "an" else "not an"} integer")
    }

    println()
    val ca = arrayOf(Complex(5.0, 0.0), Complex(5.0, -5.0))
    for (c in ca) {
        val exact = c.isLong()
        println("$c is ${if (exact) "an" else "not an"} integer")
    }

    println()
    val ra = arrayOf(Rational(24, 8), Rational(-5, 1), Rational(17, 2))
    for (r in ra) {
        val exact = r.isLong()
        println("$r is ${if (exact) "an" else "not an"} integer")
    }
}


Textonyms

When entering text on a phone's digital pad it is possible that a particular combination of digits corresponds to more than one word. Such are called textonyms.

Assuming the digit keys are mapped to letters as follows:
     2 -> ABC
     3 -> DEF
     4 -> GHI
     5 -> JKL
     6 -> MNO
     7 -> PQRS
     8 -> TUV
     9 -> WXYZ

;Task:
Write a program that finds textonyms in a list of words such as
[[Textonyms/wordlist]]   or
unixdict.txt.

The task should produce a report:

 There are #{0} words in #{1} which can be represented by the digit key mapping.
 They require #{2} digit combinations to represent them.
 #{3} digit combinations represent Textonyms.

Where:
 #{0} is the number of words in the list which can be represented by the digit key mapping.
 #{1} is the URL of the wordlist being used.
 #{2} is the number of digit combinations required to represent the words in #{0}.
 #{3} is the number of #{2} which represent more than one word.

At your discretion show a couple of examples of your solution displaying Textonyms.

E.G.:

  2748424767 -> "Briticisms", "criticisms"

;Extra credit:
Use a word list and keypad mapping other than English.

Solution:
// version 1.1.4-3

import java.io.File

val wordList = "unixdict.txt"
val url = "http://www.puzzlers.org/pub/wordlists/unixdict.txt"

const val DIGITS = "22233344455566677778889999"

val map = mutableMapOf<String, MutableList<String>>()

fun processList() {
    var countValid = 0
    val f = File(wordList)
    val sb = StringBuilder()

    f.forEachLine { word->
        var valid = true
        sb.setLength(0)
        for (c in word.toLowerCase()) {
            if (c !in 'a'..'z') {
                valid = false
                break
            }
            sb.append(DIGITS[c - 'a'])
        }
        if (valid) {
            countValid++
            val key = sb.toString()
            if (map.containsKey(key)) {
                map[key]!!.add(word)
            }
            else {
                map.put(key, mutableListOf(word))
            }
        }
    }
    var textonyms = map.filter { it.value.size > 1 }.toList()
    val report = "There are $countValid words in '$url' " +
                 "which can be represented by the digit key mapping.\n" +
                 "They require ${map.size} digit combinations to represent them.\n" +
                 "${textonyms.size} digit combinations represent Textonyms.\n"
    println(report)

    val longest = textonyms.sortedByDescending { it.first.length }
    val ambiguous = longest.sortedByDescending { it.second.size }

    println("Top 8 in ambiguity:\n")
    println("Count   Textonym  Words")
    println("======  ========  =====")
    var fmt = "%4d    %-8s  %s"
    for (a in ambiguous.take(8)) println(fmt.format(a.second.size, a.first, a.second))

    fmt = fmt.replace("8", "14")
    println("\nTop 6 in length:\n")
    println("Length  Textonym        Words")
    println("======  ==============  =====")
    for (l in longest.take(6)) println(fmt.format(l.first.length, l.first, l.second))
}

fun main(args: Array<String>) {
    processList()
}


The Name Game

Write a program that accepts a name as input and outputs the lyrics to the Shirley Ellis song "The Name Game".

The regular verse

Unless your name begins with a vowel (A, E, I, O, U), 'B', 'F' or 'M' you don't have to care about special rules.
The verse for the name 'Gary' would be like this:

    Gary, Gary, bo-bary
    Banana-fana fo-fary
    Fee-fi-mo-mary
    Gary!

At the end of every line, the name gets repeated without the first letter: Gary becomes ary
If we take (X) as the full name (Gary) and (Y) as the name without the first letter (ary) the verse would look like this:

    (X), (X), bo-b(Y)
    Banana-fana fo-f(Y)
    Fee-fi-mo-m(Y)
    (X)!

Vowel as first letter of the name

If you have a vowel as the first letter of your name (e.g. Earl) you do not truncate the name.
The verse looks like this:

    Earl, Earl, bo-bearl
    Banana-fana fo-fearl
    Fee-fi-mo-mearl
    Earl!

'B', 'F' or 'M' as first letter of the name

In case of a 'B', an 'F' or an 'M' (e.g. Billy, Felix, Mary) there is a special rule.
The line which would 'rebuild' the name (e.g. bo-billy) is sung without the first letter of the name.
The verse for the name Billy looks like this:

    Billy, Billy, bo-illy
    Banana-fana fo-filly
    Fee-fi-mo-milly
    Billy!

For the name 'Felix', this would be right:

    Felix, Felix, bo-belix
    Banana-fana fo-elix
    Fee-fi-mo-melix
    Felix!

Solution:
// version 1.2.31

fun printVerse(name: String) {
    val x = name.toLowerCase().capitalize()
    val y = if (x[0] in "AEIOU") x.toLowerCase() else x.substring(1)
    var b = "b$y"
    var f = "f$y"
    var m = "m$y"
    when (x[0]) {
        'B'  -> b = "$y"
        'F'  -> f = "$y"
        'M'  -> m = "$y"
        else -> {} // no adjustment needed
    }
    println("$x, $x, bo-$b")
    println("Banana-fana fo-$f")
    println("Fee-fi-mo-$m")
    println("$x!\n")
}

fun main(args: Array<String>) {
    listOf("Gary", "Earl", "Billy", "Felix", "Mary", "Steve").forEach { printVerse(it) }
}


The Twelve Days of Christmas

Write a program that outputs the lyrics of the Christmas carol ''The Twelve Days of Christmas''.
The lyrics can be found here.

(You must reproduce the words in the correct order, but case, format, and punctuation are left to your discretion.)

Solution:
enum class Day {
    first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth;
    val header = "On the " + this + " day of Christmas, my true love sent to me\n\t"
}

fun main(x: Array<String>) {
    val gifts = listOf("A partridge in a pear tree",
                       "Two turtle doves and",
                       "Three french hens",
                       "Four calling birds",
                       "Five golden rings",
                       "Six geese a-laying",
                       "Seven swans a-swimming",
                       "Eight maids a-milking",
                       "Nine ladies dancing",
                       "Ten lords a-leaping",
                       "Eleven pipers piping",
                       "Twelve drummers drumming")

    Day.values().forEachIndexed { i, d -> println(d.header + gifts.slice(0..i).asReversed().joinToString("\n\t")) }
}


Thue-Morse

Create a Thue-Morse sequence.

;See also
*   YouTube entry: The Fairest Sharing Sequence Ever
*   YouTube entry: Math and OCD - My story with the Thue-Morse sequence
*   Task: [[Fairshare between two and more]]

Solution:
fun thueMorse(n: Int): String {
    val sb0 = StringBuilder("0")
    val sb1 = StringBuilder("1")
    repeat(n) {
        val tmp = sb0.toString()
        sb0.append(sb1)
        sb1.append(tmp)
    }
    return sb0.toString()
}

fun main() {
    for (i in 0..6) println("$i : ${thueMorse(i)}")
}


Tonelli-Shanks algorithm

{{wikipedia}}

In computational number theory, the Tonelli-Shanks algorithm is a technique for solving for '''x''' in a congruence of the form:

:: x2  n (mod p)

where '''n''' is an integer which is a quadratic residue (mod p), '''p''' is an odd prime, and '''x,n  Fp''' where Fp = {0, 1, ..., p - 1}.

It is used in cryptography techniques.

To apply the algorithm, we need the Legendre symbol:

The Legendre symbol '''(a | p)''' denotes the value of a(p-1)/2 (mod p).
* '''(a | p)  1'''    if '''a''' is a square (mod p)
* '''(a | p)  -1'''    if '''a''' is not a square (mod p)
* '''(a | p)  0'''    if '''a'''  0 (mod p)

;Algorithm pseudo-code:

All  are taken to mean (mod p) unless stated otherwise.

* Input: '''p''' an odd prime, and an integer '''n''' .
* Step 0: Check that '''n''' is indeed a square: (n | p) must be  1 .
* Step 1: By factoring out powers of 2 from p - 1, find '''q''' and '''s''' such that p - 1 = q2s with '''q''' odd .
** If p  3 (mod 4) (i.e. s = 1), output the two solutions r  +- n(p+1)/4 .
* Step 2: Select a non-square '''z''' such that (z | p)  -1 and set c   zq .
* Step 3: Set r  n(q+1)/2, t  nq, m = s .
* Step 4: Loop the following:
** If t  1, output '''r''' and '''p - r''' .
** Otherwise find, by repeated squaring, the lowest '''i''', 0 < i < m , such that t2i  1 .
** Let b  c2(m - i - 1), and set r  rb, t  tb2, c  b2 and m = i .

;Task:
Implement the above algorithm.

Find solutions (if any) for
* n = 10 p = 13
* n = 56 p = 101
* n = 1030 p = 10009
* n = 1032 p = 10009
* n = 44402 p = 100049

;Extra credit:
* n  =    665820697     p  =   1000000009
* n  =   881398088036     p   =  1000000000039
* n  =  41660815127637347468140745042827704103445750172002   p  = 10^50 + 577

;See also:
* [[Modular exponentiation]]
* [[Cipolla's algorithm]]

Solution:
// version 1.1.3

import java.math.BigInteger

data class Solution(val root1: BigInteger, val root2: BigInteger, val exists: Boolean)

val bigZero = BigInteger.ZERO
val bigOne  = BigInteger.ONE
val bigTwo  = BigInteger.valueOf(2L)
val bigFour = BigInteger.valueOf(4L)
val bigTen  = BigInteger.TEN

fun ts(n: Long, p: Long) = ts(BigInteger.valueOf(n), BigInteger.valueOf(p))

fun ts(n: BigInteger, p: BigInteger): Solution {

    fun powModP(a: BigInteger, e: BigInteger) = a.modPow(e, p)

    fun ls(a: BigInteger) = powModP(a, (p - bigOne) / bigTwo)

    if (ls(n) != bigOne) return Solution(bigZero, bigZero, false)
    var q = p - bigOne
    var ss = bigZero
    while (q.and(bigOne) == bigZero) {
        ss = ss + bigOne
        q = q.shiftRight(1)
    }

    if (ss == bigOne) {
        val r1 = powModP(n, (p + bigOne) / bigFour)
        return Solution(r1, p - r1, true)
    }

    var z = bigTwo
    while (ls(z) != p - bigOne) z = z + bigOne
    var c = powModP(z, q)
    var r = powModP(n, (q + bigOne) / bigTwo)
    var t = powModP(n, q)
    var m = ss

    while (true) {
        if (t == bigOne) return Solution(r, p - r, true)
        var i = bigZero
        var zz = t
        while (zz != bigOne && i < m - bigOne) {
            zz  = zz * zz % p
            i = i + bigOne
        }
        var b = c
        var e = m - i - bigOne
        while (e > bigZero) {
            b = b * b % p
            e = e - bigOne
        }
        r = r * b % p
        c = b * b % p
        t = t * c % p
        m = i
    }
}

fun main(args: Array<String>) {
    val pairs = listOf<Pair<Long, Long>>(
        10L to 13L,
        56L to 101L,
        1030L to 10009L,
        1032L to 10009L,
        44402L to 100049L,
        665820697L to 1000000009L,
        881398088036L to 1000000000039L
    )

    for (pair in pairs) {
        val (n, p) = pair
        val (root1, root2, exists) = ts(n, p)
        println("n = $n")
        println("p = $p")
        if (exists) {
            println("root1 = $root1")
            println("root2 = $root2")
        }
        else println("No solution exists")
        println()
    }

    val bn = BigInteger("41660815127637347468140745042827704103445750172002")
    val bp = bigTen.pow(50) + BigInteger.valueOf(577L)
    val (broot1, broot2, bexists) = ts(bn, bp)
    println("n = $bn")
    println("p = $bp")
    if (bexists) {
        println("root1 = $broot1")
        println("root2 = $broot2")
    }
    else println("No solution exists")
}


Top rank per group

Find the top   ''N''   salaries in each department,   where   ''N''   is provided as a parameter.

Use this data as a formatted internal data structure (adapt it to your language-native idioms, rather than parse at runtime), or identify your external data source:

Employee Name,Employee ID,Salary,Department
Tyler Bennett,E10297,32000,D101
John Rappl,E21437,47000,D050
George Woltman,E00127,53500,D101
Adam Smith,E63535,18000,D202
Claire Buckman,E39876,27800,D202
David McClellan,E04242,41500,D101
Rich Holcomb,E01234,49500,D202
Nathan Adams,E41298,21900,D050
Richard Potter,E43128,15900,D101
David Motsinger,E27002,19250,D202
Tim Sampair,E03033,27000,D101
Kim Arlich,E10001,57000,D190
Timothy Grove,E16398,29900,D190

Solution:
// version 1.1.2

data class Employee(val name: String, val id: String, val salary: Int, val dept: String)

const val N = 2 //say

fun main(args: Array<String>) {
    val employees = listOf(
        Employee("Tyler Bennett", "E10297", 32000, "D101"),
        Employee("John Rappl", "E21437", 47000, "D050"),
        Employee("George Woltman" , "E00127", 53500, "D101"),
        Employee("Adam Smith", "E63535", 18000, "D202"),
        Employee("Claire Buckman", "E39876", 27800, "D202"),
        Employee("David McClellan", "E04242", 41500, "D101"),
        Employee("Rich Holcomb", "E01234", 49500, "D202"),
        Employee("Nathan Adams", "E41298", 21900, "D050"),
        Employee("Richard Potter", "E43128", 15900, "D101"),
        Employee("David Motsinger", "E27002", 19250, "D202"),
        Employee("Tim Sampair", "E03033", 27000, "D101"),
        Employee("Kim Arlich", "E10001", 57000, "D190"),
        Employee("Timothy Grove", "E16398", 29900, "D190")
    )
    val employeesByDept = employees.sortedBy { it.dept }.groupBy { it.dept }
    println("Highest $N salaries by department:\n")
    for ((key, value) in employeesByDept) {
        val topRanked = value.sortedByDescending { it.salary }.take(N)
        println("Dept $key => ")
        for (i in 0 until N) with (topRanked[i]) { println("${name.padEnd(15)} $id $salary") }
        println()
    }
}


Topic variable

Several programming languages offer syntax shortcuts to deal with the notion of "current" or "topic" variable.

A topic variable is a special variable with a very short name which can also often be omitted.

Demonstrate the utilization and behaviour of the topic variable within the language and explain or demonstrate how the topic variable behaves under different levels of nesting or scope, if this applies, within the language.

For instance you can (but you don't have to) show how the topic variable can be used by assigning the number 3 to it and then computing its square and square root.

Solution:
// version 1.1.2

fun main(args: Array<String>) {
    3.let {
        println(it)
        println(it * it)
        println(Math.sqrt(it.toDouble()))
    }
}


Topswops

Topswops is a card game created by John Conway in the 1970's.

Assume you have a particular permutation of a set of   n   cards numbered   1..n   on both of their faces, for example the arrangement of four cards given by   [2, 4, 1, 3]   where the leftmost card is on top.

A round is composed of reversing the first   m   cards where   m   is the value of the topmost card.

Rounds are repeated until the topmost card is the number   1   and the number of swaps is recorded.

For our example the swaps produce:

    [2, 4, 1, 3]    # Initial shuffle
    [4, 2, 1, 3]
    [3, 1, 2, 4]
    [2, 1, 3, 4]
    [1, 2, 3, 4]

For a total of four swaps from the initial ordering to produce the terminating case where   1   is on top.

For a particular number    n    of cards,    topswops(n)    is the maximum swaps needed for any starting permutation of the   n   cards.

;Task:
The task is to generate and show here a table of    n    vs    topswops(n)    for    n    in the range   1..10   inclusive.

;Note:
Topswops   is also known as   Fannkuch   from the German word   ''Pfannkuchen''    meaning   pancake.

;Related tasks:
*   [[Number reversal game]]
*   [[Sorting algorithms/Pancake sort]]

Solution:
// version 1.1.2

val best = IntArray(32)

fun trySwaps(deck: IntArray, f: Int, d: Int, n: Int) {
    if (d > best[n]) best[n] = d
    for (i in n - 1 downTo 0) {
        if (deck[i] == -1 || deck[i] == i) break
        if (d + best[i] <= best[n]) return
    }
    val deck2 = deck.copyOf()
    for (i in 1 until n) {
        val k = 1 shl i
        if (deck2[i] == -1) {
            if ((f and k) != 0) continue
        }
        else if (deck2[i] != i) continue
        deck2[0] = i
        for (j in i - 1 downTo 0) deck2[i - j] = deck[j]
        trySwaps(deck2, f or k, d + 1, n)
    }
}

fun topswops(n: Int): Int {
    require(n > 0 && n < best.size)
    best[n] = 0
    val deck0 = IntArray(n + 1)
    for (i in 1 until n) deck0[i] = -1
    trySwaps(deck0, 1, 0, n)
    return best[n]
}

fun main(args: Array<String>) {
    for (i in 1..10) println("${"%2d".format(i)} : ${topswops(i)}")
}


Total circles area

Solution:
// version 1.1.2

class Point(val x: Double, val y: Double)

class Circle(val x: Double, val y: Double, val r: Double)

val circles = arrayOf(
    Circle( 1.6417233788,  1.6121789534, 0.0848270516),
    Circle(-1.4944608174,  1.2077959613, 1.1039549836),
    Circle( 0.6110294452, -0.6907087527, 0.9089162485),
    Circle( 0.3844862411,  0.2923344616, 0.2375743054),
    Circle(-0.2495892950, -0.3832854473, 1.0845181219),
    Circle( 1.7813504266,  1.6178237031, 0.8162655711),
    Circle(-0.1985249206, -0.8343333301, 0.0538864941),
    Circle(-1.7011985145, -0.1263820964, 0.4776976918),
    Circle(-0.4319462812,  1.4104420482, 0.7886291537),
    Circle( 0.2178372997, -0.9499557344, 0.0357871187),
    Circle(-0.6294854565, -1.3078893852, 0.7653357688),
    Circle( 1.7952608455,  0.6281269104, 0.2727652452),
    Circle( 1.4168575317,  1.0683357171, 1.1016025378),
    Circle( 1.4637371396,  0.9463877418, 1.1846214562),
    Circle(-0.5263668798,  1.7315156631, 1.4428514068),
    Circle(-1.2197352481,  0.9144146579, 1.0727263474),
    Circle(-0.1389358881,  0.1092805780, 0.7350208828),
    Circle( 1.5293954595,  0.0030278255, 1.2472867347),
    Circle(-0.5258728625,  1.3782633069, 1.3495508831),
    Circle(-0.1403562064,  0.2437382535, 1.3804956588),
    Circle( 0.8055826339, -0.0482092025, 0.3327165165),
    Circle(-0.6311979224,  0.7184578971, 0.2491045282),
    Circle( 1.4685857879, -0.8347049536, 1.3670667538),
    Circle(-0.6855727502,  1.6465021616, 1.0593087096),
    Circle( 0.0152957411,  0.0638919221, 0.9771215985)
)

fun Double.sq() = this * this

fun areaScan(precision: Double): Double {
    fun sect(c: Circle, y: Double): Point {
        val dr = Math.sqrt(c.r.sq() - (y - c.y).sq())
        return Point(c.x - dr, c.x + dr)
    }

    val ys = circles.map { it.y + it.r } + circles.map { it.y - it.r }
    val mins = Math.floor(ys.min()!! / precision).toInt()
    val maxs = Math.ceil(ys.max()!! / precision).toInt()
    var total = 0.0
    for (x in mins..maxs) {
        val y = x * precision
        var right = Double.NEGATIVE_INFINITY
        val points = circles.filter { Math.abs(y - it.y) < it.r }
                            .map { sect(it, y) }
                            .sortedBy { it.x }
        for (p in points) {
            if (p.y <= right) continue
            total += p.y - maxOf(p.x, right)
            right = p.y
        }
    }
    return total * precision
}

fun main(args: Array<String>) {
    val p = 1e-6
    println("Approximate area = ${areaScan(p)}")
}


Trabb Pardo–Knuth algorithm

The TPK algorithm is an early example of a programming chrestomathy.
It was used in Donald Knuth and Luis Trabb Pardo's Stanford tech report The Early Development of Programming Languages.
The report traces the early history of work in developing computer languages in the 1940s and 1950s, giving several translations of the algorithm.

From the wikipedia entry:

 '''ask''' for 11 numbers to be read into a sequence ''S''
 '''reverse''' sequence ''S''
 '''for each''' ''item'' '''in''' sequence ''S''
     ''result'' ''':=''' '''call''' a function to do an ''operation''
     '''if''' ''result'' overflows
         '''alert''' user
     '''else'''
         '''print''' ''result''

The task is to implement the algorithm:
# Use the function:     f(x) = |x|^{0.5} + 5x^3
# The overflow condition is an answer of greater than 400.
# The 'user alert' should not stop processing of other items of the sequence.
# Print a prompt before accepting '''eleven''', textual, numeric inputs.
# You may optionally print the item as well as its associated result, but the results must be in reverse order of input.
# The sequence   ''' ''S'' '''   may be 'implied' and so not shown explicitly.
# ''Print and show the program in action from a typical run here''. (If the output is graphical rather than text then either add a screendump or describe textually what is displayed).

Solution:
// version 1.1.2

fun f(x: Double) = Math.sqrt(Math.abs(x)) + 5.0 * x * x * x

fun main(args: Array<String>) {
    val da = DoubleArray(11)
    println("Please enter 11 numbers:")
    var i = 0
    while (i < 11) {
        print("  ${"%2d".format(i + 1)}: ")
        val d = readLine()!!.toDoubleOrNull()
        if (d == null)
            println("Not a valid number, try again")
        else
            da[i++] = d
    }
    println("\nThe sequence you just entered in reverse is:")
    da.reverse()
    println(da.contentToString())
    println("\nProcessing this sequence...")
    for (j in 0..10) {
        val v = f(da[j])
        print("  ${"%2d".format(j + 1)}: ")
        if (v > 400.0)
            println("Overflow!")
        else
            println(v)
    }
}


Truncate a file

Truncate a file to a specific length.   This should be implemented as a routine that takes two parameters: the filename and the required file length (in bytes).

Truncation can be achieved using system or library calls intended for such a task, if such methods exist, or by creating a temporary file of a reduced size and renaming it, after first deleting the original file, if no other method is available.   The file may contain non human readable binary data in an unspecified format, so the routine should be "binary safe", leaving the contents of the untruncated part of the file unchanged.

If the specified filename does not exist, or the provided length is not less than the current file length, then the routine should raise an appropriate error condition.

On some systems, the provided file truncation facilities might not change the file or may extend the file, if the specified length is greater than the current length of the file.

This task permits the use of such facilities.   However, such behaviour should be noted, or optionally a warning message relating to an non change or increase in file size may be implemented.

Solution:
// version 1.1.2

import java.io.FileOutputStream
import java.nio.channels.FileChannel

fun truncateFile(fileName: String, newSize: Long) {
    var fc: FileChannel? = null
    try {
        fc = FileOutputStream(fileName, true).channel
        if (newSize >= fc.size())
            println("Requested file size isn't less than existing size")
        else
            fc.truncate(newSize)
    }
    catch (ex: Exception) {
        println(ex.message)
    }
    finally {
        fc!!.close()
    }
}

fun main(args: Array<String>) {
    truncateFile("test.txt", 10)
}


Truth table

A truth table is a display of the inputs to, and the output of a Boolean function organized as a table where each row gives one combination of input values and the corresponding value of the function.

;Task:
# Input a Boolean function from the user as a string then calculate and print a formatted truth table for the given function. (One can assume that the user input is correct).
# Print and show output for Boolean functions of two and three input variables, but any program should not be limited to that many variables in the function.
# Either reverse-polish or infix notation expressions are allowed.

;Related tasks:
*   [[Boolean values]]
*   [[Ternary logic]]

;See also:
*   Wolfram MathWorld entry on truth tables.
*   some "truth table" examples from Google.

Solution:
// Version 1.2.31

import java.util.Stack

class Variable(val name: Char, var value: Boolean = false)

lateinit var expr: String
var variables = mutableListOf<Variable>()

fun Char.isOperator() = this in "&|!^"

fun Char.isVariable() = this in variables.map { it.name }

fun evalExpression(): Boolean {
    val stack = Stack<Boolean>()

    for (e in expr) {
        stack.push(
            if (e == 'T')
                true
            else if (e == 'F')
                false
            else if (e.isVariable())
                variables.single { it.name == e }.value
            else when (e) {
                '&'   -> stack.pop() and stack.pop()
                '|'   -> stack.pop() or  stack.pop()
                '!'   -> !stack.pop()
                '^'   -> stack.pop() xor stack.pop()
                else  -> throw RuntimeException("Non-conformant character '$e' in expression")
            }
        )
    }

    require(stack.size == 1)
    return stack.peek()
}

fun setVariables(pos: Int) {
    require(pos <= variables.size)
    if (pos == variables.size) {
        val vs = variables.map { if (it.value) "T" else "F" }.joinToString("  ")
        val es = if (evalExpression()) "T" else "F"
        return println("$vs  $es")
    }
    variables[pos].value = false
    setVariables(pos + 1)
    variables[pos].value = true
    setVariables(pos + 1)
}

fun main(args: Array<String>) {
    println("Accepts single-character variables (except for 'T' and 'F',")
    println("which specify explicit true or false values), postfix, with")
    println("&|!^ for and, or, not, xor, respectively; optionally")
    println("seperated by spaces or tabs. Just enter nothing to quit.")

    while (true) {
        print("\nBoolean expression: ")
        expr = readLine()!!.toUpperCase().replace(" ", "").replace("\t", "")
        if (expr == "") return
        variables.clear()
        for (e in expr) {
            if (!e.isOperator() && e !in "TF" && !e.isVariable()) variables.add(Variable(e))
        }
        if (variables.isEmpty()) return
        val vs = variables.map { it.name }.joinToString("  ")
        println("\n$vs  $expr")
        val h = vs.length + expr.length + 2
        repeat(h) { print("=") }
        println("\n")
        setVariables(0)
    }
}


Two bullet roulette

The following is supposedly a question given to mathematics graduates seeking jobs on Wall Street:

  A revolver handgun has a revolving cylinder with six chambers for bullets.

  It is loaded with the following procedure:

      1. Check the first chamber to the right of the trigger for a bullet.  If a bullet
         is seen, the cylinder is rotated one chamber clockwise and the next chamber
         checked until an empty chamber is found.

      2. A cartridge containing a bullet is placed in the empty chamber.

      3. The cylinder is then rotated one chamber clockwise.

  To randomize the cylinder's position, the cylinder is spun, which causes the cylinder to take
  a random position from 1 to 6 chamber rotations clockwise from its starting position.

  When the trigger is pulled the gun will fire if there is a bullet in position 0, which is just
  counterclockwise from the loading position.

  The gun is unloaded by removing all cartridges from the cylinder.

  According to the legend, a suicidal Russian imperial military officer plays a game of Russian
  roulette by putting two bullets in a six-chamber cylinder and pulls the trigger twice.
  If the gun fires with a trigger pull, this is considered a successful suicide.

  The cylinder is always spun before the first shot, but it may or may not be spun after putting
  in the first bullet and may or may not be spun after taking the first shot.

  Which of the following situations produces the highest probability of suicide?

    A. Spinning the cylinder after loading the first bullet, and spinning again after the first shot.

    B. Spinning the cylinder after loading the first bullet only.

    C. Spinning the cylinder after firing the first shot only.

    D. Not spinning the cylinder either after loading the first bullet or after the first shot.

    E. The probability is the same for all cases.

;Task:
# Run a repeated simulation of each of the above scenario, calculating the percentage of suicide with a randomization of the four spinning, loading and firing order scenarios.
# Show the results as a percentage of deaths for each type of scenario.
# The hand calculated probabilities are 5/9, 7/12, 5/9, and 1/2. A correct program should produce results close enough to those to allow a correct response to the interview question.

;Reference:
Youtube video on the Russian 1895 Nagant revolver [[https://www.youtube.com/watch?v=Dh1mojMaEtM]]

Solution:
import kotlin.random.Random

val cylinder = Array(6) { false }

fun rShift() {
    val t = cylinder[cylinder.size - 1]
    for (i in (0 until cylinder.size - 1).reversed()) {
        cylinder[i + 1] = cylinder[i]
    }
    cylinder[0] = t
}

fun unload() {
    for (i in cylinder.indices) {
        cylinder[i] = false
    }
}

fun load() {
    while (cylinder[0]) {
        rShift()
    }
    cylinder[0] = true
    rShift()
}

fun spin() {
    val lim = Random.nextInt(0, 6) + 1
    for (i in 1..lim) {
        rShift()
    }
}

fun fire(): Boolean {
    val shot = cylinder[0]
    rShift()
    return shot
}

fun method(s: String): Int {
    unload()
    for (c in s) {
        when (c) {
            'L' -> {
                load()
            }
            'S' -> {
                spin()
            }
            'F' -> {
                if (fire()) {
                    return 1
                }
            }
        }
    }
    return 0
}

fun mString(s: String): String {
    val buf = StringBuilder()
    fun append(txt: String) {
        if (buf.isNotEmpty()) {
            buf.append(", ")
        }
        buf.append(txt)
    }
    for (c in s) {
        when (c) {
            'L' -> {
                append("load")
            }
            'S' -> {
                append("spin")
            }
            'F' -> {
                append("fire")
            }
        }
    }
    return buf.toString()
}

fun test(src: String) {
    val tests = 100000
    var sum = 0

    for (t in 0..tests) {
        sum += method(src)
    }

    val str = mString(src)
    val pc = 100.0 * sum / tests
    println("%-40s produces %6.3f%% deaths.".format(str, pc))
}

fun main() {
    test("LSLSFSF");
    test("LSLSFF");
    test("LLSFSF");
    test("LLSFF");
}


UPC

Goal:
Convert UPC bar codes to decimal.

Specifically:

The UPC standard is actually a collection of standards -- physical standards, data format standards, product reference standards...

Here,   in this task,   we will focus on some of the data format standards,   with an imaginary physical+electrical implementation which converts physical UPC bar codes to ASCII   (with spaces and   '''#'''   characters representing the presence or absence of ink).

;Sample input:
Below, we have a representation of ten different UPC-A bar codes read by our imaginary bar code reader:

         # #   # ##  #  ## #   ## ### ## ### ## #### # # # ## ##  #   #  ##  ## ###  # ##  ## ### #  # #
        # # #   ##   ## # #### #   # ## #   ## #   ## # # # ###  # ###  ##  ## ###  # #  ### ###  # # #
         # #    # # #  ###  #   #    # #  #   #    # # # # ## #   ## #   ## #   ##   # # #### ### ## # #
       # # ##  ## ##  ##   #  #   #  # ###  # ##  ## # # #   ## ##  #  ### ## ## #   # #### ## #   # #
         # # ### ## #   ## ## ###  ##  # ##   #   # ## # # ### #  ## ##  #    # ### #  ## ##  #      # #
          # #  #   # ##  ##  #   #   #  # ##  ##  #   # # # # #### #  ##  # #### #### # #  ##  # #### # #
         # #  #  ##  ##  # #   ## ##   # ### ## ##   # # # #  #   #   #  #  ### # #    ###  # #  #   # #
        # # #    # ##  ##   #  # ##  ##  ### #   #  # # # ### ## ## ### ## ### ### ## #  ##  ### ## # #
         # # ### ##   ## # # #### #   ## # #### # #### # # #   #  # ###  #    # ###  # #    # ###  # # #
        # # # #### ##   # #### # #   ## ## ### #### # # # #  ### # ###  ###  # # ###  #    # #  ### # #

Some of these were entered upside down,   and one entry has a timing error.

;Task:
Implement code to find the corresponding decimal representation of each, rejecting the error.

Extra credit for handling the rows entered upside down   (the other option is to reject them).

;Notes:
Each digit is represented by 7 bits:

    0:  0 0 0 1 1 0 1
    1:  0 0 1 1 0 0 1
    2:  0 0 1 0 0 1 1
    3:  0 1 1 1 1 0 1
    4:  0 1 0 0 0 1 1
    5:  0 1 1 0 0 0 1
    6:  0 1 0 1 1 1 1
    7:  0 1 1 1 0 1 1
    8:  0 1 1 0 1 1 1
    9:  0 0 0 1 0 1 1

On the left hand side of the bar code a space represents a '''0''' and a '''#''' represents a '''1'''.
On the right hand side of the bar code, a '''#''' represents a '''0''' and a space represents a '''1'''
Alternatively (for the above):   spaces always represent zeros and '''#''' characters always represent ones, but the representation is logically negated -- '''1'''s and '''0'''s are flipped -- on the right hand side of the bar code.

;The UPC-A bar code structure:
::*   It begins with at least 9 spaces   (which our imaginary bar code reader unfortunately doesn't always reproduce properly),
::*   then has a     ''' # # '''     sequence marking the start of the sequence,
::*   then has the six "left hand" digits,
::*   then has a   ''' # # '''   sequence in the middle,
::*   then has the six "right hand digits",
::*   then has another   ''' # # '''   (end sequence),   and finally,
::*   then ends with nine trailing spaces   (which might be eaten by wiki edits, and in any event, were not quite captured correctly by our imaginary bar code reader).

Finally, the last digit is a checksum digit which may be used to help detect errors.

;Verification:
Multiply each digit in the represented 12 digit sequence by the corresponding number in   (3,1,3,1,3,1,3,1,3,1,3,1)   and add the products.

The sum (mod 10) must be '''0'''   (must have a zero as its last digit)   if the UPC number has been read correctly.

Solution:
val LEFT_DIGITS = mapOf(
    "   ## #" to 0,
    "  ##  #" to 1,
    "  #  ##" to 2,
    " #### #" to 3,
    " #   ##" to 4,
    " ##   #" to 5,
    " # ####" to 6,
    " ### ##" to 7,
    " ## ###" to 8,
    "   # ##" to 9
)
val RIGHT_DIGITS = LEFT_DIGITS.mapKeys {
    it.key.replace(' ', 's').replace('#', ' ').replace('s', '#')
}

const val END_SENTINEL = "# #"
const val MID_SENTINEL = " # # "

fun decodeUPC(input: String) {
    fun decode(candidate: String): Pair<Boolean, List<Int>> {
        var pos = 0
        var part = candidate.slice(pos until pos + END_SENTINEL.length)
        if (part == END_SENTINEL) {
            pos += END_SENTINEL.length
        } else {
            return Pair(false, emptyList())
        }

        val output = mutableListOf<Int>()
        for (i in 0 until 6) {
            part = candidate.slice(pos until pos + 7)
            pos += 7

            if (LEFT_DIGITS.containsKey(part)) {
                output.add(LEFT_DIGITS.getOrDefault(part, -1))
            } else {
                return Pair(false, output.toList())
            }
        }

        part = candidate.slice(pos until pos + MID_SENTINEL.length)
        if (part == MID_SENTINEL) {
            pos += MID_SENTINEL.length
        } else {
            return Pair(false, output.toList())
        }

        for (i in 0 until 6) {
            part = candidate.slice(pos until pos + 7)
            pos += 7

            if (RIGHT_DIGITS.containsKey(part)) {
                output.add(RIGHT_DIGITS.getOrDefault(part, -1))
            } else {
                return Pair(false, output.toList())
            }
        }

        part = candidate.slice(pos until pos + END_SENTINEL.length)
        if (part == END_SENTINEL) {
            pos += END_SENTINEL.length
        } else {
            return Pair(false, output.toList())
        }

        val sum = output.mapIndexed { i, v -> if (i % 2 == 0) v * 3 else v }.sum()
        return Pair(sum % 10 == 0, output.toList())
    }

    val candidate = input.trim()

    var out = decode(candidate)
    if (out.first) {
        println(out.second)
    } else {
        out = decode(candidate.reversed())
        if (out.first) {
            print(out.second)
            println(" Upside down")
        } else {
            if (out.second.size == 12) {
                println("Invalid checksum")
            } else {
                println("Invalid digit(s)")
            }
        }
    }

}

fun main() {
    val barcodes = listOf(
        "         # #   # ##  #  ## #   ## ### ## ### ## #### # # # ## ##  #   #  ##  ## ###  # ##  ## ### #  # #       ",
        "        # # #   ##   ## # #### #   # ## #   ## #   ## # # # ###  # ###  ##  ## ###  # #  ### ###  # # #         ",
        "         # #    # # #  ###  #   #    # #  #   #    # # # # ## #   ## #   ## #   ##   # # #### ### ## # #         ",
        "       # # ##  ## ##  ##   #  #   #  # ###  # ##  ## # # #   ## ##  #  ### ## ## #   # #### ## #   # #        ",
        "         # # ### ## #   ## ## ###  ##  # ##   #   # ## # # ### #  ## ##  #    # ### #  ## ##  #      # #          ",
        "          # #  #   # ##  ##  #   #   #  # ##  ##  #   # # # # #### #  ##  # #### #### # #  ##  # #### # #         ",
        "         # #  #  ##  ##  # #   ## ##   # ### ## ##   # # # #  #   #   #  #  ### # #    ###  # #  #   # #        ",
        "        # # #    # ##  ##   #  # ##  ##  ### #   #  # # # ### ## ## ### ## ### ### ## #  ##  ### ## # #         ",
        "         # # ### ##   ## # # #### #   ## # #### # #### # # #   #  # ###  #    # ###  # #    # ###  # # #       ",
        "        # # # #### ##   # #### # #   ## ## ### #### # # # #  ### # ###  ###  # # ###  #    # #  ### # #         ",
    )

    for (barcode in barcodes) {
        decodeUPC(barcode)
    }
}


URL decoding

This task   (the reverse of   [[URL encoding]]   and distinct from   [[URL parser]])   is to provide a function
or mechanism to convert an URL-encoded string into its original unencoded form.

;Test cases:
*   The encoded string   "http%3A%2F%2Ffoo%20bar%2F"   should be reverted to the unencoded form   "http://foo bar/".

*   The encoded string   "google.com/search?q=%60Abdu%27l-Bah%C3%A1"   should revert to the unencoded form   "google.com/search?q=`Abdu'l-Baha".

*   The encoded string   "%25%32%35"   should revert to the unencoded form   "%25" and '''not''' "%".

Solution:
// version 1.1.2

import java.net.URLDecoder

fun main(args: Array<String>) {
    val encoded = arrayOf("http%3A%2F%2Ffoo%20bar%2F", "google.com/search?q=%60Abdu%27l-Bah%C3%A1")
    for (e in encoded) println(URLDecoder.decode(e, "UTF-8"))
}


URL encoding

Provide a function or mechanism to convert a provided string into URL encoding representation.

In URL encoding, special characters, control characters and extended characters
are converted into a percent symbol followed by a two digit hexadecimal code,
So a space character encodes into %20 within the string.

For the purposes of this task, every character except 0-9, A-Z and a-z requires conversion, so the following characters all require conversion by default:

* ASCII control codes (Character ranges 00-1F hex (0-31 decimal) and 7F (127 decimal).
* ASCII symbols (Character ranges 32-47 decimal (20-2F hex))
* ASCII symbols (Character ranges 58-64 decimal (3A-40 hex))
* ASCII symbols (Character ranges 91-96 decimal (5B-60 hex))
* ASCII symbols (Character ranges 123-126 decimal (7B-7E hex))
* Extended characters with character codes of 128 decimal (80 hex) and above.

;Example:
The string "http://foo bar/" would be encoded as "http%3A%2F%2Ffoo%20bar%2F".

;Variations:
* Lowercase escapes are legal, as in "http%3a%2f%2ffoo%20bar%2f".
* Special characters have different encodings for different standards:
** RFC 3986, ''Uniform Resource Identifier (URI): Generic Syntax'', section 2.3, says to preserve "-._~".
** HTML 5, section 4.10.22.5 URL-encoded form data, says to preserve "-._*", and to encode space " " to "+".
** encodeURI function in Javascript will preserve "-._~" (RFC 3986) and ";,/?:@&=+$!*'()#".

;Options:
It is permissible to use an exception string (containing a set of symbols
that do not need to be converted).
However, this is an optional feature and is not a requirement of this task.

;Related tasks:
*   [[URL decoding]]
*   [[URL parser]]

Solution:
// version 1.1.2

import java.net.URLEncoder

fun main(args: Array<String>) {
    val url = "http://foo bar/"
    println(URLEncoder.encode(url, "utf-8")) // note: encodes space to + not %20
}