Stair-climbing puzzle: Difference between revisions
Realize in F#
m (fixed typo) |
(Realize in F#) |
||
(39 intermediate revisions by 25 users not shown) | |||
Line 2:
From [http://lambda-the-ultimate.org/node/1872 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:
<pre>
func step_up()
Line 18 ⟶ 20:
* 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
<br>
The second (tail) recursion above can be turned into an iteration, as follows:
<pre>
Line 27 ⟶ 30:
}
</pre>
=={{header|11l}}==
{{trans|Python}}
=== Iterative ===
<syntaxhighlight lang="11l">F step_up1()
V deficit = 1
L deficit > 0
I step()
deficit--
E
deficit++</syntaxhighlight>
=== Recursive ===
<syntaxhighlight lang="11l">F step_up2()
L !step()
step_up2()</syntaxhighlight>
=={{header|ActionScript}}==
===Iterative===
<
{
var i:int = 0;
Line 36 ⟶ 56:
if(step())i++;
else i--;
}</
===Recursive===
<
{
if(!step())
Line 45 ⟶ 65:
stepUp();
}
}</
=={{header|Ada}}==
<
begin
while not Step loop
Step_Up;
end loop;
end Step_Up;</
The following is a test program simulating Step:
<
with Ada.Text_IO;
Line 85 ⟶ 106:
Reset (Dice);
Step_Up;
end Scaffolding;</
Sample output:
<pre>
Line 101 ⟶ 122:
=={{header|Aime}}==
{{trans|C}}
<
{
while (!step()) {
step_up();
}
}</
=={{header|ALGOL 68}}==
Line 116 ⟶ 137:
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8.8d.fc9.i386]}}
<
BEGIN
WHILE NOT step DO
step up
OD
END # step up #;</
PROC scaffolding = VOID:
BEGIN
Line 149 ⟶ 170:
END # scaffolding #;
scaffolding</
Sample output:
<pre>
Line 158 ⟶ 179:
Climbed up to +1
</pre>
=={{header|Arturo}}==
<syntaxhighlight lang="rebol">Position: 0
stepUp: function [].export:[Position][
startPos: Position
until -> step [
Position = startPos + 1
]
]
step: function [].export:[Position][
(0.5 > random 0 1.0)? [
Position: Position - 1
print ~"fall (|Position|)"
false
][
Position: Position + 1
print ~"rise (|Position|)"
true
]
]
stepUp</syntaxhighlight>
{{out}}
<pre>fall (-1)
fall (-2)
rise (-1)
rise (0)
fall (-1)
fall (-2)
rise (-1)
rise (0)
rise (1)</pre>
=={{header|AutoHotkey}}==
Recursive solution:
<
{
While !step()
step_up()
}</
=={{header|AWK}}==
<syntaxhighlight lang="awk">
function step_up() {
while (!step()) { step_up() }
}
</syntaxhighlight>
=={{header|BASIC}}==
Line 173 ⟶ 238:
For many (most?) BASICs, <code>STEP</code> is a (case-insensitive) keyword, therefore the "step" function would need a different name -- in this example, "step1". (Also, for some BASICs -- notably those influenced by [[Microsoft]]'s [[QuickBASIC]] -- the underscore character ("'''_'''") is invalid inside subroutine names.)
<
IF NOT step1 THEN stepup: stepup
END SUB</
See also: [[#BBC BASIC|BBC BASIC]], [[#Liberty BASIC|Liberty BASIC]], [[#PureBasic|PureBasic]], [[#TI-83 BASIC|TI-83 BASIC]]
Line 181 ⟶ 246:
=={{header|BBC BASIC}}==
Recursive solution:
<
IF NOT FNstep PROCstepup : PROCstepup
ENDPROC</
=={{header|C}}==
<
{
while (!step()) {
step_up();
}
}</
The following uses a variable and is a bit longer, but avoids a possible stack overflow by risking a probably less likely integer overflow instead:
<
{
int i = 0;
Line 205 ⟶ 270:
}
}
}</
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">void step_up() {
while (!step()) step_up();
}</syntaxhighlight>
=={{header|C++}}==
<
{
while (!step()) step_up();
}</
The following uses a variable and is a bit longer, but avoids a possible stack overflow:
<
{
for (int i = 0; i < 1; step()? ++i : --i);
}</
=={{header|Clojure}}==
First, some boilerplate.
<
(def level (atom 41))
Line 238 ⟶ 303:
(let [success (< (rand) prob)]
(swap! level (if success inc dec))
success) )</
=== Tail-recursive ===
The internal recursion uses a counter; see the function documentation.
<
"Straightforward implementation: keep track of how many level we
need to ascend, and stop when this count is zero."
Line 250 ⟶ 315:
(or (zero? deficit)
(recur (if (step) (dec deficit)
(inc deficit)))) ) )</
=== Recursive ===
Line 256 ⟶ 321:
''p'' approaches 0.5.
<
"Non-tail-recursive. No numbers."
[]
Line 263 ⟶ 328:
(step-up2) ;; try again
)
true))</
=={{header|Common Lisp}}==
<
(unless (step) (step-up) (step-up)))</
=={{header|D}}==
The recursive version (note that "step_up" is equivalent to "step_up()" in D):
<
{
while(!step)
step_up;
}</
The non-recursive version, using 1 variable:
<
{
for(uint i = 0; i < 1; step ? ++i : --i) {};
}</
Test program:
<
import std.random;
Line 305 ⟶ 371:
rand_seed(0, 0); // to make it somewhat repeatable
step_up;
}</
Sample output:
<pre>Fell down to -1
Line 318 ⟶ 384:
Climbed up to 0
Climbed up to 1</pre>
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
Recursive version using no variables other than the Boolean returned by "Step"
<syntaxhighlight lang="Delphi">
{Recursive version}
procedure Step_Up;
begin
while not Step do Step_Up;
end;
</syntaxhighlight>
Iterative versions using one variable.
<syntaxhighlight lang="Delphi">
{Iterative version}
procedure Step_Up;
var I: integer;
begin
while I<1 do
if Step then Inc(I) else Dec(I);
end;
</syntaxhighlight>
Functional example program
<syntaxhighlight lang="Delphi">
var Position: integer;
function Step(Memo: TMemo): boolean;
begin
Result:=Random(2)=1;
if Result then Inc(Position)
else Dec(Position);
If Result then Memo.Lines.Add(Format('Climbed up to %d', [Position]))
else Memo.Lines.Add(Format('Fell down to %d', [Position]));
end;
procedure StepUp(Memo: TMemo);
begin
while not Step(Memo) do StepUp(Memo);
end;
procedure ShowStairClimb(Memo: TMemo);
begin
Position:=0;
Randomize;
StepUp(Memo);
end;
</syntaxhighlight>
{{out}}
<pre>
Fell down to -1
Climbed up to 0
Fell down to -1
Climbed up to 0
Climbed up to 1
Elapsed Time: 4.600 ms.
</pre>
=={{header|E}}==
Line 325 ⟶ 462:
The problem framework:
<
var prob := 0.5001
Line 332 ⟶ 469:
level += success.pick(1, -1)
return success
}</
Counting solution:
<
var deficit := 1
while (deficit > 0) {
deficit += step().pick(-1, 1)
}
}</
Ordinary recursive solution:
<
if (!step()) {
stepUpRecur()
stepUpRecur()
}
}</
Eventual-recursive solution. This executes on the vat ''queue'' rather than the stack, so while it has the same space usage properties as the stack-recursive version it does not use the stack which is often significantly smaller than the heap. Its return value resolves when it has completed its task.
<
if (!step()) {
return when (stepUpEventualRecur <- (),
stepUpEventualRecur <- ()) -> {}
}
}</
Fully eventual counting solution. This would be appropriate for controlling an actual robot, where the climb operation is non-instantaneous (and therefore eventual):
[[Category:E examples needing attention]]
<
# This general structure (tail-recursive def{if{when}}) is rather common
# and probably ought to be defined in a library.
Line 375 ⟶ 512:
}
return loop(1)
}</
=={{header|EchoLisp}}==
<
(define (step-up) (while (not (step)) (step-up)))
;; checking this is tail-recusive :
Line 400 ⟶ 537:
(climb stairs)
(writeln 'stairs stairs 'probability success 'steps STEPS)))
</syntaxhighlight>
{{out}}
Line 430 ⟶ 565:
</pre>
=={{header|Elixir}}==
{{trans|Erlang}}
<syntaxhighlight lang="elixir">defmodule Stair_climbing do
defp step, do: 1 == :rand.uniform(2)
defp step_up(true), do: :ok
defp step_up(false) do
step_up(step)
step_up(step)
end
def step_up, do: step_up(step)
end
IO.inspect Stair_climbing.step_up</syntaxhighlight>
=={{header|Erlang}}==
<
-module(stair).
-compile(export_all).
Line 447 ⟶ 597:
step_up() ->
step_up(step()).
</syntaxhighlight>
=={{header|Euphoria}}==
<
if not step() then
step_up()
step_up()
end if
end procedure</
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
let rec step_up() = while not(step()) do step_up()
</syntaxhighlight>
=={{header|Factor}}==
<syntaxhighlight lang="factor">: step-up ( -- ) step [ step-up step-up ] unless ;</syntaxhighlight>
=={{header|Forth}}==
Recursive. May exceed return stack unless compiler optimizes tail calls.
<
Counting. Avoids using a named variable.
<
=={{header|Fortran}}==
Line 466 ⟶ 624:
{{works with|Fortran|90 and later}}
<
implicit none
Line 493 ⟶ 651:
end subroutine step_up_iter
end module StairRobot</
=={{header|FreeBASIC}}==
Since step is a statement modifier in FreeBASIC, we will use step_
Iterative version using one variable.
<syntaxhighlight lang="freebasic">Sub step_up()
Dim As Integer i
Do
If step_() Then
i += 1
Else
i -= 1
End If
Loop Until i = 1
End Sub</syntaxhighlight>
Recursive version.
<syntaxhighlight lang="freebasic">Sub step_up()
While Not step_()
step_up()
Wend
End Sub</syntaxhighlight>
Demonstration program.
<syntaxhighlight lang="freebasic">Function step_() As Boolean
If Int((Rnd * 2)) Then
Print "Robot sube"
Return True
Else
Print "Robot se cae"
Return False
End If
End Function
'recursive
Sub step_up()
While Not step_()
step_up()
Wend
End Sub
step_up
Sleep</syntaxhighlight>
=={{header|Go}}==
38 bytes, no variables, no numbers.
<
=={{header|Groovy}}==
<syntaxhighlight lang="grovy">
class Stair_climbing{
static void main(String[] args){
}
static def step_up(){
while not step(){
step_up();
}
}
}
</syntaxhighlight>
=={{header|Haskell}}==
Line 502 ⟶ 719:
In Haskell, stateful computation is only allowed in a monad. Then suppose we have a monad <code>Robot</code> with an action <code>step :: Robot Bool</code>. We can implement <code>stepUp</code> like this:
<
stepUp = untilM step stepUp
Line 508 ⟶ 725:
untilM test action = do
result <- test
if result then return () else action >> untilM test action</
Here's an example implementation of <code>Robot</code> and <code>step</code>, as well as a <code>main</code> with which to test <code>stepUp</code>.
<
import System.Random (StdGen, getStdGen, random)
Line 530 ⟶ 747:
putStrLn $ "The robot is at step #" ++ show startingPos ++ "."
let (endingPos, _) = execState stepUp (startingPos, g)
putStrLn $ "The robot is at step #" ++ show endingPos ++ "."</
=={{header|Icon}} and {{header|Unicon}}==
Line 539 ⟶ 756:
is implemented in Icon (or Unicon) and fails only when the implementation in
another language returns <tt>false</tt>, then:
<
return step() | (step_up(),step_up())
end</
You can subtract a few more characters (and multiply the difficulty
of understanding) with:
<
(|not step(), step_up())
end</
=={{header|J}}==
'''Solution (Tacit):'''
<
attemptClimb =: [: <:`>:@.step 0:
isNotUpOne =: -.@(+/@])
step_up=: (] , attemptClimb)^:isNotUpOne^:_</
Note that <code>0:</code> is not a number but a verb (function) that returns the number zero irrespective of its argument(s). And, arguably, infinity is not any specific number. And, finally, <code>step</code> is presumed to pre-exist in the task description. Therefore the above solution for <code>step_up</code> could validly be said to meet the restrictions of no variables or numbers.
J's verbs (functions) always take an argument. J programmers use verbs which ignore their arguments (e.g. <code>step</code> and <code>attemptClimb</code>) to
'''Solution (Explicit):'''
<
while. -. +/y do. y=. y , _1 1 {~ step 0 end.
)
Line 567 ⟶ 784:
step_upR=: monad define NB. recursive (stack overflow possible!)
while. -. step'' do. step_upR'' end.
)</
'''Example usage:'''
<
_1 1 _1 _1 1 1 1
+/\ _1 1 _1 _1 1 1 1 NB. running sum of output (current step relative to start)
_1 0 _1 _2 _1 0 1
+/\ step_up '' NB. another example
_1 _2 _3 _2 _3 _2 _1 _2 _3 _4 _3 _2 _3 _2 _3 _2 _3 _2 _1 _2 _1 _2 _1 0 1</
Another approach might be:
<
Here, the argument is the number of the starting step and the result is a list of the numbers of each visited step including the initial and final steps. For example:
<
2 1 0 1 2 3
keepTrying 3
3 2 3 2 3 2 3 4
keepTrying 4
4 5</
=={{header|Java}}==
{{trans|C++}}
<
while (!step()) stepUp();
}</
The following uses a variable and is a bit longer, but avoids a possible stack overflow:
<
for (int i = 0; i < 1; step() ? ++i : --i);
}</
=={{header|jq}}==
Line 605 ⟶ 822:
Since jq is a purely functional language, we need to keep track of time explicitly. This can be done using a clock that ticks the time:
<syntaxhighlight lang
To model the robot's success and failure, we shall assume a sufficiently large array of 0/1 values is available.
To avoid problems with modeling infinite time, we will pad the array with 1s if necessary.
<
"step" returns true or false based on the current time (the input) and the value of "random":
<
random as $r
| if . >= ($r|length) then true else ($r[.] == 1) end ;</
We can now define step_up:
<
if step then tick
else tick | step_up | step_up
end;</
Now we can start the simulation at time 0; step_up will then emit the number of "step" attempts that have been made to achieve success:
<syntaxhighlight lang
{{out}}
<
11</
===Tail Call Optimization===
To take advantage of jq's TCO (available in versions of jq after the release of Version 1.4), the step_up
function must be tail-recursive and have arity 0. This can be
achieved by providing [time, goal] as the input as follows:
<
.[0] as $time | .[1] as $goal
| if $goal == 0 then $time
Line 635 ⟶ 852:
if $time|step then $goal - 1 else $goal + 1 end
| [ ($time|tick), .] | tco_step_up
end ;</
The simulation can then be started as follows:
<syntaxhighlight lang
=={{header|Julia}}==
As specified, shorter and fewer numbers preferred. It may be supposed that the robot would reach the bottom of any steps well before blowing the stack to reboot.
<syntaxhighlight lang="julia">
step_up() = while !step() step_up() end
</syntaxhighlight>
Here is an example to test the code with a step that has a 1/3 failure rate:
<syntaxhighlight lang="julia">
step() = (b = rand([true,true,false]); println(b); b)
step_up()
</syntaxhighlight>
{{output}}
<pre>
julia> step_up()
true
julia> step_up()
true
julia> step_up()
false
true
true
</pre>
=={{header|Kotlin}}==
{{trans|D}}
<syntaxhighlight lang="scala">// 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()
}</syntaxhighlight>
{{out}}
<pre>
Fell down to -1
Fell down to -2
Climbed up to -1
Climbed up to 0
Fell down to -1
Climbed up to 0
Fell down to -1
Climbed up to 0
Climbed up to 1
</pre>
=={{header|Liberty BASIC}}==
<
'Run it several times to see the differences; sometimes the robot falls
'quite a ways before making it to the next step up, but sometimes he makes it
Line 660 ⟶ 940:
Print "Robot fell down"
End If
End Function</
=={{header|Logo}}==
Recursive.
<
if not step [step.up step.up]
end</
Constant space (fully tail-recursive).
<
if :n=0 [stop]
(step.up ifelse step [:n-1] [:n+1])
end</
=={{header|Lua}}==
<syntaxhighlight lang="lua">
function step_up()
while not step() do step_up() end
end
</syntaxhighlight>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">StepUp[] := If[!Step[], StepUp[]; StepUp[]]</syntaxhighlight>
=={{header|MATLAB}}==
<
while ~step()
step_up();
end</
=={{header|Nim}}==
One liner (yes it is possible in Nim).
<syntaxhighlight lang="nim">proc stepUp = (while not step(): stepUp())</syntaxhighlight>
=={{header|OCaml}}==
<
while not(step()) do
step_up()
done
;;</
=={{header|Oz}}==
Recursive solution:
<
if {Not {Step}} then
{StepUp} %% make up for the fall
{StepUp} %% repeat original attempt
end
end</
Might lead to a stack overflow because the first call to <code>StepUp</code> is not in tail position.
Iterative solution:
<
Level = {NewCell 0}
in
Line 731 ⟶ 1,001:
end
end
</syntaxhighlight>
Oz has arbitrary large integers. So if the robot is very unlucky, the contents of the <code>Level</code> variable will fill up all the memory and the program will fail. I believe this problem needs infinite memory to be solved for all cases.
=={{header|PARI/GP}}==
<
=={{header|Pascal}}==
Recursive solution:
<
begin
while not step do
stepUp;
end;</
=={{header|Perl}}==
<
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">procedure</span> <span style="color: #000000;">step_up</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">while</span> <span style="color: #008080;">not</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">do</span> <span style="color: #000000;">step_up</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<!--</syntaxhighlight>-->
=={{header|PicoLisp}}==
<
(until (step1) # ('step1', because 'step' is a system function)
(stepUp) ) )</
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">function StepUp
{
If ( -not ( Step ) )
{
StepUp
StepUp
}
}
# Step simulator for testing
function Step
{
If ( Get-Random 0,1 )
{
$Success = $True
Write-Verbose "Up one step"
}
Else
{
$Success = $False
Write-Verbose "Fell one step"
}
return $Success
}
# Test
$VerbosePreference = 'Continue'
StepUp</syntaxhighlight>
{{out}}
<pre>VERBOSE: Fell one step
VERBOSE: Fell one step
VERBOSE: Up one step
VERBOSE: Fell one step
VERBOSE: Fell one step
VERBOSE: Up one step
VERBOSE: Up one step
VERBOSE: Up one step
VERBOSE: Fell one step
VERBOSE: Up one step
VERBOSE: Up one step</pre>
=={{header|Prolog}}==
The robot code is very short
<syntaxhighlight lang="prolog">step_up :- \+ step, step_up, step_up.</syntaxhighlight>
The test program keeps track of the level in a dynamic predicate.
<syntaxhighlight lang="prolog">:- dynamic level/1.
setup :-
retractall(level(_)),
assert(level(1)).
step :-
level(Level),
random_between(0,3,N),
(
N > 0 ->
succ(Level, NewLevel), format('Climbed up to ~d~n', NewLevel)
;
succ(NewLevel, Level), format('Fell down to ~d~n', NewLevel)
),
retractall(level(Level)),
assert(level(NewLevel)),
N > 0. % Fail if 0 because that is a non step up.</syntaxhighlight>
{{out}}
<pre>
?- setup, between(1,10,_), step_up, fail.
Climbed up to 2
Climbed up to 3
Climbed up to 4
Climbed up to 5
Fell down to 4
Climbed up to 5
Climbed up to 6
Fell down to 5
Climbed up to 6
Climbed up to 7
Climbed up to 8
Fell down to 7
Climbed up to 8
false.
?-
</pre>
=={{header|PureBasic}}==
Iterative version using one variable.
<
Protected i
Repeat: If _step(): i + 1: Else: i - 1: EndIf: Until i = 1
EndProcedure</
Recursive version. Stack may overflow as probability of a fall approaches or exceeds 50%.
<
While Not _step()
step_up()
Wend
EndProcedure</
Demonstration program.
<
Procedure _step()
Line 803 ⟶ 1,158:
Input()
CloseConsole()
EndIf</
Sample output:
<pre>Begin at level: 0
Line 816 ⟶ 1,171:
=== Iterative ===
<
"""Straightforward implementation: keep track of how many level we
need to ascend, and stop when this count is zero."""
deficit = 1
while deficit > 0:
Line 824 ⟶ 1,179:
deficit -= 1
else:
deficit += 1</
=== Recursive ===
Line 830 ⟶ 1,185:
''p'' approaches 0.5.
<
"No numbers."
while not step():
step_up2() # undo the fall</
=={{header|Quackery}}==
<syntaxhighlight lang="quackery">[ step if done recurse again ] is step-up</syntaxhighlight>
=={{header|R}}==
Line 839 ⟶ 1,198:
The step() function described would not be idiomatic R, since it would
require using the global assignment operator to get the side effect.
<
success <- runif(1) > p
## Requires that the "robot" is a variable named "level"
level <<- level - 1 + (2 * success)
success
}</
===Recursive Solution===
<
while(! step()) {
stepUp()
}
}</
===Iterative Solution===
<
i <- 0
while ( ! i) {
i <- i - 1 + (2 * step())
}
}</
Example output:
Line 878 ⟶ 1,237:
=={{header|Racket}}==
<
(define p 0.5001)
(define (step)
Line 888 ⟶ 1,247:
(else (step-up (add1 n)))))
(step-up 1)</
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>sub step_up { step_up until step; }</syntaxhighlight>
=={{header|REBOL}}==
<
Title: "Stair Climber"
URL: http://rosettacode.org/wiki/Stair_Climbing
]
Line 931 ⟶ 1,292:
step_upt: does [if not step [step_upt step_upt]]
step_upt print "Success!"</
Output:
Line 946 ⟶ 1,307:
=={{header|REXX}}==
<
end
return</syntaxhighlight>
=={{header|
<syntaxhighlight lang="ring">
stepup()
func stepup
while n <
if stp() n=n+1 else n= n-1 ok
see n + nl
end
func stp
return 0
</syntaxhighlight>
=={{header|Ruby}}==
<
start_position = $position
step until ($position == start_position + 1)
Line 987 ⟶ 1,348:
$position = 0
step_up</
Sample run:
<pre>$ ruby -d stair.climbing.rb
Line 999 ⟶ 1,360:
"rise (0)"
"rise (1)"</pre>
=={{header|Run BASIC}}==
<syntaxhighlight lang="runbasic">
result = stepUp()
Function stepUp()
While Not(stepp())
result = stepUp()
Wend
End Function
Function stepp()
stepp = int((Rnd(1) * 2))
print "Robot stepped "+word$("up down",stepp+1)
End Function
</syntaxhighlight>
=={{header|Rust}}==
<syntaxhighlight lang="rust">fn step_up() {
while !step() {
step_up();
}
}</syntaxhighlight>
=={{header|SAS}}==
<syntaxhighlight lang="sas">
%macro step();
%sysfunc(round(%sysfunc(ranuni(0))))
%mend step;
</syntaxhighlight>
===Recursive===
<syntaxhighlight lang="sas">
%macro step_up();
Line 1,019 ⟶ 1,406:
%step_up;
</syntaxhighlight>
===Iterative===
<syntaxhighlight lang="sas">
%macro step_up();
%do %while (not %step);
%put Step Down;
%step_up;
%end;
%put Step Up;
%mend step_up;
</syntaxhighlight>
Sample Output:
Line 1,039 ⟶ 1,441:
Simple recursive solution:
<
Non-recursive solution which almost gets away with not having named variables:
<
def rec: List[Boolean] => Boolean = step :: (_: List[Boolean]) match {
case true :: Nil => true
Line 1,050 ⟶ 1,452:
}
rec(Nil)
}</
=={{header|Scheme}}==
<
(cond ((zero? n-steps) 'done)
((step) (step-up (- n-steps 1)))
(else (step-up (+ n-steps 1)))))</
=={{header|Seed7}}==
<
begin
while not doStep do
step_up;
end while;
end func;</
=={{header|Sidef}}==
<
while (!step()) {
step_up();
}
}</
=={{header|Smalltalk}}==
Line 1,077 ⟶ 1,479:
The following uses a block closure and the recursive solution which consumes stack until successful.
<
stepUp := [ [ step value ] whileFalse: [ stepUp value ] ].</
=={{header|Standard ML}}==
<syntaxhighlight lang="sml">
(*
* val step : unit -> bool
Line 1,092 ⟶ 1,495:
*)
fun step_up() = step() orelse (step_up() andalso step_up())
</syntaxhighlight>
Alternate version:
<syntaxhighlight lang="sml">fun step() = true
fun step_up() = while step() = false do step_up()
</syntaxhighlight>
=={{header|Swift}}==
<
while !step() {
step_up()
}
}</
The following uses a variable and is a bit longer, but avoids a possible stack overflow:
<
for var i = 0; i < 1; step()? ++i : --i { }
}</
=={{header|Tcl}}==
The setup (note that <code>level</code> and <code>steps</code> are not used elsewhere, but are great for testing…)
<
set prob 0.5001
proc step {} {
Line 1,120 ⟶ 1,529:
return 0
}
}</
===Iterative Solution===
All iterative solutions require a counter variable, but at least we can avoid any literal digits...
<
for {incr d} {$d} {incr d} {
incr d [set s -[step]]; incr d $s
}
}</
===Recursive Solution===
This is the simplest possible recursive solution:
<
while {![step]} step-up-rec
}</
=={{header|TI-83 BASIC}}==
Line 1,138 ⟶ 1,547:
<code>prgmSTEP</code>:
<
0→C
Disp "FALL"
Line 1,154 ⟶ 1,563:
End
If B=1
Pause</
<code>prgmSTEPUP</code>:
<
While C=0
prgmSTEPUP
prgmSTEP
End</
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "random" for Random
import "./fmt" for Conv
var rand = Random.new(1268) // generates short repeatable sequence
var position = 0
var step = Fn.new {
var r = Conv.itob(rand.int(2))
if (r) {
position = position + 1
System.print("Climbed up to %(position)")
} else {
position = position - 1
System.print("Fell down to %(position)")
}
return r
}
var stepUp // recursive
stepUp = Fn.new {
while (!step.call()) stepUp.call()
}
stepUp.call()</syntaxhighlight>
{{out}}
<pre>
Fell down to -1
Fell down to -2
Climbed up to -1
Climbed up to 0
Fell down to -1
Climbed up to 0
Climbed up to 1
</pre>
=={{header|XPL0}}==
<
int I;
[I:= 0;
Line 1,173 ⟶ 1,621:
proc Step_up; \Recursive version
while not Step do Step_up;</
=={{header|zkl}}==
Line 1,179 ⟶ 1,627:
This version consumes stack space proportional to the number of steps it needs to go up, as opposed to the number of steps it attempts. This is a substantial difference if the probability of success is only somewhat greater than or equal to 1/2.
<
fcn stepUp{ while(not step()){ self.fcn() } }</
You could also use "stepUp" instead of self.fcn, self.fcn seems a little clearer and makes it easier to refactor.
An example step function:
{{trans|D}}
<syntaxhighlight lang="zkl">var position=0;
fcn step(){ //-->0|1
r:=(0).random(2); // 0 or 1
if(r) println("Climbed up to ",position+=1);
else println("Fell down to ", position-=1);
r
}
stepUp();</syntaxhighlight>
{{out}}
<pre>
Fell down to -1
Climbed up to 0
Fell down to -1
Fell down to -2
Climbed up to -1
Climbed up to 0
Climbed up to 1
</pre>
|