Stair-climbing puzzle: Difference between revisions

From Rosetta Code
Content added Content deleted
mNo edit summary
(Realize in F#)
 
(27 intermediate revisions by 16 users not shown)
Line 30: Line 30:
}
}
</pre>
</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}}==
=={{header|ActionScript}}==
===Iterative===
===Iterative===
<lang ActionScript>function stepUp()
<syntaxhighlight lang="actionscript">function stepUp()
{
{
var i:int = 0;
var i:int = 0;
Line 39: Line 56:
if(step())i++;
if(step())i++;
else i--;
else i--;
}</lang>
}</syntaxhighlight>
===Recursive===
===Recursive===
<lang ActionScript>function stepUp()
<syntaxhighlight lang="actionscript">function stepUp()
{
{
if(!step())
if(!step())
Line 48: Line 65:
stepUp();
stepUp();
}
}
}</lang>
}</syntaxhighlight>


=={{header|Ada}}==
=={{header|Ada}}==
<lang Ada>procedure Step_Up is
<syntaxhighlight lang="ada">procedure Step_Up is
begin
begin
while not Step loop
while not Step loop
Step_Up;
Step_Up;
end loop;
end loop;
end Step_Up;</lang>
end Step_Up;</syntaxhighlight>
The following is a test program simulating Step:
The following is a test program simulating Step:
<lang Ada>with Ada.Numerics.Discrete_Random;
<syntaxhighlight lang="ada">with Ada.Numerics.Discrete_Random;
with Ada.Text_IO;
with Ada.Text_IO;


Line 89: Line 106:
Reset (Dice);
Reset (Dice);
Step_Up;
Step_Up;
end Scaffolding;</lang>
end Scaffolding;</syntaxhighlight>
Sample output:
Sample output:
<pre>
<pre>
Line 105: Line 122:
=={{header|Aime}}==
=={{header|Aime}}==
{{trans|C}}
{{trans|C}}
<lang aime>void step_up(void)
<syntaxhighlight lang="aime">void step_up(void)
{
{
while (!step()) {
while (!step()) {
step_up();
step_up();
}
}
}</lang>
}</syntaxhighlight>


=={{header|ALGOL 68}}==
=={{header|ALGOL 68}}==
Line 120: Line 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]}}
{{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]}}
<lang Algol68> PROC step up = VOID:
<syntaxhighlight lang="algol68"> PROC step up = VOID:
BEGIN
BEGIN
WHILE NOT step DO
WHILE NOT step DO
step up
step up
OD
OD
END # step up #;</lang>The following is a test program simulating step: <lang Algol68>
END # step up #;</syntaxhighlight>The following is a test program simulating step: <syntaxhighlight lang="algol68">
PROC scaffolding = VOID:
PROC scaffolding = VOID:
BEGIN
BEGIN
Line 153: Line 170:
END # scaffolding #;
END # scaffolding #;


scaffolding</lang>
scaffolding</syntaxhighlight>
Sample output:
Sample output:
<pre>
<pre>
Line 162: Line 179:
Climbed up to +1
Climbed up to +1
</pre>
</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}}==
=={{header|AutoHotkey}}==
Recursive solution:
Recursive solution:
<lang AutoHotkey>step_up()
<syntaxhighlight lang="autohotkey">step_up()
{
{
While !step()
While !step()
step_up()
step_up()
}</lang>
}</syntaxhighlight>

=={{header|AWK}}==
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
function step_up() {
function step_up() {
while (!step()) { step_up() }
while (!step()) { step_up() }
}
}
</syntaxhighlight>
</lang>


=={{header|BASIC}}==
=={{header|BASIC}}==
Line 183: Line 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.)
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.)


<lang qbasic>SUB stepup
<syntaxhighlight lang="qbasic">SUB stepup
IF NOT step1 THEN stepup: stepup
IF NOT step1 THEN stepup: stepup
END SUB</lang>
END SUB</syntaxhighlight>


See also: [[#BBC BASIC|BBC BASIC]], [[#Liberty BASIC|Liberty BASIC]], [[#PureBasic|PureBasic]], [[#TI-83 BASIC|TI-83 BASIC]]
See also: [[#BBC BASIC|BBC BASIC]], [[#Liberty BASIC|Liberty BASIC]], [[#PureBasic|PureBasic]], [[#TI-83 BASIC|TI-83 BASIC]]
Line 191: Line 246:
=={{header|BBC BASIC}}==
=={{header|BBC BASIC}}==
Recursive solution:
Recursive solution:
<lang bbcbasic> DEF PROCstepup
<syntaxhighlight lang="bbcbasic"> DEF PROCstepup
IF NOT FNstep PROCstepup : PROCstepup
IF NOT FNstep PROCstepup : PROCstepup
ENDPROC</lang>
ENDPROC</syntaxhighlight>


=={{header|C}}==
=={{header|C}}==
<lang c>void step_up(void)
<syntaxhighlight lang="c">void step_up(void)
{
{
while (!step()) {
while (!step()) {
step_up();
step_up();
}
}
}</lang>
}</syntaxhighlight>


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:
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:
<lang c>void step_up(void)
<syntaxhighlight lang="c">void step_up(void)
{
{
int i = 0;
int i = 0;
Line 215: Line 270:
}
}
}
}
}</lang>
}</syntaxhighlight>

=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">void step_up() {
while (!step()) step_up();
}</syntaxhighlight>


=={{header|C++}}==
=={{header|C++}}==
<lang cpp>void step_up()
<syntaxhighlight lang="cpp">void step_up()
{
{
while (!step()) step_up();
while (!step()) step_up();
}</lang>
}</syntaxhighlight>


The following uses a variable and is a bit longer, but avoids a possible stack overflow:
The following uses a variable and is a bit longer, but avoids a possible stack overflow:
<lang cpp>void step_up()
<syntaxhighlight lang="cpp">void step_up()
{
{
for (int i = 0; i < 1; step()? ++i : --i);
for (int i = 0; i < 1; step()? ++i : --i);
}</lang>
}</syntaxhighlight>

=={{header|C sharp|C#}}==
<lang csharp>void step_up() {
while (!step()) step_up();
}</lang>


=={{header|Clojure}}==
=={{header|Clojure}}==
First, some boilerplate.
First, some boilerplate.


<lang lisp>;; the initial level
<syntaxhighlight lang="lisp">;; the initial level
(def level (atom 41))
(def level (atom 41))


Line 248: Line 303:
(let [success (< (rand) prob)]
(let [success (< (rand) prob)]
(swap! level (if success inc dec))
(swap! level (if success inc dec))
success) )</lang>
success) )</syntaxhighlight>


=== Tail-recursive ===
=== Tail-recursive ===
The internal recursion uses a counter; see the function documentation.
The internal recursion uses a counter; see the function documentation.


<lang lisp>(defn step-up1
<syntaxhighlight lang="lisp">(defn step-up1
"Straightforward implementation: keep track of how many level we
"Straightforward implementation: keep track of how many level we
need to ascend, and stop when this count is zero."
need to ascend, and stop when this count is zero."
Line 260: Line 315:
(or (zero? deficit)
(or (zero? deficit)
(recur (if (step) (dec deficit)
(recur (if (step) (dec deficit)
(inc deficit)))) ) )</lang>
(inc deficit)))) ) )</syntaxhighlight>


=== Recursive ===
=== Recursive ===
Line 266: Line 321:
''p'' approaches 0.5.
''p'' approaches 0.5.


<lang lisp>(defn step-up2
<syntaxhighlight lang="lisp">(defn step-up2
"Non-tail-recursive. No numbers."
"Non-tail-recursive. No numbers."
[]
[]
Line 273: Line 328:
(step-up2) ;; try again
(step-up2) ;; try again
)
)
true))</lang>
true))</syntaxhighlight>

=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
<lang lisp>(defun step-up ()
<syntaxhighlight lang="lisp">(defun step-up ()
(unless (step) (step-up) (step-up)))</lang>
(unless (step) (step-up) (step-up)))</syntaxhighlight>


=={{header|D}}==
=={{header|D}}==
The recursive version (note that "step_up" is equivalent to "step_up()" in D):
The recursive version (note that "step_up" is equivalent to "step_up()" in D):
<lang d>void step_up()
<syntaxhighlight lang="d">void step_up()
{
{
while(!step)
while(!step)
step_up;
step_up;
}</lang>
}</syntaxhighlight>
The non-recursive version, using 1 variable:
The non-recursive version, using 1 variable:
<lang d>void step_up_nr()
<syntaxhighlight lang="d">void step_up_nr()
{
{
for(uint i = 0; i < 1; step ? ++i : --i) {};
for(uint i = 0; i < 1; step ? ++i : --i) {};
}</lang>
}</syntaxhighlight>
Test program:
Test program:
<lang d>import std.stdio;
<syntaxhighlight lang="d">import std.stdio;
import std.random;
import std.random;


Line 315: Line 371:
rand_seed(0, 0); // to make it somewhat repeatable
rand_seed(0, 0); // to make it somewhat repeatable
step_up;
step_up;
}</lang>
}</syntaxhighlight>
Sample output:
Sample output:
<pre>Fell down to -1
<pre>Fell down to -1
Line 328: Line 384:
Climbed up to 0
Climbed up to 0
Climbed up to 1</pre>
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}}==
=={{header|E}}==
Line 335: Line 462:
The problem framework:
The problem framework:


<lang e>var level := 41
<syntaxhighlight lang="e">var level := 41
var prob := 0.5001
var prob := 0.5001


Line 342: Line 469:
level += success.pick(1, -1)
level += success.pick(1, -1)
return success
return success
}</lang>
}</syntaxhighlight>


Counting solution:
Counting solution:


<lang e>def stepUpCounting() {
<syntaxhighlight lang="e">def stepUpCounting() {
var deficit := 1
var deficit := 1
while (deficit > 0) {
while (deficit > 0) {
deficit += step().pick(-1, 1)
deficit += step().pick(-1, 1)
}
}
}</lang>
}</syntaxhighlight>


Ordinary recursive solution:
Ordinary recursive solution:
<lang e>def stepUpRecur() {
<syntaxhighlight lang="e">def stepUpRecur() {
if (!step()) {
if (!step()) {
stepUpRecur()
stepUpRecur()
stepUpRecur()
stepUpRecur()
}
}
}</lang>
}</syntaxhighlight>


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.
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.


<lang e>def stepUpEventualRecur() {
<syntaxhighlight lang="e">def stepUpEventualRecur() {
if (!step()) {
if (!step()) {
return when (stepUpEventualRecur <- (),
return when (stepUpEventualRecur <- (),
stepUpEventualRecur <- ()) -> {}
stepUpEventualRecur <- ()) -> {}
}
}
}</lang>
}</syntaxhighlight>


Fully eventual counting solution. This would be appropriate for controlling an actual robot, where the climb operation is non-instantaneous (and therefore eventual):
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]]
[[Category:E examples needing attention]]
<lang e>def stepUpEventual() {
<syntaxhighlight lang="e">def stepUpEventual() {
# This general structure (tail-recursive def{if{when}}) is rather common
# This general structure (tail-recursive def{if{when}}) is rather common
# and probably ought to be defined in a library.
# and probably ought to be defined in a library.
Line 385: Line 512:
}
}
return loop(1)
return loop(1)
}</lang>
}</syntaxhighlight>


=={{header|EchoLisp}}==
=={{header|EchoLisp}}==
<lang scheme>
<syntaxhighlight lang="scheme">
(define (step-up) (while (not (step)) (step-up)))
(define (step-up) (while (not (step)) (step-up)))
;; checking this is tail-recusive :
;; checking this is tail-recusive :
Line 410: Line 537:
(climb stairs)
(climb stairs)
(writeln 'stairs stairs 'probability success 'steps STEPS)))
(writeln 'stairs stairs 'probability success 'steps STEPS)))
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 440: Line 567:
=={{header|Elixir}}==
=={{header|Elixir}}==
{{trans|Erlang}}
{{trans|Erlang}}
<lang elixir>defmodule Stair_climbing do
<syntaxhighlight lang="elixir">defmodule Stair_climbing do
defp step, do: 1 == :rand.uniform(2)
defp step, do: 1 == :rand.uniform(2)
Line 452: Line 579:
end
end


IO.inspect Stair_climbing.step_up</lang>
IO.inspect Stair_climbing.step_up</syntaxhighlight>


=={{header|Erlang}}==
=={{header|Erlang}}==
<lang erlang>
<syntaxhighlight lang="erlang">
-module(stair).
-module(stair).
-compile(export_all).
-compile(export_all).
Line 470: Line 597:
step_up() ->
step_up() ->
step_up(step()).
step_up(step()).
</syntaxhighlight>
</lang>


=={{header|Euphoria}}==
=={{header|Euphoria}}==
<lang euphoria>procedure step_up()
<syntaxhighlight lang="euphoria">procedure step_up()
if not step() then
if not step() then
step_up()
step_up()
step_up()
step_up()
end if
end if
end procedure</lang>
end procedure</syntaxhighlight>

=={{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}}==
=={{header|Forth}}==
Recursive. May exceed return stack unless compiler optimizes tail calls.
Recursive. May exceed return stack unless compiler optimizes tail calls.
<lang forth>: step-up begin step 0= while recurse repeat ;</lang>
<syntaxhighlight lang="forth">: step-up begin step 0= while recurse repeat ;</syntaxhighlight>
Counting. Avoids using a named variable.
Counting. Avoids using a named variable.
<lang forth>: step-up -1 begin step if 1+ else 1- then ?dup 0= until ;</lang>
<syntaxhighlight lang="forth">: step-up -1 begin step if 1+ else 1- then ?dup 0= until ;</syntaxhighlight>


=={{header|Fortran}}==
=={{header|Fortran}}==
Line 490: Line 624:


{{works with|Fortran|90 and later}}
{{works with|Fortran|90 and later}}
<lang fortran>module StairRobot
<syntaxhighlight lang="fortran">module StairRobot
implicit none
implicit none


Line 517: Line 651:
end subroutine step_up_iter
end subroutine step_up_iter


end module StairRobot</lang>
end module StairRobot</syntaxhighlight>

=={{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}}==
=={{header|Go}}==
38 bytes, no variables, no numbers.
38 bytes, no variables, no numbers.
<lang go>func step_up(){for !step(){step_up()}}</lang>
<syntaxhighlight lang="go">func step_up(){for !step(){step_up()}}</syntaxhighlight>


=={{header|Groovy}}==
=={{header|Groovy}}==
<syntaxhighlight lang="grovy">
<lang Grovy>
class Stair_climbing{
class Stair_climbing{
static void main(String[] args){
static void main(String[] args){
Line 535: Line 713:


}
}
</syntaxhighlight>
</lang>


=={{header|Haskell}}==
=={{header|Haskell}}==
Line 541: Line 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:
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:


<lang haskell>stepUp :: Robot ()
<syntaxhighlight lang="haskell">stepUp :: Robot ()
stepUp = untilM step stepUp
stepUp = untilM step stepUp


Line 547: Line 725:
untilM test action = do
untilM test action = do
result <- test
result <- test
if result then return () else action >> untilM test action</lang>
if result then return () else action >> untilM test action</syntaxhighlight>


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>.
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>.


<lang haskell>import Control.Monad.State
<syntaxhighlight lang="haskell">import Control.Monad.State
import System.Random (StdGen, getStdGen, random)
import System.Random (StdGen, getStdGen, random)


Line 569: Line 747:
putStrLn $ "The robot is at step #" ++ show startingPos ++ "."
putStrLn $ "The robot is at step #" ++ show startingPos ++ "."
let (endingPos, _) = execState stepUp (startingPos, g)
let (endingPos, _) = execState stepUp (startingPos, g)
putStrLn $ "The robot is at step #" ++ show endingPos ++ "."</lang>
putStrLn $ "The robot is at step #" ++ show endingPos ++ "."</syntaxhighlight>


=={{header|Icon}} and {{header|Unicon}}==
=={{header|Icon}} and {{header|Unicon}}==
Line 578: Line 756:
is implemented in Icon (or Unicon) and fails only when the implementation in
is implemented in Icon (or Unicon) and fails only when the implementation in
another language returns <tt>false</tt>, then:
another language returns <tt>false</tt>, then:
<lang unicon>procedure step_up()
<syntaxhighlight lang="unicon">procedure step_up()
return step() | (step_up(),step_up())
return step() | (step_up(),step_up())
end</lang>
end</syntaxhighlight>


You can subtract a few more characters (and multiply the difficulty
You can subtract a few more characters (and multiply the difficulty
of understanding) with:
of understanding) with:
<lang unicon>procedure step_up()
<syntaxhighlight lang="unicon">procedure step_up()
(|not step(), step_up())
(|not step(), step_up())
end</lang>
end</syntaxhighlight>


=={{header|J}}==
=={{header|J}}==
'''Solution (Tacit):'''
'''Solution (Tacit):'''
<lang j>step =: 0.6 > ?@0:
<syntaxhighlight lang="j">step =: 0.6 > ?@0:
attemptClimb =: [: <:`>:@.step 0:
attemptClimb =: [: <:`>:@.step 0:
isNotUpOne =: -.@(+/@])
isNotUpOne =: -.@(+/@])


step_up=: (] , attemptClimb)^:isNotUpOne^:_</lang>
step_up=: (] , attemptClimb)^:isNotUpOne^:_</syntaxhighlight>
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.
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.


Line 600: Line 778:


'''Solution (Explicit):'''
'''Solution (Explicit):'''
<lang j>step_upX=: monad define NB. iterative
<syntaxhighlight lang="j">step_upX=: monad define NB. iterative
while. -. +/y do. y=. y , _1 1 {~ step 0 end.
while. -. +/y do. y=. y , _1 1 {~ step 0 end.
)
)
Line 606: Line 784:
step_upR=: monad define NB. recursive (stack overflow possible!)
step_upR=: monad define NB. recursive (stack overflow possible!)
while. -. step'' do. step_upR'' end.
while. -. step'' do. step_upR'' end.
)</lang>
)</syntaxhighlight>


'''Example usage:'''
'''Example usage:'''
<lang j> step_up '' NB. output is sequence of falls & climbs required to climb one step.
<syntaxhighlight lang="j"> step_up '' NB. output is sequence of falls & climbs required to climb one step.
_1 1 _1 _1 1 1 1
_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 1 _1 _1 1 1 1 NB. running sum of output (current step relative to start)
_1 0 _1 _2 _1 0 1
_1 0 _1 _2 _1 0 1
+/\ step_up '' NB. another example
+/\ 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</lang>
_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</syntaxhighlight>




Another approach might be:
Another approach might be:


<lang J>keepTrying=: (, {: - _1 ^ step)^:({. >: {:)^:_</lang>
<syntaxhighlight lang="j">keepTrying=: (, {: - _1 ^ step)^:({. >: {:)^:_</syntaxhighlight>


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


<lang J> keepTrying 2
<syntaxhighlight lang="j"> keepTrying 2
2 1 0 1 2 3
2 1 0 1 2 3
keepTrying 3
keepTrying 3
3 2 3 2 3 2 3 4
3 2 3 2 3 2 3 4
keepTrying 4
keepTrying 4
4 5</lang>
4 5</syntaxhighlight>


=={{header|Java}}==
=={{header|Java}}==
{{trans|C++}}
{{trans|C++}}
<lang java>public void stepUp() {
<syntaxhighlight lang="java">public void stepUp() {
while (!step()) stepUp();
while (!step()) stepUp();
}</lang>
}</syntaxhighlight>
The following uses a variable and is a bit longer, but avoids a possible stack overflow:
The following uses a variable and is a bit longer, but avoids a possible stack overflow:
<lang java>public void stepUp(){
<syntaxhighlight lang="java">public void stepUp(){
for (int i = 0; i < 1; step() ? ++i : --i);
for (int i = 0; i < 1; step() ? ++i : --i);
}</lang>
}</syntaxhighlight>


=={{header|jq}}==
=={{header|jq}}==
Line 644: Line 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:
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:
<lang jq>def tick: .+1;</lang>
<syntaxhighlight lang="jq">def tick: .+1;</syntaxhighlight>
To model the robot's success and failure, we shall assume a sufficiently large array of 0/1 values is available.
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.
To avoid problems with modeling infinite time, we will pad the array with 1s if necessary.
<lang jq>def random: [0, 0, 0, 1, 0, 1, 1, 0];</lang>
<syntaxhighlight lang="jq">def random: [0, 0, 0, 1, 0, 1, 1, 0];</syntaxhighlight>


"step" returns true or false based on the current time (the input) and the value of "random":
"step" returns true or false based on the current time (the input) and the value of "random":
<lang jq>def step:
<syntaxhighlight lang="jq">def step:
random as $r
random as $r
| if . >= ($r|length) then true else ($r[.] == 1) end ;</lang>
| if . >= ($r|length) then true else ($r[.] == 1) end ;</syntaxhighlight>


We can now define step_up:
We can now define step_up:
<lang jq>def step_up:
<syntaxhighlight lang="jq">def step_up:
if step then tick
if step then tick
else tick | step_up | step_up
else tick | step_up | step_up
end;</lang>
end;</syntaxhighlight>
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:
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:
<lang jq>0 | step_up</lang>
<syntaxhighlight lang="jq">0 | step_up</syntaxhighlight>
{{out}}
{{out}}
<lang sh>$ jq -n -f stair-climbing_puzzle.jq
<syntaxhighlight lang="sh">$ jq -n -f stair-climbing_puzzle.jq
11</lang>
11</syntaxhighlight>
===Tail Call Optimization===
===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
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
function must be tail-recursive and have arity 0. This can be
achieved by providing [time, goal] as the input as follows:
achieved by providing [time, goal] as the input as follows:
<lang jq>def tco_step_up:
<syntaxhighlight lang="jq">def tco_step_up:
.[0] as $time | .[1] as $goal
.[0] as $time | .[1] as $goal
| if $goal == 0 then $time
| if $goal == 0 then $time
Line 674: Line 852:
if $time|step then $goal - 1 else $goal + 1 end
if $time|step then $goal - 1 else $goal + 1 end
| [ ($time|tick), .] | tco_step_up
| [ ($time|tick), .] | tco_step_up
end ;</lang>
end ;</syntaxhighlight>
The simulation can then be started as follows:
The simulation can then be started as follows:
<lang jq>[0,1] | tco_step_up</lang>
<syntaxhighlight lang="jq">[0,1] | tco_step_up</syntaxhighlight>


=={{header|Julia}}==
=={{header|Julia}}==
As specified, shorter and fewer numbers preferred.
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.
<lang julia>
<syntaxhighlight lang="julia">
step_up() = while !step() step_up() end
step_up() = while !step() step_up() end
</syntaxhighlight>
</lang>
Here is an example to test the code with a step that has a 1/3 failure rate:
Here is an example to test the code with a step that has a 1/3 failure rate:
<lang julia>
<syntaxhighlight lang="julia">
step() = (b = rand([true,true,false]); println(b); b)
step() = (b = rand([true,true,false]); println(b); b)
step_up()
step_up()
</syntaxhighlight>
</lang>
{{output}}
{{output}}
<pre>
<pre>
Line 700: Line 878:
true
true
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>
</pre>


=={{header|Liberty BASIC}}==
=={{header|Liberty BASIC}}==
<lang lb>'This demo will try to get the robot to step up
<syntaxhighlight lang="lb">'This demo will try to get the robot to step up
'Run it several times to see the differences; sometimes the robot falls
'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
'quite a ways before making it to the next step up, but sometimes he makes it
Line 723: Line 940:
Print "Robot fell down"
Print "Robot fell down"
End If
End If
End Function</lang>
End Function</syntaxhighlight>


=={{header|Logo}}==
=={{header|Logo}}==
Recursive.
Recursive.
<lang logo>to step.up
<syntaxhighlight lang="logo">to step.up
if not step [step.up step.up]
if not step [step.up step.up]
end</lang>
end</syntaxhighlight>
Constant space (fully tail-recursive).
Constant space (fully tail-recursive).
<lang logo>to step.up [:n 1]
<syntaxhighlight lang="logo">to step.up [:n 1]
if :n=0 [stop]
if :n=0 [stop]
(step.up ifelse step [:n-1] [:n+1])
(step.up ifelse step [:n-1] [:n+1])
end</lang>
end</syntaxhighlight>


=={{header|Lua}}==
=={{header|Lua}}==


<syntaxhighlight lang="lua">
<lang Lua>
function step_up()
function step_up()
while not step() do step_up() end
while not step() do step_up() end
end
end
</syntaxhighlight>
</lang>


=={{header|Mathematica}}==
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">StepUp[] := If[!Step[], StepUp[]; StepUp[]]</syntaxhighlight>

<lang Mathematica>StepUp[] := If[!Step[], StepUp[]; StepUp[]]</lang>


=={{header|MATLAB}}==
=={{header|MATLAB}}==
<lang MATLAB>function step_up()
<syntaxhighlight lang="matlab">function step_up()
while ~step()
while ~step()
step_up();
step_up();
end</lang>
end</syntaxhighlight>


=={{header|Nim}}==
=={{header|Nim}}==
One liner (yes it is possible in Nim).
<lang nim>proc stepUp1 =
<syntaxhighlight lang="nim">proc stepUp = (while not step(): stepUp())</syntaxhighlight>
var deficit = 1
while deficit > 0:
if step():
dec deficit
else:
inc deficit

proc stepUp2 =
while not step():
stepUp2()</lang>


=={{header|OCaml}}==
=={{header|OCaml}}==
<lang ocaml>let rec step_up() =
<syntaxhighlight lang="ocaml">let rec step_up() =
while not(step()) do
while not(step()) do
step_up()
step_up()
done
done
;;</lang>
;;</syntaxhighlight>


=={{header|Oz}}==
=={{header|Oz}}==
Recursive solution:
Recursive solution:
<lang oz>proc {StepUp}
<syntaxhighlight lang="oz">proc {StepUp}
if {Not {Step}} then
if {Not {Step}} then
{StepUp} %% make up for the fall
{StepUp} %% make up for the fall
{StepUp} %% repeat original attempt
{StepUp} %% repeat original attempt
end
end
end</lang>
end</syntaxhighlight>
Might lead to a stack overflow because the first call to <code>StepUp</code> is not in tail position.
Might lead to a stack overflow because the first call to <code>StepUp</code> is not in tail position.


Iterative solution:
Iterative solution:
<lang oz>proc {StepUp}
<syntaxhighlight lang="oz">proc {StepUp}
Level = {NewCell 0}
Level = {NewCell 0}
in
in
Line 794: Line 1,001:
end
end
end
end
</syntaxhighlight>
</lang>
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.
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|PARI/GP}}==
<lang parigp>step_up()=while(!step(),step_up())</lang>
<syntaxhighlight lang="parigp">step_up()=while(!step(),step_up())</syntaxhighlight>


=={{header|Pascal}}==
=={{header|Pascal}}==
Recursive solution:
Recursive solution:
<lang pascal>procedure stepUp;
<syntaxhighlight lang="pascal">procedure stepUp;
begin
begin
while not step do
while not step do
stepUp;
stepUp;
end;</lang>
end;</syntaxhighlight>


=={{header|Perl}}==
=={{header|Perl}}==
<lang perl>sub step_up { step_up until step; }</lang>
<syntaxhighlight lang="perl">sub step_up { step_up until step; }</syntaxhighlight>

=={{header|Perl 6}}==
<lang perl6>sub step_up { step_up until step; }</lang>


=={{header|Phix}}==
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>procedure step_up()
<span style="color: #008080;">procedure</span> <span style="color: #000000;">step_up</span><span style="color: #0000FF;">()</span>
while not step() do step_up() end while
<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>
end procedure</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<!--</syntaxhighlight>-->


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
<lang PicoLisp>(de stepUp ()
<syntaxhighlight lang="picolisp">(de stepUp ()
(until (step1) # ('step1', because 'step' is a system function)
(until (step1) # ('step1', because 'step' is a system function)
(stepUp) ) )</lang>
(stepUp) ) )</syntaxhighlight>


=={{header|PowerShell}}==
=={{header|PowerShell}}==
<lang powershell>function StepUp
<syntaxhighlight lang="powershell">function StepUp
{
{
If ( -not ( Step ) )
If ( -not ( Step ) )
Line 852: Line 1,058:
# Test
# Test
$VerbosePreference = 'Continue'
$VerbosePreference = 'Continue'
StepUp</lang>
StepUp</syntaxhighlight>
{{out}}
{{out}}
<pre>VERBOSE: Fell one step
<pre>VERBOSE: Fell one step
Line 865: Line 1,071:
VERBOSE: Up one step
VERBOSE: Up one step
VERBOSE: Up one step</pre>
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}}==
=={{header|PureBasic}}==
Iterative version using one variable.
Iterative version using one variable.
<lang PureBasic>Procedure step_up()
<syntaxhighlight lang="purebasic">Procedure step_up()
Protected i
Protected i
Repeat: If _step(): i + 1: Else: i - 1: EndIf: Until i = 1
Repeat: If _step(): i + 1: Else: i - 1: EndIf: Until i = 1
EndProcedure</lang>
EndProcedure</syntaxhighlight>
Recursive version. Stack may overflow as probability of a fall approaches or exceeds 50%.
Recursive version. Stack may overflow as probability of a fall approaches or exceeds 50%.
<lang PureBasic>Procedure step_up()
<syntaxhighlight lang="purebasic">Procedure step_up()
While Not _step()
While Not _step()
step_up()
step_up()
Wend
Wend
EndProcedure</lang>
EndProcedure</syntaxhighlight>
Demonstration program.
Demonstration program.
<lang PureBasic>Global level
<syntaxhighlight lang="purebasic">Global level


Procedure _step()
Procedure _step()
Line 908: Line 1,158:
Input()
Input()
CloseConsole()
CloseConsole()
EndIf</lang>
EndIf</syntaxhighlight>
Sample output:
Sample output:
<pre>Begin at level: 0
<pre>Begin at level: 0
Line 921: Line 1,171:


=== Iterative ===
=== Iterative ===
<lang python>def step_up1()
<syntaxhighlight lang="python">def step_up1():
"Straightforward implementation: keep track of how many level we
"""Straightforward implementation: keep track of how many level we
need to ascend, and stop when this count is zero."
need to ascend, and stop when this count is zero."""
deficit = 1
deficit = 1
while deficit > 0:
while deficit > 0:
Line 929: Line 1,179:
deficit -= 1
deficit -= 1
else:
else:
deficit += 1</lang>
deficit += 1</syntaxhighlight>


=== Recursive ===
=== Recursive ===
Line 935: Line 1,185:
''p'' approaches 0.5.
''p'' approaches 0.5.


<lang python>def step_up2():
<syntaxhighlight lang="python">def step_up2():
"No numbers."
"No numbers."
while not step():
while not step():
step_up2() # undo the fall</lang>
step_up2() # undo the fall</syntaxhighlight>

=={{header|Quackery}}==

<syntaxhighlight lang="quackery">[ step if done recurse again ] is step-up</syntaxhighlight>


=={{header|R}}==
=={{header|R}}==
Line 944: Line 1,198:
The step() function described would not be idiomatic R, since it would
The step() function described would not be idiomatic R, since it would
require using the global assignment operator to get the side effect.
require using the global assignment operator to get the side effect.
<lang R>step <- function() {
<syntaxhighlight lang="r">step <- function() {
success <- runif(1) > p
success <- runif(1) > p
## Requires that the "robot" is a variable named "level"
## Requires that the "robot" is a variable named "level"
level <<- level - 1 + (2 * success)
level <<- level - 1 + (2 * success)
success
success
}</lang>
}</syntaxhighlight>


===Recursive Solution===
===Recursive Solution===


<lang R>stepUp <- function() {
<syntaxhighlight lang="r">stepUp <- function() {
while(! step()) {
while(! step()) {
stepUp()
stepUp()
}
}
}</lang>
}</syntaxhighlight>


===Iterative Solution===
===Iterative Solution===


<lang R>stepUpIter <- function() {
<syntaxhighlight lang="r">stepUpIter <- function() {
i <- 0
i <- 0
while ( ! i) {
while ( ! i) {
i <- i - 1 + (2 * step())
i <- i - 1 + (2 * step())
}
}
}</lang>
}</syntaxhighlight>


Example output:
Example output:
Line 983: Line 1,237:


=={{header|Racket}}==
=={{header|Racket}}==
<lang Racket>#lang racket
<syntaxhighlight lang="racket">#lang racket
(define p 0.5001)
(define p 0.5001)
(define (step)
(define (step)
Line 993: Line 1,247:
(else (step-up (add1 n)))))
(else (step-up (add1 n)))))


(step-up 1)</lang>
(step-up 1)</syntaxhighlight>

=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>sub step_up { step_up until step; }</syntaxhighlight>


=={{header|REBOL}}==
=={{header|REBOL}}==
<lang REBOL>REBOL [
<syntaxhighlight lang="rebol">REBOL [
Title: "Stair Climber"
Title: "Stair Climber"
Date: 2009-12-14
Author: oofoe
URL: http://rosettacode.org/wiki/Stair_Climbing
URL: http://rosettacode.org/wiki/Stair_Climbing
]
]
Line 1,036: Line 1,292:
step_upt: does [if not step [step_upt step_upt]]
step_upt: does [if not step [step_upt step_upt]]


step_upt print "Success!"</lang>
step_upt print "Success!"</syntaxhighlight>


Output:
Output:
Line 1,051: Line 1,307:


=={{header|REXX}}==
=={{header|REXX}}==
<lang rexx>step_up: do while \step(); call step_up
<syntaxhighlight lang="rexx">step_up: do while \step(); call step_up
end
end
return</lang>
return</syntaxhighlight>


=={{header|Ring}}==
=={{header|Ring}}==
<lang ring>
<syntaxhighlight lang="ring">
stepup()
stepup()


Line 1,068: Line 1,324:
func stp
func stp
return 0
return 0
</syntaxhighlight>
</lang>

=={{header|Run BASIC}}==
<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
</lang>


=={{header|Ruby}}==
=={{header|Ruby}}==
<lang ruby>def step_up
<syntaxhighlight lang="ruby">def step_up
start_position = $position
start_position = $position
step until ($position == start_position + 1)
step until ($position == start_position + 1)
Line 1,108: Line 1,348:


$position = 0
$position = 0
step_up</lang>
step_up</syntaxhighlight>
Sample run:
Sample run:
<pre>$ ruby -d stair.climbing.rb
<pre>$ ruby -d stair.climbing.rb
Line 1,120: Line 1,360:
"rise (0)"
"rise (0)"
"rise (1)"</pre>
"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}}==
=={{header|SAS}}==


<syntaxhighlight lang="sas">
<lang SAS>
%macro step();
%macro step();
%sysfunc(round(%sysfunc(ranuni(0))))
%sysfunc(round(%sysfunc(ranuni(0))))
%mend step;
%mend step;
</syntaxhighlight>


===Recursive===
<syntaxhighlight lang="sas">
%macro step_up();
%macro step_up();


Line 1,140: Line 1,406:


%step_up;
%step_up;
</syntaxhighlight>
</lang>

===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:
Sample Output:
Line 1,160: Line 1,441:
Simple recursive solution:
Simple recursive solution:


<lang scala>def stepUp { while (! step) stepUp }</lang>
<syntaxhighlight lang="scala">def stepUp { while (! step) stepUp }</syntaxhighlight>


Non-recursive solution which almost gets away with not having named variables:
Non-recursive solution which almost gets away with not having named variables:


<lang scala>def stepUp {
<syntaxhighlight lang="scala">def stepUp {
def rec: List[Boolean] => Boolean = step :: (_: List[Boolean]) match {
def rec: List[Boolean] => Boolean = step :: (_: List[Boolean]) match {
case true :: Nil => true
case true :: Nil => true
Line 1,171: Line 1,452:
}
}
rec(Nil)
rec(Nil)
}</lang>
}</syntaxhighlight>


=={{header|Scheme}}==
=={{header|Scheme}}==
<lang scheme>(define (step-up n-steps)
<syntaxhighlight lang="scheme">(define (step-up n-steps)
(cond ((zero? n-steps) 'done)
(cond ((zero? n-steps) 'done)
((step) (step-up (- n-steps 1)))
((step) (step-up (- n-steps 1)))
(else (step-up (+ n-steps 1)))))</lang>
(else (step-up (+ n-steps 1)))))</syntaxhighlight>


=={{header|Seed7}}==
=={{header|Seed7}}==
<lang seed7>const proc: step_up is func
<syntaxhighlight lang="seed7">const proc: step_up is func
begin
begin
while not doStep do
while not doStep do
step_up;
step_up;
end while;
end while;
end func;</lang>
end func;</syntaxhighlight>


=={{header|Sidef}}==
=={{header|Sidef}}==
<lang ruby>func step_up() {
<syntaxhighlight lang="ruby">func step_up() {
while (!step()) {
while (!step()) {
step_up();
step_up();
}
}
}</lang>
}</syntaxhighlight>


=={{header|Smalltalk}}==
=={{header|Smalltalk}}==
Line 1,198: Line 1,479:


The following uses a block closure and the recursive solution which consumes stack until successful.
The following uses a block closure and the recursive solution which consumes stack until successful.
<lang smalltalk>Smalltalk at: #stepUp put: 0.
<syntaxhighlight lang="smalltalk">Smalltalk at: #stepUp put: 0.
stepUp := [ [ step value ] whileFalse: [ stepUp value ] ].</lang>
stepUp := [ [ step value ] whileFalse: [ stepUp value ] ].</syntaxhighlight>


=={{header|Standard ML}}==
=={{header|Standard ML}}==

<lang Standard ML>
<syntaxhighlight lang="sml">
(*
(*
* val step : unit -> bool
* val step : unit -> bool
Line 1,213: Line 1,495:
*)
*)
fun step_up() = step() orelse (step_up() andalso step_up())
fun step_up() = step() orelse (step_up() andalso step_up())
</syntaxhighlight>
</lang>

Alternate version:
<syntaxhighlight lang="sml">fun step() = true

fun step_up() = while step() = false do step_up()
</syntaxhighlight>


=={{header|Swift}}==
=={{header|Swift}}==
<lang swift>func step_up() {
<syntaxhighlight lang="swift">func step_up() {
while !step() {
while !step() {
step_up()
step_up()
}
}
}</lang>
}</syntaxhighlight>


The following uses a variable and is a bit longer, but avoids a possible stack overflow:
The following uses a variable and is a bit longer, but avoids a possible stack overflow:
<lang swift>func step_up() {
<syntaxhighlight lang="swift">func step_up() {
for var i = 0; i < 1; step()? ++i : --i { }
for var i = 0; i < 1; step()? ++i : --i { }
}</lang>
}</syntaxhighlight>


=={{header|Tcl}}==
=={{header|Tcl}}==
The setup (note that <code>level</code> and <code>steps</code> are not used elsewhere, but are great for testing…)
The setup (note that <code>level</code> and <code>steps</code> are not used elsewhere, but are great for testing…)
<lang tcl>set level 41
<syntaxhighlight lang="tcl">set level 41
set prob 0.5001
set prob 0.5001
proc step {} {
proc step {} {
Line 1,241: Line 1,529:
return 0
return 0
}
}
}</lang>
}</syntaxhighlight>
===Iterative Solution===
===Iterative Solution===
All iterative solutions require a counter variable, but at least we can avoid any literal digits...
All iterative solutions require a counter variable, but at least we can avoid any literal digits...
<lang tcl>proc step-up-iter {} {
<syntaxhighlight lang="tcl">proc step-up-iter {} {
for {incr d} {$d} {incr d} {
for {incr d} {$d} {incr d} {
incr d [set s -[step]]; incr d $s
incr d [set s -[step]]; incr d $s
}
}
}</lang>
}</syntaxhighlight>
===Recursive Solution===
===Recursive Solution===
This is the simplest possible recursive solution:
This is the simplest possible recursive solution:
<lang tcl>proc step-up-rec {} {
<syntaxhighlight lang="tcl">proc step-up-rec {} {
while {![step]} step-up-rec
while {![step]} step-up-rec
}</lang>
}</syntaxhighlight>


=={{header|TI-83 BASIC}}==
=={{header|TI-83 BASIC}}==
Line 1,259: Line 1,547:


<code>prgmSTEP</code>:
<code>prgmSTEP</code>:
<lang ti83b>If rand>.5:Then
<syntaxhighlight lang="ti83b">If rand>.5:Then
0→C
0→C
Disp "FALL"
Disp "FALL"
Line 1,275: Line 1,563:
End
End
If B=1
If B=1
Pause</lang>
Pause</syntaxhighlight>


<code>prgmSTEPUP</code>:
<code>prgmSTEPUP</code>:
<lang ti83b>prgmSTEP
<syntaxhighlight lang="ti83b">prgmSTEP
While C=0
While C=0
prgmSTEPUP
prgmSTEPUP
prgmSTEP
prgmSTEP
End</lang>
End</syntaxhighlight>

=={{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}}==
=={{header|XPL0}}==
<lang XPL0>proc Step_up; \Iterative version
<syntaxhighlight lang="xpl0">proc Step_up; \Iterative version
int I;
int I;
[I:= 0;
[I:= 0;
Line 1,294: Line 1,621:


proc Step_up; \Recursive version
proc Step_up; \Recursive version
while not Step do Step_up;</lang>
while not Step do Step_up;</syntaxhighlight>


=={{header|zkl}}==
=={{header|zkl}}==
Line 1,300: Line 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.
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.
<lang zkl>fcn step{ } // add code to return Bool
<syntaxhighlight lang="zkl">fcn step{ } // add code to return Bool
fcn stepUp{ while(not step()){ self.fcn() } }</lang>
fcn stepUp{ while(not step()){ self.fcn() } }</syntaxhighlight>
You could also use "stepUp" instead of self.fcn, self.fcn seems a little clearer and makes it easier to refactor.
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:
An example step function:
{{trans|D}}
{{trans|D}}
<lang zkl>var position=0;
<syntaxhighlight lang="zkl">var position=0;
fcn step(){ //-->0|1
fcn step(){ //-->0|1
r:=(0).random(2); // 0 or 1
r:=(0).random(2); // 0 or 1
Line 1,313: Line 1,640:
r
r
}
}
stepUp();</lang>
stepUp();</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>

Latest revision as of 14:41, 28 March 2024

Task
Stair-climbing puzzle
You are encouraged to solve this task according to the task description, using any language you may know.

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();
    }
}

11l

Translation of: Python

Iterative

F step_up1()
   V deficit = 1
   L deficit > 0
      I step()
         deficit--
      E
         deficit++

Recursive

F step_up2()
   L !step()
      step_up2()

ActionScript

Iterative

function stepUp()
{
	var i:int = 0;
	while(i < 1)
		if(step())i++;
		else i--;
}

Recursive

function stepUp()
{
	if(!step())
	{
		stepUp();
		stepUp();
	}
}

Ada

procedure Step_Up is
begin
   while not Step loop
      Step_Up;
   end loop;
end Step_Up;

The following is a test program simulating Step:

with Ada.Numerics.Discrete_Random;
with Ada.Text_IO;

procedure Scaffolding is
   package Try is new Ada.Numerics.Discrete_Random (Boolean);
   use Try;
   Dice  : Generator;
   Level : Integer := 0;

   function Step return Boolean is
   begin
      if Random (Dice) then
         Level := Level + 1;
         Ada.Text_IO.Put_Line ("Climbed up to" & Integer'Image (Level));
         return True;
      else
         Level := Level - 1;
         Ada.Text_IO.Put_Line ("Fell down to" & Integer'Image (Level));
         return False;
      end if;
   end Step;
   
   procedure Step_Up is
   begin
      while not Step loop
         Step_Up;
      end loop;
   end Step_Up;
begin
   Reset (Dice);
   Step_Up;
end Scaffolding;

Sample output:

Fell down to-1
Climbed up to 0
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

Aime

Translation of: C
void step_up(void)
{
    while (!step()) {
        step_up();
    }
}

ALGOL 68

Translation of: Ada
Works with: ALGOL 68 version Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386
   PROC step up = VOID:
   BEGIN
      WHILE NOT step DO
         step up
      OD
   END # step up #;

The following is a test program simulating step:

PROC scaffolding = VOID:
BEGIN
   INT level := 0;

   PROC step = BOOL:
   BEGIN
      IF random > 0.5 THEN
         level +:= 1;
         print(("Climbed up to",level, new line));
         TRUE
      ELSE
         level -:= 1;
         print(("Fell down to",level, new line));
         FALSE
      FI
   END # step #;

   PROC step up = VOID:
   BEGIN
      WHILE NOT step DO
         step up
      OD
   END # step up #;

   step up
END # scaffolding #;

scaffolding

Sample output:

Fell down to         -1
Fell down to         -2
Climbed up to         -1
Climbed up to         +0
Climbed up to         +1

Arturo

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
Output:
fall (-1)
fall (-2)
rise (-1)
rise (0)
fall (-1)
fall (-2)
rise (-1)
rise (0)
rise (1)

AutoHotkey

Recursive solution:

step_up()
{
    While !step()
       step_up()
}

AWK

function step_up() {
    while (!step()) { step_up() }
}

BASIC

Works with: QBasic
Works with: Visual Basic

For many (most?) BASICs, STEP 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.)

SUB stepup
    IF NOT step1 THEN stepup: stepup
END SUB

See also: BBC BASIC, Liberty BASIC, PureBasic, TI-83 BASIC

BBC BASIC

Recursive solution:

      DEF PROCstepup
      IF NOT FNstep PROCstepup : PROCstepup
      ENDPROC

C

void step_up(void)
{
    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:

void step_up(void)
{
    int i = 0;

    while (i < 1) {
        if (step()) {
            ++i;
        } else {
            --i;
        }
    }
}

C#

void step_up() {
    while (!step()) step_up();
}

C++

void step_up()
{
  while (!step()) step_up();
}

The following uses a variable and is a bit longer, but avoids a possible stack overflow:

void step_up()
{
  for (int i = 0; i < 1; step()? ++i : --i);
}

Clojure

First, some boilerplate.

;; the initial level
(def level (atom 41))

;; the probability of success
(def prob 0.5001)


(defn step
  []
  (let [success (< (rand) prob)]
    (swap! level (if success inc dec))
    success) )

Tail-recursive

The internal recursion uses a counter; see the function documentation.

(defn step-up1
  "Straightforward implementation: keep track of how many level we
   need to ascend, and stop when this count is zero."
  []
  (loop [deficit 1]
    (or (zero? deficit)
	(recur (if (step) (dec deficit)
		   (inc deficit)))) ) )

Recursive

This satisfies Chung-chieh's challenge to avoid using numbers. Might blow the stack as p approaches 0.5.

(defn step-up2
  "Non-tail-recursive. No numbers."
  []
  (if (not (step))
    (do (step-up2) ;; undo the fall
	(step-up2) ;; try again
	)
    true))

Common Lisp

(defun step-up ()
  (unless (step) (step-up) (step-up)))

D

The recursive version (note that "step_up" is equivalent to "step_up()" in D):

void step_up()
{
    while(!step)
        step_up;
}

The non-recursive version, using 1 variable:

void step_up_nr()
{
    for(uint i = 0; i < 1; step ? ++i : --i) {};
}

Test program:

import std.stdio;
import std.random;

int position;
bool step()
{
    bool r = rand() > (uint.max / 2);
    if(r)
        writefln("Climbed up to %d", ++position);
    else
        writefln("Fell down to %d", --position);
    return r;
}

void step_up()
{
    while(!step)
        step_up;
}

void main()
{
    rand_seed(0, 0); // to make it somewhat repeatable
    step_up;
}

Sample output:

Fell down to -1
Fell down to -2
Fell down to -3
Fell down to -4
Climbed up to -3
Fell down to -4
Climbed up to -3
Climbed up to -2
Climbed up to -1
Climbed up to 0
Climbed up to 1

Delphi

Works with: Delphi version 6.0

Recursive version using no variables other than the Boolean returned by "Step"

{Recursive version}

procedure Step_Up;
begin
while not Step do Step_Up;
end;

Iterative versions using one variable.

{Iterative version}

procedure Step_Up;
var I: integer;
begin
while I<1 do
if Step then Inc(I) else Dec(I);
end;

Functional example program

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;
Output:
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.

E

This is at first a very direct

Translation of: Clojure

The problem framework:

var level := 41
var prob := 0.5001

def step() {
    def success := entropy.nextDouble() < prob
    level += success.pick(1, -1)
    return success
}

Counting solution:

def stepUpCounting() {
    var deficit := 1
    while (deficit > 0) {
        deficit += step().pick(-1, 1)
    }
}

Ordinary recursive solution:

def stepUpRecur() { 
    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.

def stepUpEventualRecur() {
    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):

def stepUpEventual() {
    # This general structure (tail-recursive def{if{when}}) is rather common
    # and probably ought to be defined in a library.
  
    def loop(deficit) {
        if (deficit > 0) {
            return when (def success := step()) -> {
                loop(deficit + success.pick(-1, 1))
            }
        }
    }
    return loop(1)
}

EchoLisp

(define (step-up) (while (not (step)) (step-up)))
;; checking this is tail-recusive :
step-up
    (#λ null (#while (#not (step)) (#lambda-tail-call)))

;; Experimentation (not part of the task)
;; How much step calls to climb  1000 stairs ?
;; success is the robot success probability
(define (step) 
 (set! STEPS (1+ STEPS)) ;; count
 (< (random) SUCCESS)) ;; ->#t or #f

(define (climb stairs)
	(when (> stairs 0)  (step-up) (climb (1- stairs))))
	
(define (task  (stairs 1000))
	(for ((success (in-range 1 0 -5/100)))
	(set! SUCCESS success)
	(set! STEPS 0)
	(climb stairs)
	(writeln 'stairs stairs 'probability success 'steps STEPS)))
Output:
stairs     1000     probability     1         steps     1000    
stairs     1000     probability     19/20     steps     1062    
stairs     1000     probability     9/10      steps     1115    
stairs     1000     probability     17/20     steps     1207    
stairs     1000     probability     4/5       steps     1254    
stairs     1000     probability     3/4       steps     1305    
stairs     1000     probability     7/10      steps     1440    
stairs     1000     probability     13/20     steps     1542    
stairs     1000     probability     3/5       steps     1641    
stairs     1000     probability     11/20     steps     1865    
stairs     1000     probability     1/2       steps     2045    
stairs     1000     probability     9/20      steps     2177    
stairs     1000     probability     2/5       steps     2615    
stairs     1000     probability     7/20      steps     2769    
stairs     1000     probability     3/10      steps     3312    
stairs     1000     probability     1/4       steps     3963    
stairs     1000     probability     1/5       steps     5054    
stairs     1000     probability     3/20      steps     6573    
stairs     1000     probability     1/10      steps     9840    
stairs     1000     probability     1/20      steps     18689    

;; looks as if steps = stairs / success-probability

Elixir

Translation of: Erlang
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

Erlang

-module(stair).
-compile(export_all).

step() ->
    1 == random:uniform(2).

step_up(true) ->
    ok;
step_up(false) ->   
    step_up(step()),
    step_up(step()).

step_up() ->
    step_up(step()).

Euphoria

procedure step_up()
    if not step() then
        step_up()
        step_up()
    end if
end procedure

F#

let rec step_up() = while not(step()) do step_up()

Factor

: step-up ( -- ) step [ step-up step-up ] unless ;

Forth

Recursive. May exceed return stack unless compiler optimizes tail calls.

: step-up   begin step 0= while recurse repeat ;

Counting. Avoids using a named variable.

: step-up   -1 begin step if 1+ else 1- then ?dup 0= until ;

Fortran

Translation of: C++
Works with: Fortran version 90 and later
module StairRobot
  implicit none

contains

  logical function step()
    ! try to climb up and return true or false
    step = .true.     ! to avoid compiler warning
  end function step

  recursive subroutine step_up_rec
    do while ( .not. step() )
       call step_up_rec
    end do
  end subroutine step_up_rec

  subroutine step_up_iter
    integer :: i = 0
    do while ( i < 1 )
       if ( step() ) then
          i = i + 1
       else
          i = i - 1
       end if
    end do
  end subroutine step_up_iter

end module StairRobot

FreeBASIC

Since step is a statement modifier in FreeBASIC, we will use step_

Iterative version using one variable.

Sub step_up()
    Dim As Integer i
    Do
        If step_() Then
            i += 1
        Else
            i -= 1
        End If
    Loop Until i = 1
End Sub

Recursive version.

Sub step_up()
    While Not step_()
        step_up()
    Wend
End Sub

Demonstration program.

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


Go

38 bytes, no variables, no numbers.

func step_up(){for !step(){step_up()}}

Groovy

class Stair_climbing{
static void main(String[] args){
}
static def step_up(){
    while not step(){
            step_up();
            }
}

}

Haskell

In Haskell, stateful computation is only allowed in a monad. Then suppose we have a monad Robot with an action step :: Robot Bool. We can implement stepUp like this:

stepUp :: Robot ()
stepUp = untilM step stepUp

untilM :: Monad m => m Bool -> m () -> m ()
untilM test action = do
    result <- test
    if result then return () else action >> untilM test action

Here's an example implementation of Robot and step, as well as a main with which to test stepUp.

import Control.Monad.State
import System.Random (StdGen, getStdGen, random)

type Robot = State (Int, StdGen)

step :: Robot Bool
step = do
    (i, g) <- get
    let (succeeded, g') = random g
    put (if succeeded then i + 1 else i - 1, g')
    return succeeded

startingPos = 20 :: Int

main = do
    g <- getStdGen
    putStrLn $ "The robot is at step #" ++ show startingPos ++ "."
    let (endingPos, _) = execState stepUp (startingPos, g)
    putStrLn $ "The robot is at step #" ++ show endingPos ++ "."

Icon and Unicon

Icon (and Unicon) don't have boolean values. Instead expressions (all expressions) either succeed or they fail. Control structures respond to this success or failure. Assuming that step() is implemented in Icon (or Unicon) and fails only when the implementation in another language returns false, then:

procedure step_up()
    return step() | (step_up(),step_up())
end

You can subtract a few more characters (and multiply the difficulty of understanding) with:

procedure step_up()
    (|not step(), step_up())
end

J

Solution (Tacit):

step         =: 0.6 > ?@0:
attemptClimb =: [: <:`>:@.step 0:
isNotUpOne   =: -.@(+/@])

step_up=: (] , attemptClimb)^:isNotUpOne^:_

Note that 0: 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, step is presumed to pre-exist in the task description. Therefore the above solution for step_up 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. step and attemptClimb) to serve as verbs which "do not take an argument".

Solution (Explicit):

step_upX=: monad define           NB. iterative
  while. -. +/y do. y=. y , _1 1 {~ step 0 end.
)

step_upR=: monad define           NB. recursive (stack overflow possible!)   
   while. -. step'' do. step_upR'' end.
)

Example usage:

   step_up ''            NB. output is sequence of falls & climbs required to climb one step.
_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:

keepTrying=: (, {: - _1 ^ step)^:({. >: {:)^:_

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:

   keepTrying 2
2 1 0 1 2 3
   keepTrying 3
3 2 3 2 3 2 3 4
   keepTrying 4
4 5

Java

Translation of: C++
public void stepUp() {
  while (!step()) stepUp();
}

The following uses a variable and is a bit longer, but avoids a possible stack overflow:

public void stepUp(){
  for (int i = 0; i < 1; step() ? ++i : --i);
}

jq

Works with: jq version 1.4

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:

def tick: .+1;

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.

def random: [0, 0, 0, 1, 0, 1, 1, 0];

"step" returns true or false based on the current time (the input) and the value of "random":

def step:
  random as $r
  | if . >= ($r|length) then true else ($r[.] == 1) end ;

We can now define step_up:

def 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:

0 | step_up
Output:
$ jq -n -f stair-climbing_puzzle.jq
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:

def tco_step_up:
  .[0] as $time | .[1] as $goal
  | if $goal == 0 then $time
    else
       if $time|step then $goal - 1 else $goal + 1 end
       | [ ($time|tick), .] | tco_step_up
    end ;

The simulation can then be started as follows:

[0,1] | tco_step_up

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.

step_up() = while !step() step_up() end

Here is an example to test the code with a step that has a 1/3 failure rate:

step() = (b = rand([true,true,false]); println(b); b)
step_up()
Output:
julia>  step_up()
true

julia>  step_up()
true

julia>  step_up()
false
true
true

Kotlin

Translation of: D
// 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()
}
Output:
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

Liberty BASIC

'This demo will try to get the robot to step up
'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
'on the first try

result = Stepp.Up()

Function Stepp.Up()
    While Not(Stepp())
        result = Stepp.Up()
    Wend
End Function

Function Stepp()
    Stepp = Int((Rnd(1) * 2))
    If Stepp Then
        Print "Robot stepped up"
    Else
        Print "Robot fell down"
    End If
End Function

Recursive.

to step.up
  if not step [step.up step.up]
end

Constant space (fully tail-recursive).

to step.up [:n 1]
  if :n=0 [stop]
  (step.up ifelse step [:n-1] [:n+1])
end

Lua

function step_up()
    while not step() do step_up() end
end

Mathematica/Wolfram Language

StepUp[] := If[!Step[], StepUp[]; StepUp[]]

MATLAB

function step_up()
    while ~step()
        step_up();
    end

Nim

One liner (yes it is possible in Nim).

proc stepUp = (while not step(): stepUp())

OCaml

let rec step_up() =
  while not(step()) do
    step_up()
  done
;;

Oz

Recursive solution:

proc {StepUp}
   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 StepUp is not in tail position.

Iterative solution:

proc {StepUp}
   Level = {NewCell 0}
in
   for until:@Level == 1 do
      if {Step} then Level := @Level + 1
      else Level := @Level - 1
      end
   end
end

Oz has arbitrary large integers. So if the robot is very unlucky, the contents of the Level 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.

PARI/GP

step_up()=while(!step(),step_up())

Pascal

Recursive solution:

procedure stepUp;
begin
  while not step do
    stepUp;
end;

Perl

sub step_up { step_up until step; }

Phix

procedure step_up()
    while not step() do step_up() end while
end procedure

PicoLisp

(de stepUp ()
   (until (step1)  # ('step1', because 'step' is a system function)
      (stepUp) ) )

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
Output:
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

Prolog

The robot code is very short

step_up :- \+ step, step_up, step_up.

The test program keeps track of the level in a dynamic predicate.

:- 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.
Output:
?- 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.

?-

PureBasic

Iterative version using one variable.

Procedure step_up()
  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%.

Procedure step_up()
  While Not _step()
    step_up()
  Wend 
EndProcedure

Demonstration program.

Global level

Procedure _step()
  If Random(1) ;equal chance of stepping up or falling down
    level + 1
    PrintN("Climbed up to " + Str(level))
    ProcedureReturn #True
  Else
    level - 1
    PrintN("Fell down to " + Str(level))
    ProcedureReturn #False
  EndIf 
EndProcedure
  
;recursive
Procedure step_up()
  While Not _step()
    step_up()
  Wend 
EndProcedure

If OpenConsole()
  PrintN("Begin at level: " + Str(level))
  step_up()
  PrintN("*** Now at level: " + Str(level))
   
  Print(#CRLF$ + #CRLF$ + "Press ENTER to exit")
  Input()
  CloseConsole()
EndIf

Sample output:

Begin at level: 0
Fell down to -1
Climbed up to 0
Fell down to -1
Climbed up to 0
Climbed up to 1
*** Now at level: 1

Python

Iterative

def step_up1():
  """Straightforward implementation: keep track of how many level we
     need to ascend, and stop when this count is zero."""
  deficit = 1
  while deficit > 0:
    if step():
      deficit -= 1
    else:
      deficit += 1

Recursive

This satisfies Chung-chieh's challenge to avoid using numbers. Might blow the stack as p approaches 0.5.

def step_up2():
  "No numbers."
  while not step():
    step_up2() # undo the fall

Quackery

[ step if done recurse again ] is step-up

R

The step() function described would not be idiomatic R, since it would require using the global assignment operator to get the side effect.

step <- function() {
    success <- runif(1) > p
    ## Requires that the "robot" is a variable named "level"
    level <<- level - 1 + (2 * success)
    success
}

Recursive Solution

stepUp <- function() {
    while(! step()) {
        stepUp()
    }
}

Iterative Solution

stepUpIter <- function() {
    i <- 0
    while ( ! i) {
        i <- i - 1 + (2 * step())
    }
}

Example output:

> p <- 0.25
> level <- 1
> print(level)
[1] 1
> stepUp()
> print(level)
[1] 2
> stepUpIter()
> print(level)
[1] 3

Racket

#lang racket
(define p 0.5001)
(define (step)
  (> p (random)))

(define (step-up n)
  (cond ((zero? n) 'done)
        ((step) (step-up (sub1 n)))
        (else (step-up (add1 n)))))

(step-up 1)

Raku

(formerly Perl 6)

sub step_up { step_up until step; }

REBOL

REBOL [
    Title: "Stair Climber"
    URL: http://rosettacode.org/wiki/Stair_Climbing
]

random/seed now

step: does [random/only reduce [yes no]]

; Iterative solution with symbol stack. No numbers, draws a nifty
; diagram of number of steps to go. This is intended more to
; demonstrate a correct solution:

step_up: func [/steps s] [
	either not steps [
		print "Starting up..."
		step_up/steps copy [|]
	][
		while [not empty? s][
			print ["    Steps left:" s]
			either step [remove s][append s '|]
		]
	]
]

step_up  print ["Success!" crlf]

; Recursive solution. No numbers, no variables. "R" means a recover
; step, "+" means a step up.

step_upr: does [if not step [prin "R " step_upr  prin "+ " step_upr]]

step_upr  print ["Success!" crlf]

; Small recursive solution, no monitoring:

step_upt: does [if not step [step_upt step_upt]]

step_upt  print "Success!"

Output:

Starting up...
    Steps left: |
    Steps left: | |
    Steps left: |
Success!

R R + R R R R R R R + + R + + + + + + R + R R + R + R + R + + + Success!

Success!

REXX

step_up:           do  while \step();   call step_up
                   end
          return

Ring

stepup()

func stepup
     n = 0
     while n < 1
           if stp() n=n+1 else n= n-1 ok
           see n + nl
     end

func stp
     return 0

Ruby

def step_up
  start_position = $position
  step until ($position == start_position + 1)
end

# assumptions about the step function:
# - it maintains the current position of the robot "as a side effect"
# - the robot is equally likely to step back as to step up
def step
  if rand < 0.5
    $position -= 1
    p "fall (#$position)" if $DEBUG
    return false
  else
    $position += 1
    p "rise (#$position)" if $DEBUG
    return true
  end
end

$position = 0
step_up

Sample run:

$ ruby -d stair.climbing.rb
"fall (-1)"
"rise (0)"
"fall (-1)"
"rise (0)"
"fall (-1)"
"fall (-2)"
"rise (-1)"
"rise (0)"
"rise (1)"

Run BASIC

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

Rust

fn step_up() {
	while !step() {
		step_up();
	}
}

SAS

%macro step();
	%sysfunc(round(%sysfunc(ranuni(0))))
	%mend step;

Recursive

%macro step_up();

	%if not %step %then %do;
		%put Step Down;
		%step_up;
		%step_up;
		%end;
	%else %put Step Up;

	%mend step_up;

%step_up;

Iterative

%macro step_up();

	%do %while (not %step);
		%put Step Down;
		%step_up;
		%end;
	%put Step Up;

	%mend step_up;


Sample Output:

Step Down
Step Down
Step Down
Step Up
Step Down
Step Down
Step Up
Step Up
Step Up
Step Up
Step Up

Scala

Simple recursive solution:

def stepUp { while (! step) stepUp }

Non-recursive solution which almost gets away with not having named variables:

def stepUp {
  def rec: List[Boolean] => Boolean = step :: (_: List[Boolean]) match {
    case true :: Nil => true
    case true :: false :: rest => rec(rest)
    case other => rec(other)
  }
  rec(Nil)
}

Scheme

(define (step-up n-steps)
  (cond ((zero? n-steps) 'done)
        ((step) (step-up (- n-steps 1)))
        (else (step-up (+ n-steps 1)))))

Seed7

const proc: step_up is func
  begin
    while not doStep do
      step_up;
    end while;
  end func;

Sidef

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

Smalltalk

Works with: GNU Smalltalk

The following uses a block closure and the recursive solution which consumes stack until successful.

Smalltalk at: #stepUp put: 0.
stepUp := [ [ step value ] whileFalse: [ stepUp value ] ].

Standard ML

(*
 * val step : unit -> bool
 * This is a stub for a function which returns true if successfully climb a step or false otherwise.
 *) 
fun step() = true

(*
 * val step_up : unit -> bool
 *)
fun step_up() = step() orelse (step_up() andalso step_up())

Alternate version:

fun step() = true

fun step_up() = while step() = false do step_up()

Swift

func step_up() {
  while !step() {
    step_up()
  }
}

The following uses a variable and is a bit longer, but avoids a possible stack overflow:

func step_up() {
  for var i = 0; i < 1; step()? ++i : --i { }
}

Tcl

The setup (note that level and steps are not used elsewhere, but are great for testing…)

set level 41
set prob 0.5001
proc step {} {
    global level prob steps
    incr steps
    if {rand() < $prob} {
	incr level 1
	return 1
    } else {
	incr level -1
	return 0
    }
}

Iterative Solution

All iterative solutions require a counter variable, but at least we can avoid any literal digits...

proc step-up-iter {} {
    for {incr d} {$d} {incr d} {
	incr d [set s -[step]]; incr d $s
    }
}

Recursive Solution

This is the simplest possible recursive solution:

proc step-up-rec {} {
    while {![step]} step-up-rec
}

TI-83 BASIC

TI-83 BASIC doesn't have functions (only subroutines), so a variable must be used as the return value for prgmSTEP. Set A to 1 before calling to display the offset from the stair it was called from (store in D). Set B to 1 to pause after each attempt. C is the return variable for prgmSTEP. D is the stair it is on (only used for display, and not used if A isn't 1).

prgmSTEP:

If rand>.5:Then
0→C
Disp "FALL"
If A=1:Then
D-1→D
Disp D
End
Else
1→C
Disp "CLIMB"
If A=1:Then
D+1→D
Disp D
End
End
If B=1
Pause

prgmSTEPUP:

prgmSTEP
While C=0
prgmSTEPUP
prgmSTEP
End

Wren

Translation of: Kotlin
Library: Wren-fmt
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()
Output:
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

XPL0

proc Step_up;           \Iterative version
int I;
[I:= 0;
while I<1 do
        if Step then I:= I+1
        else I:= I-1;
];

proc Step_up;           \Recursive version
while not Step do Step_up;

zkl

According to Leon P Smith in the referenced LTU thread:

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 step{  } // add code to return Bool
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:

Translation of: D
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();
Output:
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