How to resolve the algorithm 9 billion names of God the integer step by step in the Scala programming language
How to resolve the algorithm 9 billion names of God the integer step by step in the Scala programming language
Table of Contents
Problem Statement
This task is a variation of the short story by Arthur C. Clarke. (Solvers should be aware of the consequences of completing this task.) In detail, to specify what is meant by a “name”:
Display the first 25 rows of a number triangle which begins: Where row
n
{\displaystyle n}
corresponds to integer
n
{\displaystyle n}
, and each column
C
{\displaystyle C}
in row
m
{\displaystyle m}
from left to right corresponds to the number of names beginning with
C
{\displaystyle C}
. A function
G ( n )
{\displaystyle G(n)}
should return the sum of the
n
{\displaystyle n}
-th row. Demonstrate this function by displaying:
G ( 23 )
{\displaystyle G(23)}
,
G ( 123 )
{\displaystyle G(123)}
,
G ( 1234 )
{\displaystyle G(1234)}
, and
G ( 12345 )
{\displaystyle G(12345)}
.
Optionally note that the sum of the
n
{\displaystyle n}
-th row
P ( n )
{\displaystyle P(n)}
is the integer partition function. Demonstrate this is equivalent to
G ( n )
{\displaystyle G(n)}
by displaying:
P ( 23 )
{\displaystyle P(23)}
,
P ( 123 )
{\displaystyle P(123)}
,
P ( 1234 )
{\displaystyle P(1234)}
, and
P ( 12345 )
{\displaystyle P(12345)}
.
If your environment is able, plot
P ( n )
{\displaystyle P(n)}
against
n
{\displaystyle n}
for
n
1 … 999
{\displaystyle n=1\ldots 999}
.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm 9 billion names of God the integer step by step in the Scala programming language
Source code in the scala programming language
object Main {
// This is a special class for memoization
case class Memo[A,B](f: A => B) extends (A => B) {
private val cache = Map.empty[A, B]
def apply(x: A) = cache getOrElseUpdate (x, f(x))
}
// Naive, but memoized solution
lazy val namesStartingMemo : Memo[Tuple2[Int, Int], BigInt] = Memo {
case (1, 1) => 1
case (a, n) =>
if (a > n/2) namesStartingMemo(a - 1, n - 1)
else if (n < a) 0
else if (n == a) 1
else (1 to a).map(i => namesStartingMemo(i, n - a)).sum
}
def partitions(n: Int) = (1 to n).map(namesStartingMemo(_, n)).sum
// main method
def main(args: Array[String]): Unit = {
for (i <- 1 to 25) {
for (j <- 1 to i) {
print(namesStartingMemo(j, i));
print(' ');
}
println()
}
println(partitions(23))
println(partitions(123))
println(partitions(1234))
println(partitions(12345))
}
}
val cache = new Array[BigInt](15000)
cache(0) = 1
val cacheNaive = scala.collection.mutable.Map[Tuple2[Int, Int], BigInt]()
def p(n: Int, k: Int): BigInt = cacheNaive.getOrElseUpdate((n, k), (n, k) match {
case (n, 1) => 1
case (n, k) if n < k => 0
case (n, k) if n == k => 1
case (n, k) =>
if (k > n/2) p(n - 1, k - 1)
else p(n - 1, k - 1) + p(n - k, k)
})
def partitions(n: Int) = (1 to n).map(p(n, _)).sum
def updateCache(n: Int, d: Int, k: Int) =
if ((k & 1) == 1) cache(n) = cache(n) + cache(d)
else cache(n) = cache(n) - cache(d)
def quickPartitions(n: Int): BigInt = {
cache(n) = 0
for (k <- 1 to n) {
val d = n - k * (3 * k - 1) / 2
if (d >= 0) {
updateCache(n, d, k)
val e = d - k
if (e >= 0) {
updateCache(n, e, k)
}
}
}
cache(n)
}
for (i <- 1 to 23) {
for (j <- 1 to i) {
print(f"${p(i, j)}%4d")
}
println
}
println(partitions(23))
for (i <- 1 until cache.length) {
quickPartitions(i)
}
println(quickPartitions(123))
println(quickPartitions(1234))
println(quickPartitions(12345))
You may also check:How to resolve the algorithm Quaternion type step by step in the Mercury programming language
You may also check:How to resolve the algorithm De Bruijn sequences step by step in the 8080 Assembly programming language
You may also check:How to resolve the algorithm Text processing/2 step by step in the PowerShell programming language
You may also check:How to resolve the algorithm MD5 step by step in the Raku programming language
You may also check:How to resolve the algorithm Literals/String step by step in the J programming language