Minimal steps down to 1: Difference between revisions
Add Kotlin implementation
(→{{header|Haskell}}: added Haskell solution) |
(Add Kotlin implementation) |
||
(11 intermediate revisions by 6 users not shown) | |||
Line 1:
{{task}}
Given:
Line 51 ⟶ 49:
{{trans|Python: Tabulated}}
<
Set[Int] divs, subs
[Int] table
Line 102 ⟶ 100:
V mx = max(mintab.table[1..])
V ans = enumerate(mintab.table).filter((n, steps) -> steps == @mx).map((n, steps) -> n)
print(‘ Taking ’mx‘ steps is/are the ’ans.len‘ numbers: ’ans.map(n -> String(n)).join(‘, ’))</
{{out}}
Line 150 ⟶ 148:
=={{header|C sharp}}==
{{works with|C sharp|7}}
<
using System.Collections.Generic;
using System.Linq;
Line 223 ⟶ 221:
private static string Delimit<T>(this IEnumerable<T> source) => string.Join(", ", source);
}</
{{out}}
<pre>
Line 253 ⟶ 251:
There is one number below 2000 that requires 17 steps: 1699
There is one number below 20000 that requires 24 steps: 19681</pre>
=={{header|C++}}==
<syntaxhighlight lang="c++">
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
const int32_t limit = 50'000;
std::vector<int32_t> divisors;
std::vector<int32_t> subtractors;
std::vector<std::vector<std::string>> minimums;
template <typename T>
void print_vector(const std::vector<T>& list) {
for ( uint64_t i = 0; i < list.size(); ++i ) {
std::cout << list[i];
if ( i < list.size() - 1 ) {
std::cout << ", ";
}
}
}
// Assumes that numbers are presented in ascending order up to 'limit'.
void minimum_steps(int32_t n) {
if ( n == 1 ) {
return;
}
int32_t minimum = limit;
int32_t p = 0;
int32_t q = 0;
std::string operator_symbol = "";
for ( int32_t divisor : divisors ) {
if ( n % divisor == 0 ) {
int32_t d = n / divisor;
int32_t steps = minimums[d].size() + 1;
if ( steps < minimum ) {
minimum = steps;
p = d;
q = divisor;
operator_symbol = "/";
}
}
}
for ( int32_t subtractor : subtractors ) {
int32_t d = n - subtractor;
if ( d >= 1 ) {
int32_t steps = minimums[d].size() + 1;
if ( steps < minimum ) {
minimum = steps;
p = d;
q = subtractor;
operator_symbol = "-";
}
}
}
minimums[n].emplace_back(operator_symbol + std::to_string(q) + " -> " + std::to_string(p));
minimums[n].insert(minimums[n].end(), minimums[p].begin(), minimums[p].end());
}
int main() {
for ( int32_t item : { 0, 1 } ) {
divisors = { 2, 3 };
subtractors = { item + 1 };
minimums = std::vector(limit + 1, std::vector<std::string>(0));
std::cout << "With: Divisors: { "; print_vector<int32_t>(divisors);
std::cout << " }, Subtractors: { "; print_vector<int32_t>(subtractors); std::cout << " } =>" << std::endl;
std::cout << " Minimum number of steps to diminish the following numbers down to 1 is:" << std::endl;
for ( int32_t i = 1; i < limit; ++i ) {
minimum_steps(i);
if ( i <= 10 ) {
int32_t steps = minimums[i].size();
const std::string plural = ( steps == 1 ) ? " : " : "s: ";
std::cout << " " << std::setw(2) << i << ": " << steps << " step" + plural;
print_vector<std::string>(minimums[i]); std::cout << std::endl;
}
}
for ( int32_t lim : { 2'000, 20'000, 50'000 } ) {
uint64_t max = 0;
for ( int32_t j = 1; j <= lim; ++j ) {
uint64_t m = minimums[j].size();
if ( m > max ) {
max = m;
}
}
std::vector<int32_t> maxs;
for ( int32_t j = 1; j <= lim; ++j ) {
if ( minimums[j].size() == max ) {
maxs.emplace_back(j);
}
}
int32_t size = maxs.size();
std::string verb1 = ( size == 1 ) ? "is" : "are";
std::string verb2 = ( size == 1 ) ? "has" : "have";
std::string plural = ( size == 1 ) ? "" : "s";
std::cout << " There " << verb1 << " " << size << " number" << plural << " in the range 1 - " << lim
<< " that " << verb2 << " maximum 'minimal steps' of " << max << ":" << std::endl;
std::cout << " [ "; print_vector<int32_t>(maxs); std::cout << " ]" << std::endl;
}
std::cout << std::endl;
}
}
</syntaxhighlight>
{{ out }}
<pre>
With: Divisors: { 2, 3 }, Subtractors: { 1 } =>
Minimum number of steps to diminish the following numbers down to 1 is:
1: 0 steps:
2: 1 step : /2 -> 1
3: 1 step : /3 -> 1
4: 2 steps: /2 -> 2, /2 -> 1
5: 3 steps: -1 -> 4, /2 -> 2, /2 -> 1
6: 2 steps: /2 -> 3, /3 -> 1
7: 3 steps: -1 -> 6, /2 -> 3, /3 -> 1
8: 3 steps: /2 -> 4, /2 -> 2, /2 -> 1
9: 2 steps: /3 -> 3, /3 -> 1
10: 3 steps: -1 -> 9, /3 -> 3, /3 -> 1
There are 16 numbers in the range 1 - 2000 that have maximum 'minimal steps' of 14:
[ 863, 1079, 1295, 1439, 1511, 1583, 1607, 1619, 1691, 1727, 1823, 1871, 1895, 1907, 1919, 1943 ]
There are 5 numbers in the range 1 - 20000 that have maximum 'minimal steps' of 20:
[ 12959, 15551, 17279, 18143, 19439 ]
There are 3 numbers in the range 1 - 50000 that have maximum 'minimal steps' of 22:
[ 25919, 31103, 38879 ]
With: Divisors: { 2, 3 }, Subtractors: { 2 } =>
Minimum number of steps to diminish the following numbers down to 1 is:
1: 0 steps:
2: 1 step : /2 -> 1
3: 1 step : /3 -> 1
4: 2 steps: /2 -> 2, /2 -> 1
5: 2 steps: -2 -> 3, /3 -> 1
6: 2 steps: /2 -> 3, /3 -> 1
7: 3 steps: -2 -> 5, -2 -> 3, /3 -> 1
8: 3 steps: /2 -> 4, /2 -> 2, /2 -> 1
9: 2 steps: /3 -> 3, /3 -> 1
10: 3 steps: /2 -> 5, -2 -> 3, /3 -> 1
There is 1 number in the range 1 - 2000 that has maximum 'minimal steps' of 17:
[ 1699 ]
There is 1 number in the range 1 - 20000 that has maximum 'minimal steps' of 24:
[ 19681 ]
There is 1 number in the range 1 - 50000 that has maximum 'minimal steps' of 26:
[ 45925 ]
</pre>
=={{header|FreeBASIC}}==
{{trans|XPL0}}
<syntaxhighlight lang="freebasic">Dim Shared As Integer minPasos 'minimal number of steps to get to 1
Dim Shared As Integer Subtractor '1 or 2
Dim Shared As Integer Ns(20000), Ops(20000), MinNs(20000), MinOps(20000)
Sub Reduce(N As Integer, Paso As Integer) 'Reduce N to 1, recording minimum steps
If N = 1 Then
If Paso < minPasos Then
For i As Integer = 0 To Paso-1
MinOps(i) = Ops(i)
MinNs(i) = Ns(i)
Next i
minPasos = Paso
End If
End If
If Paso >= minPasos Then Exit Sub 'don't search further
If N Mod 3 = 0 Then Ops(Paso) = 3 : Ns(Paso) = N/3 : Reduce(N/3, Paso+1)
If N Mod 2 = 0 Then Ops(Paso) = 2 : Ns(Paso) = N/2 : Reduce(N/2, Paso+1)
Ops(Paso) = -Subtractor
Ns(Paso) = N-Subtractor
Reduce(N-Subtractor, Paso+1)
End Sub
Sub ShowSteps(N As Integer) 'Show minimal steps and how N steps to 1
minPasos = 50000
Reduce(N, 0)
Print "N = " & N & " takes " & minPasos & " steps: N";
For i As Integer = 0 To minPasos-1
Print Iif(Sgn(MinOps(i)) < 0, " -", " /");
Print Abs(MinOps(i)) & "=>" & MinNs(i); '" "
Next i
Print
End Sub
Sub ShowCount(Range As Integer) 'Show count of maximum minimal steps and their Ns
Dim As Integer N, MaxSteps
MaxSteps = 0 'find maximum number of minimum steps
For N = 1 To Range
minPasos = 50000
Reduce(N, 0)
If minPasos > MaxSteps Then MaxSteps = minPasos
Next N
Print "Maximum steps:"; MaxSteps; " for N =";
For N = 1 To Range 'show numbers (Ns) for Maximum steps
minPasos = 50000
Reduce(N, 0)
If minPasos = MaxSteps Then Print N; '" ";
Next N
Print
End Sub
Dim As Integer N
Subtractor = 1 '1.
For N = 1 To 10
ShowSteps(N)
Next N
ShowCount(2000) '2.
ShowCount(20000) '2a.
Print
Subtractor = 2 '3.
For N = 1 To 10
ShowSteps(N)
Next N
ShowCount(2000) '4.
ShowCount(20000) '4a.
Sleep</syntaxhighlight>
{{out}}
<pre>Same as XPL0 entry.</pre>
=={{header|Go}}==
<
import (
Line 348 ⟶ 567:
fmt.Println()
}
}</
{{out}}
Line 392 ⟶ 611:
=={{header|Haskell}}==
<
import Data.List
import Data.Ord
Line 435 ⟶ 654:
(s, k) <- steps >>= run n
let (m, ss) = go k
return (m+1, s:ss)</
<pre>λ> minSteps [Div 2, Div 3, Sub 1] 123
Line 445 ⟶ 664:
The task
<
showSteps = foldl go . show
where
Line 464 ⟶ 683:
head $ groupBy ((==) `on` (fst.snd)) $
sortOn (negate . fst . snd) $
zip [1..] (minSteps steps <$> range)</
<pre>λ> task1 [Div 2, Div 3, Sub 1]
Line 510 ⟶ 729:
λ> task2 [Div 2, Div 3, Sub 2] [1..2000]
17: (((((((((((1699-2)-2)/3-2)-2)/3-2)-2)/3-2)-2)/3-2)-2)/3-2)/3</pre>
=={{header|J}}==
Implementation:
<syntaxhighlight lang="j">step=: {{
~.((#~ 1<:]),y-/m),(#~ (=<.)),y%/n
}}
steps=: {{
m step n^:(1 - 1 e. ])^:a:
}}
show=: {{
paths=.,:,:0 0 1 NB. operator, operand, net value
m=.,m [ n=.,n NB. m: subtractors, n: divisors
for_ok.}.|.m steps n y do. NB. ok: valid net values
last=.{."2 paths
subs=. (1,.m,.0)+"2]0 0 1*"1 last+"1 0/m
divs=. (2,.n,.0)+"2]0 0 1*"1 last*"1 0/n
prev=. subs,"2 divs NB. we are working backwards from 1
paths=. (,({:"1 prev)e.ok)#,/prev,"1 2/"2 paths
end.
;@((<":y),,)"2((' -/'{~{.);":@{:)"1}:"2}:"1 paths
}}
</syntaxhighlight>
Counting the steps is rather trivial -- we build a step function which subtracts the possible subtractors (discarding numbers which are too small) and divides by the possible divisors (discarding numbers which are not integers), then we iterate on that until we find a 1.
Showing the paths is more complicated. The approach used here is to first find the valid step values and then, starting from 1, add the possible subtractors, and multiply by the possible divisors, discarding the values which were not valid for that step and tracking the previous values. Once we have built a representation of the valid paths (at each stage: operator, operand and net result) we reverse and format those.
Task examples:
<syntaxhighlight lang="j">taskA=: {{
for_j. 1+i.10 do.
echo rplc&(' 1 steps';' 1 step')j,&":': ',(_1+#x steps y j),&":' steps.'
echo x show y j
echo ''
end.
}}
taskB=: {{
echo 'considering positive integers up to ',":m
tallies=. _1+#@(x steps y)every 1+i.m
echo (>./tallies) ,&": ' steps: ',&": 1+I.(=>./)tallies
echo ''
}}
task=: 2e4 taskB, 2e3 taskB, taskA
1 task 2 3
1: 0 steps.
1
2: 1 step.
2-1
2/2
3: 1 step.
3/3
4: 2 steps.
4/2-1
4/2/2
4-1/3
5: 3 steps.
5-1/2-1
5-1/2/2
5-1-1/3
6: 2 steps.
6/3-1
6/3/2
6/2/3
7: 3 steps.
7-1/3-1
7-1/3/2
7-1/2/3
8: 3 steps.
8/2/2-1
8/2/2/2
8/2-1/3
9: 2 steps.
9/3/3
10: 3 steps.
10-1/3/3
considering positive integers up to 2000
14 steps: 863 1079 1295 1439 1511 1583 1607 1619 1691 1727 1823 1871 1895 1907 1919 1943
considering positive integers up to 20000
20 steps: 12959 15551 17279 18143 19439
2 task 2 3
1: 0 steps.
1
2: 1 step.
2/2
3: 1 step.
3-2
3/3
4: 2 steps.
4-2/2
4/2/2
5: 2 steps.
5-2-2
5-2/3
6: 2 steps.
6/2-2
6/3/2
6/2/3
7: 3 steps.
7-2-2-2
7-2-2/3
8: 3 steps.
8-2/2-2
8/2-2/2
8/2/2/2
8-2/3/2
8-2/2/3
9: 2 steps.
9/3-2
9/3/3
10: 3 steps.
10/2-2-2
10/2-2/3
considering positive integers up to 2000
17 steps: 1699
considering positive integers up to 20000
24 steps: 19681
</syntaxhighlight>
=={{header|Java}}==
Line 515 ⟶ 880:
Algorithm works with any function that supports the <code>Function</code> interface in the code below.
<
import java.util.ArrayList;
import java.util.HashMap;
Line 730 ⟶ 1,095:
}
</syntaxhighlight>
{{out}}
Line 794 ⟶ 1,159:
Implemented as a generic solution for any functions acting on an integer and taking any range of second arguments, with the goal solution also specifiable. To do so generically, it is also necessary to specify a failure condition, which in the example is falling below 1.
<
struct Action{T}
Line 885 ⟶ 1,250:
empty!(memoized)
teststeps(1, failed, actions2, [2000, 20000, 50000])
</
<pre>
With goal 1, divisors [2, 3], subtractors [1]:
Line 954 ⟶ 1,319:
There are 1 with 24 steps for start between 1 and 20000: [19681]
There are 1 with 26 steps for start between 1 and 50000: [45925]
</pre>
=={{header|Kotlin}}==
{{trans|Java}}
<syntaxhighlight lang="Kotlin">
fun main() {
runTasks(getFunctions1())
runTasks(getFunctions2())
runTasks(getFunctions3())
}
fun runTasks(functions: List<Function>) {
val minPath = getInitialMap(functions, 5)
// Task 1
val max = 10
populateMap(minPath, functions, max)
println("\nWith functions: $functions")
println(" Minimum steps to 1:")
for (n in 2..max) {
val steps = minPath[n]?.size ?: 0
println(" %2d: %d step%s: %s".format(n, steps, if (steps == 1) "" else "s", minPath[n]))
}
// Task 2
displayMaxMin(minPath, functions, 2000)
// Task 2a
displayMaxMin(minPath, functions, 20000)
// Task 2a +
displayMaxMin(minPath, functions, 100000)
}
fun displayMaxMin(minPath: MutableMap<Int, List<String>>, functions: List<Function>, max: Int) {
populateMap(minPath, functions, max)
val maxIntegers = getMaxMin(minPath, max)
val maxSteps = maxIntegers.removeAt(0)
val numCount = maxIntegers.size
println(" There ${if (numCount == 1) "is" else "are"} $numCount number${if (numCount == 1) "" else "s"} in the range 1-$max that have maximum 'minimal steps' of $maxSteps:\n $maxIntegers")
}
fun getMaxMin(minPath: Map<Int, List<String>>, max: Int): MutableList<Int> {
var maxSteps = Int.MIN_VALUE
val maxIntegers = mutableListOf<Int>()
for (n in 2..max) {
val len = minPath[n]?.size ?: 0
if (len > maxSteps) {
maxSteps = len
maxIntegers.clear()
maxIntegers.add(n)
} else if (len == maxSteps) {
maxIntegers.add(n)
}
}
maxIntegers.add(0, maxSteps)
return maxIntegers
}
fun populateMap(minPath: MutableMap<Int, List<String>>, functions: List<Function>, max: Int) {
for (n in 2..max) {
if (n in minPath) continue
var minFunction: Function? = null
var minSteps = Int.MAX_VALUE
for (f in functions) {
if (f.actionOk(n)) {
val result = f.action(n)
val steps = 1 + (minPath[result]?.size ?: 0)
if (steps < minSteps) {
minFunction = f
minSteps = steps
}
}
}
minFunction?.let {
val result = it.action(n)
val path = mutableListOf(it.toString(n))
path.addAll(minPath[result] ?: emptyList())
minPath[n] = path
}
}
}
fun getInitialMap(functions: List<Function>, max: Int): MutableMap<Int, List<String>> {
val minPath = mutableMapOf<Int, List<String>>()
for (i in 2..max) {
for (f in functions) {
if (f.actionOk(i)) {
val result = f.action(i)
if (result == 1) {
minPath[i] = listOf(f.toString(i))
}
}
}
}
return minPath
}
fun getFunctions1(): List<Function> = listOf(
Divide3Function(),
Divide2Function(),
Subtract1Function()
)
fun getFunctions2(): List<Function> = listOf(
Divide3Function(),
Divide2Function(),
Subtract2Function()
)
fun getFunctions3(): List<Function> = listOf(
Divide2Function(),
Divide3Function(),
Subtract2Function(),
Subtract1Function()
)
abstract class Function {
abstract fun action(n: Int): Int
abstract fun actionOk(n: Int): Boolean
abstract fun toString(n: Int): String
}
class Divide2Function : Function() {
override fun action(n: Int) = n / 2
override fun actionOk(n: Int) = n % 2 == 0
override fun toString(n: Int) = "/2 -> ${n / 2}"
override fun toString() = "Divisor 2"
}
class Divide3Function : Function() {
override fun action(n: Int) = n / 3
override fun actionOk(n: Int) = n % 3 == 0
override fun toString(n: Int) = "/3 -> ${n / 3}"
override fun toString() = "Divisor 3"
}
class Subtract1Function : Function() {
override fun action(n: Int) = n - 1
override fun actionOk(n: Int) = true
override fun toString(n: Int) = "-1 -> ${n - 1}"
override fun toString() = "Subtractor 1"
}
class Subtract2Function : Function() {
override fun action(n: Int) = n - 2
override fun actionOk(n: Int) = n > 2
override fun toString(n: Int) = "-2 -> ${n - 2}"
override fun toString() = "Subtractor 2"
}
</syntaxhighlight>
{{out}}
<pre>
With functions: [Divisor 3, Divisor 2, Subtractor 1]
Minimum steps to 1:
2: 1 step: [-1 -> 1]
3: 1 step: [/3 -> 1]
4: 2 steps: [/2 -> 2, -1 -> 1]
5: 3 steps: [-1 -> 4, /2 -> 2, -1 -> 1]
6: 2 steps: [/3 -> 2, -1 -> 1]
7: 3 steps: [-1 -> 6, /3 -> 2, -1 -> 1]
8: 3 steps: [/2 -> 4, /2 -> 2, -1 -> 1]
9: 2 steps: [/3 -> 3, /3 -> 1]
10: 3 steps: [-1 -> 9, /3 -> 3, /3 -> 1]
There are 16 numbers in the range 1-2000 that have maximum 'minimal steps' of 14:
[863, 1079, 1295, 1439, 1511, 1583, 1607, 1619, 1691, 1727, 1823, 1871, 1895, 1907, 1919, 1943]
There are 5 numbers in the range 1-20000 that have maximum 'minimal steps' of 20:
[12959, 15551, 17279, 18143, 19439]
There is 1 number in the range 1-100000 that have maximum 'minimal steps' of 24:
[77759]
With functions: [Divisor 3, Divisor 2, Subtractor 2]
Minimum steps to 1:
2: 1 step: [/2 -> 1]
3: 1 step: [-2 -> 1]
4: 2 steps: [/2 -> 2, /2 -> 1]
5: 2 steps: [-2 -> 3, -2 -> 1]
6: 2 steps: [/3 -> 2, /2 -> 1]
7: 3 steps: [-2 -> 5, -2 -> 3, -2 -> 1]
8: 3 steps: [/2 -> 4, /2 -> 2, /2 -> 1]
9: 2 steps: [/3 -> 3, -2 -> 1]
10: 3 steps: [/2 -> 5, -2 -> 3, -2 -> 1]
There is 1 number in the range 1-2000 that have maximum 'minimal steps' of 17:
[1699]
There is 1 number in the range 1-20000 that have maximum 'minimal steps' of 24:
[19681]
There is 1 number in the range 1-100000 that have maximum 'minimal steps' of 28:
[98413]
With functions: [Divisor 2, Divisor 3, Subtractor 2, Subtractor 1]
Minimum steps to 1:
2: 1 step: [-1 -> 1]
3: 1 step: [-2 -> 1]
4: 2 steps: [/2 -> 2, -1 -> 1]
5: 2 steps: [-2 -> 3, -2 -> 1]
6: 2 steps: [/2 -> 3, -2 -> 1]
7: 3 steps: [-2 -> 5, -2 -> 3, -2 -> 1]
8: 3 steps: [/2 -> 4, /2 -> 2, -1 -> 1]
9: 2 steps: [/3 -> 3, -2 -> 1]
10: 3 steps: [/2 -> 5, -2 -> 3, -2 -> 1]
There is 1 number in the range 1-2000 that have maximum 'minimal steps' of 13:
[1943]
There are 2 numbers in the range 1-20000 that have maximum 'minimal steps' of 17:
[17495, 19439]
There are 22 numbers in the range 1-100000 that have maximum 'minimal steps' of 19:
[58319, 69983, 76463, 77759, 78623, 87479, 89423, 90071, 90287, 90359, 90383, 90395, 91259, 91355, 91367, 93311, 95255, 95471, 95903, 96119, 96191, 98171]
</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<
ClearAll[MinimalStepToOne, MinimalStepToOneHelper]
MinimalStepToOne[n_Integer] := Module[{res},
Line 1,165 ⟶ 1,738:
a = Last[SortBy[GatherBy[allsols, Last], First /* Last]];
{a[[1, 2]], a[[All, 1]]}</
{{out}}
<pre>1: (0 steps) 1
Line 1,194 ⟶ 1,767:
We use two recursive functions, the first one to find the minimal length sequences, the second one to find the minimal number of steps. For both, we use memoization. The program takes about 10 ms to execute.
<
type
Line 1,314 ⟶ 1,887:
run(divisors = [2, 3], subtractors = [1])
echo ""
run(divisors = [2, 3], subtractors = [2])</
{{out}}
Line 1,346 ⟶ 1,919:
=={{header|Perl}}==
<
use strict; # https://rosettacode.org/wiki/Minimal_steps_down_to_1
Line 1,393 ⟶ 1,966:
}
return \@solve, \@maximal;
}</
{{out}}
<pre>
Line 1,429 ⟶ 2,002:
=={{header|Phix}}==
Using simple iterative (vs recursive) memoisation. To make things a bit more interesting it maintains separate caches for any&all {d,s} sets.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">cache</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
<span style="color: #000000;">ckeys</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">ms21</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">ds</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">cdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ds</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ckeys</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">cdx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">ckeys</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ckeys</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ds</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">cache</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cache</span><span style="color: #0000FF;">,{{}})</span>
<span style="color: #000000;">cdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cache</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cache</span><span style="color: #0000FF;">[</span><span style="color: #000000;">cdx</span><span style="color: #0000FF;">])+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ms</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">steps</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ds</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- (d then s)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">dsk</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">ok</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dsk</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">:</span><span style="color: #000000;">i</span><span style="color: #0000FF;">></span><span style="color: #000000;">dsk</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ok</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?</span><span style="color: #000000;">i</span><span style="color: #0000FF;">/</span><span style="color: #000000;">dsk</span><span style="color: #0000FF;">:</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">dsk</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cache</span><span style="color: #0000FF;">[</span><span style="color: #000000;">cdx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">m</span><span style="color: #0000FF;">])+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ms</span><span style="color: #0000FF;">></span><span style="color: #000000;">l</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">ms</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">l</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">step</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%s%d -> %d"</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"/-"</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">],</span><span style="color: #000000;">dsk</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">steps</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">prepend</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cache</span><span style="color: #0000FF;">[</span><span style="color: #000000;">cdx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">m</span><span style="color: #0000FF;">]),</span><span style="color: #000000;">step</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">steps</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">cache</span><span style="color: #0000FF;">[</span><span style="color: #000000;">cdx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cache</span><span style="color: #0000FF;">[</span><span style="color: #000000;">cdx</span><span style="color: #0000FF;">],</span><span style="color: #000000;">steps</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">cache</span><span style="color: #0000FF;">[</span><span style="color: #000000;">cdx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">n</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show10</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">ds</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\nWith divisors %v and subtractors %v:\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ds</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">steps</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ms21</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ds</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ns</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">steps</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">ps</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ns</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?</span><span style="color: #008000;">""</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"s"</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">eg</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ns</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?</span><span style="color: #008000;">""</span><span style="color: #0000FF;">:</span><span style="color: #008000;">", eg "</span><span style="color: #0000FF;">&</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">steps</span><span style="color: #0000FF;">,</span><span style="color: #008000;">","</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%2d takes %d step%s%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ns</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ps</span><span style="color: #0000FF;">,</span><span style="color: #000000;">eg</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">maxsteps</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">ds</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">lim</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ms</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ls</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">mc</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000000;">steps</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">args</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">lim</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">steps</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ms21</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ds</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">ls</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">steps</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ls</span><span style="color: #0000FF;">></span><span style="color: #000000;">ms</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">ms</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ls</span>
<span style="color: #000000;">mc</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">ls</span><span style="color: #0000FF;">=</span><span style="color: #000000;">ms</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">mc</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">n</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">lm</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mc</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">are</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ps</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ns</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lm</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?{</span><span style="color: #008000;">"is"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"s"</span><span style="color: #0000FF;">}:{</span><span style="color: #008000;">"are"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"s"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">args</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span> <span style="color: #000000;">are</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lm</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ps</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">lim</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ns</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ms</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mc</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)}</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"There %s %d number%s below %d that require%s %d steps: %v\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">args</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">show10</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}})</span>
<span style="color: #000000;">maxsteps</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}},</span><span style="color: #000000;">2000</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">maxsteps</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}},</span><span style="color: #000000;">20000</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">maxsteps</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}},</span><span style="color: #000000;">50000</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show10</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}})</span>
<span style="color: #000000;">maxsteps</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}},</span><span style="color: #000000;">2000</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">maxsteps</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}},</span><span style="color: #000000;">20000</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">maxsteps</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}},</span><span style="color: #000000;">50000</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
With divisors {2,3} and subtractors {1}:
1 takes 0 steps
2 takes 1 step, eg /2 -> 1
3 takes 1 step, eg /3 -> 1
4 takes 2 steps, eg /2 -> 2,/2 -> 1
5 takes 3 steps, eg -1 -> 4,/2 -> 2,/2 -> 1
6 takes 2 steps, eg /2 -> 3,/3 -> 1
7 takes 3 steps, eg -1 -> 6,/2 -> 3,/3 -> 1
8 takes 3 steps, eg /2 -> 4,/2 -> 2,/2 -> 1
9 takes 2 steps, eg /3 -> 3,/3 -> 1
10 takes 3 steps, eg -1 -> 9,/3 -> 3,/3 -> 1
There are 16 numbers below 2000 that require 14 steps: {863,1079,1295,
There are 5 numbers below 20000 that require 20 steps: {12959,15551,17279,18143,19439}
There are 3 numbers below 50000 that require 22 steps: {25919,31103,38879}
With divisors {2,3} and subtractors {2}:
1 takes 0 steps
2 takes 1 step, eg /2 -> 1
3 takes 1 step, eg /3 -> 1
4 takes 2 steps, eg /2 -> 2,/2 -> 1
5 takes 2 steps, eg -2 -> 3,/3 -> 1
6 takes 2 steps, eg /2 -> 3,/3 -> 1
7 takes 3 steps, eg -2 -> 5,-2 -> 3,/3 -> 1
8 takes 3 steps, eg /2 -> 4,/2 -> 2,/2 -> 1
9 takes 2 steps, eg /3 -> 3,/3 -> 1
10 takes 3 steps, eg /2 -> 5,-2 -> 3,/3 -> 1
There is 1 number below 2000 that requires 17 steps: {1699}
Line 1,538 ⟶ 2,116:
Although the stretch goal could be achieved by changing the recursion limit, it does point out a possible issue with this type of solution. But then again, this solution may be more natural to some.
<
from functools import lru_cache
Line 1,593 ⟶ 2,171:
', '.join(str(n) for n in sorted(ans)))
#print(minrec._minrec.cache_info())
print()</
{{out}}
Line 1,637 ⟶ 2,215:
The table to solve for N contains all the results from 1 up to N. This is used in the solution.
<
"Tabulation, memoised minimised steps to 1"
Line 1,694 ⟶ 2,272:
ans = [n for n, steps in enumerate(table) if steps == mx]
print(' Taking', mx, f'steps is/are the {len(ans)} numbers:',
', '.join(str(n) for n in ans))</
{{out}}
Line 1,741 ⟶ 2,319:
{{works with|Rakudo|2019.11}}
<syntaxhighlight lang="raku"
for [2,3], 1, 2000,
Line 1,779 ⟶ 2,357:
}
}
}</
{{out}}
<pre>Divisors: [2, 3], subtract: 1
Line 1,838 ⟶ 2,416:
{{trans|Python}}
<
var table = Array(repeating: n + 2, count: n + 1)
var how = Array(repeating: [""], count: n + 2)
Line 1,892 ⟶ 2,470:
)
}
}</
{{out}}
Line 1,939 ⟶ 2,517:
{{trans|Go}}
{{libheader|Wren-fmt}}
<
var limit = 50000
Line 2,021 ⟶ 2,599:
}
System.print()
}</
{{out}}
Line 2,065 ⟶ 2,643:
=={{header|XPL0}}==
<
Subtractor; \1 or 2
char Ns(20000), Ops(20000), MinNs(20000), MinOps(20000);
Line 2,132 ⟶ 2,710:
ShowCount(2000); \4.
ShowCount(20_000); \4a.
]</
{{out}}
Line 2,163 ⟶ 2,741:
=={{header|zkl}}==
<
fcn buildCache(N,D,S){
minCache=Dictionary(1,T(1,"",0));
Line 2,180 ⟶ 2,758:
do(steps){ v,o,s := minCache[N]; ops.write(" ",o,"-->",N=v); }
return(steps,ops.close())
}</
<
buildCache(MAX,D,S);
Line 2,195 ⟶ 2,773:
S=T(2); buildCache(MAX,D,S);
}</
{{out}}
<pre style="height:45ex">
|