Long stairs: Difference between revisions

added RPL
(added RPL)
 
(26 intermediate revisions by 19 users not shown)
Line 8:
 
If you escaped, run 10,000 tests and print the average time taken and the average final length of the staircase.
 
=={{header|11l}}==
{{trans|C}}
 
<syntaxhighlight lang="11l">V secs_tot = 0
V steps_tot = 0
print(‘Seconds steps behind steps ahead’)
 
L(trial) 1..10000
V sbeh = 0
V slen = 100
V secs = 0
L sbeh < slen
sbeh++
L 5
I random:(slen) < sbeh
sbeh++
slen++
 
secs++
I trial == 1 & secs C 600..609
print(‘#. #. #.’.format(secs, sbeh, slen - sbeh))
 
secs_tot += secs
steps_tot += slen
 
print(‘Average secs taken: #.6’.format(secs_tot / 10000.0))
print(‘Average final length of staircase: #.6’.format(steps_tot / 10000.0))</syntaxhighlight>
 
{{out}}
<pre>
Seconds steps behind steps ahead
600 1906 1194
601 1910 1195
602 1913 1197
603 1918 1197
604 1923 1197
605 1929 1196
606 1934 1196
607 1936 1199
608 1940 1200
609 1943 1202
Average secs taken: 2920.077500
Average final length of staircase: 14700.387500
</pre>
 
=={{header|AppleScript}}==
<syntaxhighlight lang="applescript">use AppleScript version "2.5" -- OS X 10.11 (El Capitan) or later.
use framework "Foundation"
use framework "GameplayKit" -- For the random number generator (faster than AppleScript's).
 
on longStairs()
set output to {"Sample from first run:", "Seconds Steps behind Steps ahead"}
set RNG to current application's class "GKMersenneTwisterRandomSource"'s new()
set {runCount, totalTime, totalLength, firstRun, padding} to {10000, 0, 0, true, " "}
repeat runCount times
set t to 0
set stepsBehind to 0
set stepsAhead to 100
repeat until (stepsAhead = 0)
repeat 5 times
if ((RNG's nextIntWithUpperBound:(stepsBehind + stepsAhead)) > stepsBehind) then
set stepsAhead to stepsAhead + 1
else
set stepsBehind to stepsBehind + 1
end if
end repeat
set t to t + 1
set stepsBehind to stepsBehind + 1
set stepsAhead to stepsAhead - 1
if ((firstRun) and (t < 610) and (t > 599)) then ¬
set end of output to text -5 thru -1 of (padding & t) & ¬
text -13 thru -1 of (padding & stepsBehind) & ¬
text -15 thru -1 of (padding & stepsAhead)
end repeat
set totalTime to totalTime + t
set totalLength to totalLength + stepsBehind
set firstRun to false
end repeat
set {avTime, avLength} to {totalTime / runCount, totalLength / runCount}
set end of output to "Average time taken over " & intToText(runCount, ",") & " runs: " & ¬
(avTime div minutes) & " minutes " & (avTime mod minutes) & " seconds"
set end of output to "Average final staircase length: " & intToText(avLength div 1, ",") & ¬
"." & text 3 thru -1 of ((avLength mod 1) as text) & " steps"
return join(output, linefeed)
end longStairs
 
on intToText(int, separator)
set groups to {}
repeat while (int > 999)
set groups's beginning to ((1000 + (int mod 1000 as integer)) as text)'s text 2 thru 4
set int to int div 1000
end repeat
set groups's beginning to int
return join(groups, separator)
end intToText
 
on join(lst, delim)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delim
set txt to lst as text
set AppleScript's text item delimiters to astid
return txt
end join
 
longStairs()</syntaxhighlight>
 
{{output}}
<syntaxhighlight lang="applescript">"Sample from first run:
Seconds Steps behind Steps ahead
600 2276 824
601 2278 827
602 2282 828
603 2287 828
604 2292 828
605 2296 829
606 2299 831
607 2304 831
608 2310 830
609 2315 830
Average time taken over 10,000 runs: 48 minutes 39.0985 seconds
Average final staircase length: 14,695.4925 steps"</syntaxhighlight>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">result := "Sec steps behind steps ahead"
x := longStairs(609)
for i, s in x.4
result .= "`n" i+599 "`t" s "`t`t" x.2 - s
tests := 10000
loop % tests
{
x := longStairs()
totSteps += x.1
totSec += x.3
}
MsgBox, 262144, , % result .= "`n`nAfter " tests " tests:`nAverage time taken = " totSec/tests " Sec"
. "`nAverage Stair length = " totSteps/tests " steps"
return
 
longStairs(t:=0){
Stairs := [], last10Steps := [], s := 0
loop 100
Stairs[A_Index] := 0
loop
{
Stairs[++s] := "S" ; take a step forward
if (last10Steps.count()>=10)
last10Steps.RemoveAt(1)
last10Steps.push(s)
loop 5 ; add 5 steps to stairs
{
Random, stp, 1, % Stairs.Count()
Stairs.InsertAt(stp, "x")
s += s > stp ? 1 : 0
}
escT := s = Stairs.Count() ? A_Index : 0
if (A_Index = t || escT) ; reached time limit or Escaped
break
}
return [s, Stairs.Count(), escT, last10Steps]
}</syntaxhighlight>
{{out}}
<pre>Sec steps behind steps ahead
600 1991 1154
601 1993 1152
602 1997 1148
603 2001 1144
604 2004 1141
605 2008 1137
606 2010 1135
607 2013 1132
608 2016 1129
609 2018 1127
 
After 10000 tests:
Average time taken = 3063.260000 Sec
Average Stair length = 15416.300000 steps</pre>
 
=={{header|BASIC}}==
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vbnet">steps_behind = 0
stairs_length = 100
seconds_tot = 0
steps_tot = 0
print "Seconds steps behind steps ahead"
for trial = 1 to 10000 #We'll have the runner try this 10000 times
steps_behind = 0 #runner starts at the bottom
seconds = 0 #reset time taken
stairs_length = 100 #Staircase has 100 steps
while steps_behind < stairs_length #if the runner hasn#t reached the top
steps_behind += 1 #go up one step
for j = 1 to 5 #The evil wizard conjures another five steps
if int(rand*stairs_length) < steps_behind then steps_behind += 1
#there#s a chance that a new step will be behind you
stairs_length += 1 #but either way the staircase is one step longer
next j
seconds += 1 #that all took one second
if trial = 1 and seconds > 599 and seconds < 610 then print seconds, steps_behind, stairs_length - steps_behind
#for the first attempt, see how the runner is doing after ten minutes
end while
seconds_tot += seconds #if the runner escaped, track the time taken and the length of the stairs
steps_tot += stairs_length
next trial
 
print "Average time taken: "; seconds_tot/10000; " seconds."
print "Average final staircase length: "; steps_tot/10000; " steps."
#if you noticed that last number is about 100*exp(5), that#s no coincidence</syntaxhighlight>
{{out}}
<pre>Similar as FreeBASIC entry.</pre>
 
==={{header|FreeBASIC}}===
<syntaxhighlight lang="vbnet">
randomize timer
dim as uinteger steps_behind = 0, stairs_length = 100, seconds, j
dim as uinteger seconds_tot, steps_tot
print "Seconds", "steps behind", "steps ahead"
for trial as uinteger = 1 to 10000 'We'll have the runner try this 10000 times
steps_behind = 0 'runner starts at the bottom
seconds = 0 'reset time taken
stairs_length = 100 'Staircase has 100 steps
while steps_behind < stairs_length 'if the runner hasn't reached the top
steps_behind += 1 'go up one step
for j = 1 to 5 'The evil wizard conjures another five steps
if int(rnd*stairs_length) < steps_behind then steps_behind += 1
'there's a chance that a new step will be behind you
stairs_length += 1 'but either way the staircase is one step longer
next j
seconds += 1 'that all took one second
if trial = 1 and seconds >599 and seconds < 610 then print seconds, steps_behind, stairs_length - steps_behind
'for the first attempt, see how the runner is doing after ten minutes
wend
seconds_tot += seconds 'if the runner escaped, track the time taken and the length of the stairs
steps_tot += stairs_length
next trial
 
print "Average time taken: ";seconds_tot/10000; " seconds."
print "Average final staircase length: ";steps_tot/10000; " steps."
'if you noticed that last number is about 100*exp(5), that's no coincidence</syntaxhighlight>
{{out}}<pre>
Seconds steps behind steps ahead
600 2032 1068
601 2038 1067
602 2042 1068
603 2045 1070
604 2048 1072
605 2053 1072
606 2055 1075
607 2060 1075
608 2064 1076
609 2068 1077
Average time taken: 2921.9457 seconds.
Average final staircase length: 14709.7285 steps.
</pre>
 
==={{header|Gambas}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vbnet">Public Sub Main()
 
Randomize
Dim steps_behind As Integer = 0, stairs_length As Integer = 100, seconds As Integer
Dim seconds_tot As Integer, steps_tot As Integer, j As Integer
Print "Seconds", "steps behind", "steps ahead"
For trial As Integer = 1 To 10000 'We'll have the runner try this 10000 times
steps_behind = 0 'runner starts at the bottom
seconds = 0 'reset time taken
stairs_length = 100 'Staircase has 100 steps
While steps_behind < stairs_length 'if the runner hasn't reached the top
steps_behind += 1 'go up one step
For j = 1 To 5 'The evil wizard conjures another five steps
If Int(Rnd * stairs_length) < steps_behind Then steps_behind += 1
'there's a chance that a new step will be behind you
stairs_length += 1 'but either way the staircase is one step longer
Next
seconds += 1 'that all took one second
If trial = 1 And seconds > 599 And seconds < 610 Then Print seconds, steps_behind, Chr$(9); stairs_length - steps_behind
'for the first attempt, see how the runner is doing after ten minutes
Wend
seconds_tot += seconds 'if the runner escaped, track the time taken and the length of the stairs
steps_tot += stairs_length
Next
Print "Average time taken: "; seconds_tot / 10000; " seconds."
Print "Average final staircase length: "; steps_tot / 10000; " steps."
'if you noticed that last number is about 100*exp(5), that's no coincidence
End </syntaxhighlight>
{{out}}
<pre>Similar as FreeBASIC entry.</pre>
 
==={{header|GW-BASIC}}===
<syntaxhighlight lang="qbasic">
10 RANDOMIZE TIMER
20 TIMET = 0 : STEPST = 0
30 FOR TRIAL = 1 TO 10000
40 TIME = 0
50 SBEH = 0
60 SLEN = 100
70 SBEH = SBEH + 1
80 IF SBEH >= SLEN THEN GOTO 160
90 FOR WIZ = 1 TO 5
100 IF INT(RND*SLEN)<SBEH THEN SBEH = SBEH + 1
110 SLEN = SLEN + 1
120 NEXT WIZ
130 TIME = TIME + 1
140 IF TRIAL = 1 AND 599<TIME AND TIME <610 THEN PRINT TIME, SBEH, SLEN-SBEH
150 GOTO 70
160 TIMET = TIMET+TIME+1
170 STEPST = STEPST + SLEN
180 NEXT TRIAL
190 PRINT TIMET/10000
200 PRINT STEPST/10000</syntaxhighlight>
 
==={{header|PureBasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="purebasic">OpenConsole()
Define.i steps_behind = 0, stairs_length = 100, seconds, j
Define.i seconds_tot, steps_tot
PrintN("Seconds" + #TAB$ + "steps behind" + #TAB$ + "steps ahead")
For trial.i = 1 To 10000 ;We'll have the runner try this 10000 times
steps_behind = 0 ;runner starts at the bottom
seconds = 0 ;reset time taken
stairs_length = 100 ;Staircase has 100 steps
While steps_behind < stairs_length ;if the runner hasn;t reached the top
steps_behind + 1 ;go up one step
For j = 1 To 5 ;The evil wizard conjures another five steps
If Int(Random(1) * stairs_length) < steps_behind:
steps_behind + 1
EndIf
;there;s a chance that a new step will be behind you
stairs_length + 1 ;but either way the staircase is one step longer
Next j
seconds + 1 ;that all took one second
If (trial = 1) And (seconds > 599) And (seconds < 610):
PrintN(Str(seconds) + #TAB$ + #TAB$ + Str(steps_behind) + #TAB$ + Str(stairs_length - steps_behind))
;for the first attempt, see how the runner is doing after ten minutes
EndIf
Wend
seconds_tot + seconds ;if the runner escaped, track the time taken and the length of the stairs
steps_tot + stairs_length
Next trial
 
PrintN("Average time taken: " + Str(seconds_tot/10000) + " seconds.")
PrintN("Average final staircase length: " + Str(steps_tot/10000) + " steps.")
;if you noticed that last number is about 100*exp(5), that;s no coincidence
 
PrintN(#CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()</syntaxhighlight>
{{out}}
<pre>Similar as FreeBASIC entry.</pre>
 
==={{header|QBasic}}===
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
{{works with|True BASIC}}
<syntaxhighlight lang="qbasic">RANDOMIZE TIMER : REM RANDOMIZE for True BASIC
stepsbehind = 0
stairslength = 100
 
PRINT "Seconds", "steps behind", "steps ahead"
FOR trial = 1 TO 10000
stepsbehind = 0
seconds = 0
stairslength = 100
DO WHILE stepsbehind < stairslength
stepsbehind = stepsbehind + 1
FOR j = 1 TO 5
IF INT(RND * stairslength) < stepsbehind THEN stepsbehind = stepsbehind + 1
stairslength = stairslength + 1
NEXT j
seconds = seconds + 1
IF trial = 1 AND seconds > 599 AND seconds < 610 THEN PRINT seconds, stepsbehind, stairslength - stepsbehind
LOOP
secondstot = secondstot + seconds
stepstot = stepstot + stairslength
NEXT trial
 
PRINT "Average time taken: "; secondstot / 10000; " seconds."
PRINT "Average final staircase length: "; stepstot / 10000; " steps."
END</syntaxhighlight>
 
==={{header|True BASIC}}===
{{trans|QBasic}}
{{works with|QBasic}}
<syntaxhighlight lang="qbasic">RANDOMIZE ! RANDOMIZE TIME for QBasic
LET stepsbehind = 0
LET stairslength = 100
 
PRINT "Seconds", "steps behind", "steps ahead"
FOR trial = 1 TO 10000
LET stepsbehind = 0
LET seconds = 0
LET stairslength = 100
DO WHILE stepsbehind < stairslength
LET stepsbehind = stepsbehind + 1
FOR j = 1 TO 5
IF INT(RND * stairslength) < stepsbehind THEN LET stepsbehind = stepsbehind + 1
LET stairslength = stairslength + 1
NEXT j
LET seconds = seconds + 1
IF trial = 1 AND seconds > 599 AND seconds < 610 THEN PRINT seconds, stepsbehind, stairslength - stepsbehind
LOOP
LET secondstot = secondstot + seconds
LET stepstot = stepstot + stairslength
NEXT trial
 
PRINT "Average time taken: "; secondstot / 10000; " seconds."
PRINT "Average final staircase length: "; stepstot / 10000; " steps."
END</syntaxhighlight>
 
==={{header|VBScript}}===
<syntaxhighlight lang="vb">
Option Explicit
Randomize Timer
 
Function pad(s,n)
If n<0 Then pad= right(space(-n) & s ,-n) Else pad= left(s& space(n),n) End If
End Function
 
Sub print(s)
On Error Resume Next
WScript.stdout.WriteLine (s)
If err= &h80070006& Then WScript.Echo " Please run this script with CScript": WScript.quit
End Sub
 
Function Rounds(maxsecs,wiz,a)
Dim mystep,maxstep,toend,j,i,x,d
If IsArray(a) Then d=True: print "seconds behind pending"
maxstep=100
For j=1 To maxsecs
For i=1 To wiz
If Int(Rnd*maxstep)<=mystep Then mystep=mystep+1
maxstep=maxstep+1
Next
mystep=mystep+1
If mystep=maxstep Then Rounds=Array(j,maxstep) :Exit Function
If d Then
If j>=a(0) And j<=a(1) Then print pad(j,-7) & pad (mystep,-7) & pad (maxstep-mystep,-8)
End If
Next
Rounds=Array(maxsecs,maxstep)
End Function
 
 
Dim n,r,a,sumt,sums,ntests,t,maxsecs
ntests=10000
maxsecs=7000
t=timer
a=Array(600,609)
For n=1 To ntests
r=Rounds(maxsecs,5,a)
If r(0)<>maxsecs Then
sumt=sumt+r(0)
sums=sums+r(1)
End if
a=""
Next
 
print vbcrlf & "Done " & ntests & " tests in " & Timer-t & " seconds"
print "escaped in " & sumt/ntests & " seconds with " & sums/ntests & " stairs"
</syntaxhighlight>
{{out}}
<small>
<pre>
seconds behind pending
600 2123 977
601 2126 979
602 2130 980
603 2134 981
604 2137 983
605 2141 984
606 2145 985
607 2151 984
608 2155 985
609 2159 986
 
Done 10000 tests in 51.30469 seconds
escaped in 2923.1174 seconds with 14715.587 stairs
</pre>
</small>
 
==={{header|Yabasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vbnet">steps_behind = 0
stairs_length = 100
print "Seconds", chr$(9), "steps behind", chr$(9), "steps ahead"
for trial = 1 to 10000 //We'll have the runner try this 10000 times
steps_behind = 0 //runner starts at the bottom
seconds = 0 //reset time taken
stairs_length = 100 //Staircase has 100 steps
while steps_behind < stairs_length //if the runner hasn//t reached the top
steps_behind = steps_behind + 1 //go up one step
for j = 1 to 5 //The evil wizard conjures another five steps
if int(ran(1)*stairs_length) < steps_behind steps_behind = steps_behind + 1
//there//s a chance that a new step will be behind you
stairs_length = stairs_length + 1 //but either way the staircase is one step longer
next j
seconds = seconds + 1 //that all took one second
if trial = 1 and seconds > 599 and seconds < 610 print seconds, chr$(9), steps_behind, chr$(9), chr$(9), stairs_length - steps_behind
//for the first attempt, see how the runner is doing after ten minutes
wend
seconds_tot = seconds_tot + seconds //if the runner escaped, track the time taken and the length of the stairs
steps_tot = steps_tot + stairs_length
next trial
 
print "Average time taken: ", seconds_tot/10000, " seconds."
print "Average final staircase length: ", steps_tot/10000, " steps."
//if you noticed that last number is about 100*exp(5), that//s no coincidence</syntaxhighlight>
{{out}}
<pre>Similar as FreeBASIC entry.</pre>
 
=={{header|C}}==
<syntaxhighlight lang="c">
<lang c>
#include <stdio.h>
#include <stdlib.h>
Line 41 ⟶ 552:
printf( "Average final length of staircase: %f\n", steps_tot/10000.0 );
return 0;
}</langsyntaxhighlight>
{{out}}<pre>
Seconds steps behind steps ahead
Line 57 ⟶ 568:
Average final length of staircase: 14707.466000
</pre>
 
=={{header|Dart}}==
{{trans|C}}
<syntaxhighlight lang="dart">import 'dart:math';
 
void main() {
int secsTot = 0,
stepsTot = 0; // keep track of time and steps over all the trials
Random rand = new Random();
 
print("Seconds steps behind steps ahead");
 
for (int trial = 1; trial <= 10000; trial++) {
// 10000 attempts for the runner
int sbeh = 0, slen = 100, secs = 0; // initialise this trial
 
while (sbeh < slen) {
// as long as the runner is still on the stairs
sbeh += 1; // runner climbs a step
 
for (int wiz = 1; wiz <= 5; wiz++) {
// evil wizard conjures five new steps
if (rand.nextInt(slen) < sbeh)
sbeh += 1; // maybe a new step is behind us
slen += 1; // either way, the staircase is longer
}
 
secs += 1; // one second has passed
 
if (trial == 1 && 599 < secs && secs < 610)
print("$secs $sbeh ${slen - sbeh}");
}
 
secsTot += secs;
stepsTot += slen;
}
 
print("Average secs taken: ${secsTot / 10000.0}");
print("Average final length of staircase: ${stepsTot / 10000.0}");
}</syntaxhighlight>
{{out}}
<pre>Similar as C entry.</pre>
 
=={{header|Factor}}==
<syntaxhighlight lang="factor">USING: combinators.random io kernel math math.order prettyprint ;
 
: position ( -- n ) 0 ;
: stairs ( -- n ) 100 ;
: new ( -- m n ) position stairs ;
: incd ( m n -- o p ) swap 1 + swap ;
: seconds ( m -- n ) 100 - 5 / ;
: window? ( n -- ? ) seconds 600 609 between? ;
: zap ( m n -- o p ) 2dup / [ incd ] whenp 1 + ;
: barrage ( m n -- o p ) 5 [ zap ] times ;
: .n ( n -- ) pprint 7 [ bl ] times ;
: .stats ( m n -- ) dup seconds .n over .n swap - .n nl ;
: .header ( -- ) "Seconds behind ahead" print ;
: ?.status ( m n -- o p ) dup window? [ 2dup .stats ] when ;
: tick ( m n -- o p ) incd barrage ;
: demo ( m n -- o p ) tick ?.status ;
: sim-with ( q -- n ) new rot [ 2dup < ] swap while drop ; inline
: first ( -- n ) [ demo ] sim-with ;
: sim ( -- n ) [ tick ] sim-with ;
: sims ( -- n ) 0 first + 9999 [ sim + ] times ;
: steps ( m -- n ) "Avg. steps: " write 10000 / dup . ;
: time ( n -- ) "Avg. seconds: " write seconds . ;
: main ( -- ) .header sims nl steps time ;
 
main</syntaxhighlight>
{{out}}
<pre>
Seconds behind ahead
600 2067 1033
601 2073 1032
602 2078 1032
603 2082 1033
604 2087 1033
605 2091 1034
606 2096 1034
607 2099 1036
608 2103 1037
609 2108 1037
 
Avg. steps: 14731+23/200
Avg. seconds: 2926+223/1000
</pre>
And for fun, a version without stack effects.
<syntaxhighlight lang="factor">USING: combinators.random effects.parser io kernel math
math.order parser prettyprint stack-checker words ;
 
<< SYNTAX: .: [ scan-new-word parse-definition dup infer ]
with-definition define-declared ; >>
 
.: position 0 ;
.: stairs 100 ;
.: new position stairs ;
.: incd swap 1 + swap ;
.: seconds 100 - 5 / ;
.: window? seconds 600 609 between? ;
.: zap 2dup / [ incd ] whenp 1 + ;
.: barrage 5 [ zap ] times ;
.: .n pprint 7 [ bl ] times ;
.: .stats dup seconds .n over .n swap - .n nl ;
.: .header "Seconds behind ahead" print ;
.: ?.status dup window? [ 2dup .stats ] when ;
.: tick incd barrage ;
.: demo tick ?.status ;
.: first new [ 2dup < ] [ demo ] while drop ;
.: sim new [ 2dup < ] [ tick ] while drop ;
.: sims 0 first + 9999 [ sim + ] times ;
.: steps "Avg. steps: " write 10000 / dup . ;
.: time "Avg. seconds: " write seconds . ;
.: main .header sims nl steps time ;
 
main</syntaxhighlight>
 
=={{header|Fermat}}==
<langsyntaxhighlight lang="fermat">
time_tot:=0; {we'll keep track of the total time and steps across all the trials}
steps_tot:=0;
Line 85 ⟶ 711:
 
!!(time_tot/10000);
!!(steps_tot/10000);</langsyntaxhighlight>
{{out}}<pre>
Seconds Steps behind Steps ahead
Line 102 ⟶ 728:
</pre>
 
=={{header|FreeBASICGo}}==
{{trans|Wren}}
<syntaxhighlight lang="go">package main
 
import (
<lang freebasic>
"fmt"
randomize timer
"math/rand"
dim as uinteger steps_behind = 0, stairs_length = 100, seconds, j
"time"
dim as uinteger seconds_tot, steps_tot
)
print "Seconds", "steps behind", "steps ahead"
for trial as uinteger = 1 to 10000 'We'll have the runner try this 10000 times
steps_behind = 0 'runner starts at the bottom
seconds = 0 'reset time taken
stairs_length = 100 'Staircase has 100 steps
while steps_behind < stairs_length 'if the runner hasn't reached the top
steps_behind += 1 'go up one step
for j = 1 to 5 'The evil wizard conjures another five steps
if int(rnd*stairs_length) < steps_behind then steps_behind += 1
'there's a chance that a new step will be behind you
stairs_length += 1 'but either way the staircase is one step longer
next j
seconds += 1 'that all took one second
if trial = 1 and seconds >599 and seconds < 610 then print seconds, steps_behind, stairs_length - steps_behind
'for the first attempt, see how the runner is doing after ten minutes
wend
seconds_tot += seconds 'if the runner escaped, track the time taken and the length of the stairs
steps_tot += stairs_length
next trial
 
func main() {
print "Average time taken: ";seconds_tot/10000; " seconds."
rand.Seed(time.Now().UnixNano())
print "Average final staircase length: ";steps_tot/10000; " steps."
totalSecs := 0
'if you noticed that last number is about 100*exp(5), that's no coincidence</lang>
totalSteps := 0
{{out}}<pre>
Seconds fmt.Println("Seconds steps behind steps ahead")
fmt.Println("------- ------------ -----------")
600 2032 1068
601 for trial := 1; trial < 10000; 2038trial++ 1067{
602 sbeh := 2042 10680
603 slen := 2045 1070100
604 secs := 2048 10720
605 for sbeh < 2053slen 1072{
606 2055 1075sbeh++
607 2060 for wiz := 1; wiz < 6; wiz++ 1075{
608 2064 if rand.Intn(slen) < sbeh 1076{
609 2068 1077sbeh++
}
Average time taken: 2921.9457 seconds.
slen++
Average final staircase length: 14709.7285 steps.
}
secs++
if trial == 1 && secs > 599 && secs < 610 {
fmt.Printf("%d %d %d\n", secs, sbeh, slen-sbeh)
}
}
totalSecs += secs
totalSteps += slen
}
fmt.Println("\nAverage secs taken:", float64(totalSecs)/10000)
fmt.Println("Average final length of staircase:", float64(totalSteps)/10000)
}</syntaxhighlight>
 
{{out}}
Sample run:
<pre>
Seconds steps behind steps ahead
------- ------------ -----------
600 2138 962
601 2143 962
602 2148 962
603 2153 962
604 2159 961
605 2163 962
606 2167 963
607 2172 963
608 2177 963
609 2183 962
 
Average secs taken: 2917.9058
Average final length of staircase: 14689.519
</pre>
 
=={{header|J}}==
<syntaxhighlight lang="j">stairsim=:{{
t=. 0 NB. fifths of a second
echo ;_8 _16 _20{.each 'seconds';'steps to top';'steps from bottom'
for_trial. i.1e4 do.
loc=. {.'min max'=. 0 100
while. loc < max do.
if. 0=5|t=.t+1 do.
loc=. loc+1
if. 0=trial do.
if. 1=2999 3046 I.t do.
echo 8 16 20":(t%5),(max-loc),(loc-min)
end.
end.
end.
ins=. min+?max-min
if. ins < loc do. min=. min-1 else. max=. max+1 end.
end.
end.
echo 'Average steps taken: ',":t%5e4
echo 'Average length of staircase: ',":100+t%1e4
}}</syntaxhighlight>
 
Example run:<syntaxhighlight lang="j"> stairsim''
seconds steps to top steps from bottom
600 1142 1957
601 1142 1962
602 1141 1968
603 1141 1973
604 1142 1977
605 1143 1981
606 1143 1986
607 1143 1991
608 1144 1995
609 1144 2000
Average steps taken: 3026.43
Average length of staircase: 15232.2</syntaxhighlight>
 
=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
 
Neither the C nor the Go-based implmentations of jq currently have a
built-in PRNG, so for the present task
/dev/urandom is used as a source of entropy by invoking jq as follows:
 
<pre>
cat /dev/urandom | tr -cd '0-9' | fold -w 1 | jq -nrf long-stairs.jq
</pre>
where long-stairs.jq contains the jq program shown below.
For simplicity and since the intermediate output has the character of
a probe, the program uses `debug` statements to show the intermediate results.
<syntaxhighlight lang="jq"># 0 <= output < $n
def rand($n):
 
def ntimes(f): range(0; .) | f;
# input: an array of length ($n|tostring|length)
def r:
. as $in
| (join("") | tonumber) as $m
| if $m < $n then $m
else $in[1:] + [input] | r
end;
[$n | tostring | length | ntimes(input)] | r;
 
# $n specifies the number of iterations
def task($n):
(reduce range(1; $n + 1) as $trial (null;
.sbeh = 0
| .slen = 100
| .secs = 0
| until (.sbeh >= .slen;
.sbeh += 1
| reduce range(1;6) as $wiz (.;
if (rand( .slen) < .sbeh) then .sbeh += 1 else . end
| .slen += 1 )
| .secs += 1
| if ($trial == 1 and .secs > 599 and .secs < 610)
then ([.secs, .sbeh, .slen - .sbeh] | debug) as $debug | .
else .
end )
| .totalSecs += .secs
| .totalSteps += .slen ) ) ;
 
"Seconds steps behind steps ahead",
"------- ------------ -----------",
(1E4 as $n
| task($n)
| "\nAverage secs taken over \($n) trials: \(.totalSecs/$n)",
"Average final length of staircase: \(.totalSteps/$n)"
)</syntaxhighlight>
{{out}}
<pre>
Seconds steps behind steps ahead
------- ------------ -----------
["DEBUG:",[600,1916,1184]]
["DEBUG:",[601,1919,1186]]
["DEBUG:",[602,1920,1190]]
["DEBUG:",[603,1924,1191]]
["DEBUG:",[604,1926,1194]]
["DEBUG:",[605,1931,1194]]
["DEBUG:",[606,1934,1196]]
["DEBUG:",[607,1938,1197]]
["DEBUG:",[608,1942,1198]]
["DEBUG:",[609,1945,1200]]
 
Average secs taken over 10000 trials: 3211.962
Average final length of staircase: 16159.81
</pre>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">""" https://rosettacode.org/wiki/Long_stairs """
 
using Statistics
 
struct LongStairs
startstep::Int
startlength::Int
climbersteps::Int
addsteps::Int
end
 
Base.length(LongStairs) = typemax(Int)
Base.eltype(ls::LongStairs) = Vector{Int}
 
function Base.iterate(s::LongStairs, param = (s.startstep, s.startlength))
pos, len = param
pos += s.climbersteps
pos += sum(pos .> rand(1:len, s.addsteps))
len += s.addsteps
return [pos, len], (pos, len)
end
 
ls = LongStairs(1, 100, 1, 5)
 
println("Seconds Behind Ahead\n----------------------")
for (secs, (pos, len)) in enumerate(collect(Iterators.take(ls, 609))[600:609])
println(secs + 599, " ", pos, " ", len - pos)
end
 
println("Ten thousand trials to top:")
times, heights = Int[], Int[]
for trial in 1:10_000
trialstairs = LongStairs(1, 100, 1, 5)
for (sec, (step, height)) in Iterators.enumerate(trialstairs)
if step >= height
push!(times, sec)
push!(heights, height)
break
end
end
end
@show mean(times), mean(heights)
</syntaxhighlight>{{out}}
<pre>
Seconds Behind Ahead
----------------------
601 1938 1167
602 1944 1166
603 1948 1167
604 1952 1168
605 1956 1169
606 1959 1171
607 1963 1172
608 1967 1173
609 1971 1174
Ten thousand trials to top:
(mean(times), mean(heights)) = (2927.0853, 14735.4265)
</pre>
=={{header|Nim}}==
<syntaxhighlight lang="Nim">import std/[random, strformat]
 
randomize()
 
proc simulate(verbose: bool): (int, int) =
if verbose:
echo "Seconds Steps behind Steps ahead"
var curr = 1 # Number of current step.
var last = 100 # Number of last step.
var t = 0
while true:
inc t
inc curr
if curr > last:
return (t, last) # Escaped!
# Add new steps.
for i in 1..5:
let n = rand(1..last)
if n < curr: inc curr # Behind current step.
inc last
if verbose and t in 600..609:
echo &"{t:^7} {curr:^12} {last - curr:^12}"
if t == 609: return # This part is terminated.
 
# First part of the task.
discard simulate(true)
echo()
 
# Second part of the task.
var tSum, stepSum = 0
for _ in 1..10_000:
let (t, n) = simulate(false)
tSum += t
stepSum += n
echo &"Average seconds taken: {tSum / 10_000}"
echo &"Average final length of staircase: {stepSum / 10_000}"
</syntaxhighlight>
 
{{out}}
<pre>Seconds Steps behind Steps ahead
600 2031 1069
601 2034 1071
602 2038 1072
603 2043 1072
604 2046 1074
605 2050 1075
606 2055 1075
607 2061 1074
608 2066 1074
609 2070 1075
 
Average seconds taken: 2924.1551
Average final length of staircase: 14715.7755
</pre>
 
=={{header|GW-BASIC}}==
<lang gwbasic>
10 RANDOMIZE TIMER
20 TIMET = 0 : STEPST = 0
30 FOR TRIAL = 1 TO 10000
40 TIME = 0
50 SBEH = 0
60 SLEN = 100
70 SBEH = SBEH + 1
80 IF SBEH >= SLEN THEN GOTO 160
90 FOR WIZ = 1 TO 5
100 IF INT(RND*SLEN)<SBEH THEN SBEH = SBEH + 1
110 SLEN = SLEN + 1
120 NEXT WIZ
130 TIME = TIME + 1
140 IF TRIAL = 1 AND 599<TIME AND TIME <610 THEN PRINT TIME, SBEH, SLEN-SBEH
150 GOTO 70
160 TIMET = TIMET+TIME+1
170 STEPST = STEPST + SLEN
180 NEXT TRIAL
190 PRINT TIMET/10000
200 PRINT STEPST/10000</lang>
=={{header|Pascal}}==
==={{header|Free Pascal}}===
Trying to calculate results of multiple random rounds.Now a partial step forward 1/CntOfSpellStairs for every spell stair.<BR>
<lang pascal>program WizardStaircase;
Now results are much closer.
<syntaxhighlight lang="pascal">program WizardStaircase;
const
StartStairLength = 100;
Line 182 ⟶ 1,029:
end;
 
function OneRun(StairsPerSpell:Cardinal;WithOutput:boolean):longword;
var
inFront,behind,total,i,trials: longwordCardinal;
begin
trials := 0;
Line 195 ⟶ 1,042:
dec(infront);
//spell
for i := 1 to StairsPerSpell do;
beginrepeat
if random(total)+1 <= behind then
inc(behind)
else
inc(infront);
inc(total);
end dec(i);
until i=0;
 
if WithOutput then
begin
Line 209 ⟶ 1,056:
OutActual(trials,behind,infront);
end;
 
until infront = 0;
OneRun := total;
end;
 
procedure CheckDouble(StairsPerSpell:Cardinal);
var
behind,infront,relpos,total,One,relSpell : double;
i : LongInt;
begin
write(StairsPerSpell:3);
One := 1.0;
behind := 0.0;
inFront := StartStairLength;
total := StartStairLength;
relSpell := One/StairsPerSpell;
repeat
i := StairsPerSpell;
//doing a partial move per one stair per spell
repeat
relpos := (behind+relSpell)/total;
behind := behind + relpos +relSpell;
inFront := inFront+(One-relpos)-relSpell;
total := total+One;
dec(i);
until i= 0;
until infront < One;
writeln((total-StartStairLength)/StairsPerSpell:10:0,total:14:0);
end;
 
var
i,
mySpell,
attempt,
minStairs,
Line 221 ⟶ 1,093:
total : longword;
begin
minStairs := High(minStairs);
maxStairs := low(maxStairs);
randomize;
writeln('Seconds steps total behind ahead');
total := OneRun(StairsPerSpell,true);
 
total := 0;
writeln(' average stairs needed steps minimum maximum');
For i := rounds-1 downto 0 do
for mySpell := 1 to 7 do
begin
attemptwrite(mySpell:=3,' OneRun(false ');
total := 0;
if minStairs>attempt then
minstairsminStairs := attemptHigh(minStairs);
if maxStairs<attempt then:= low(maxStairs);
For maxstairsi := attempt;rounds-1 downto 0 do
begin
inc(total,attempt);
attempt:= OneRun(mySpell,false);
if minStairs>attempt then
minstairs := attempt;
if maxStairs<attempt then
maxstairs := attempt;
inc(total,attempt);
end;
writeln((total-StartStairLength)/rounds/mySpell:12:3,total/rounds:14:3,minStairs:9,maxStairs:10);
end;
writeln(' average stairs minimum maximum');
writeln(total/rounds:14:3,minStairs:9,maxStairs:10);
writeln;
 
writeln((total-StartStairLength)/rounds/StairsPerSpell:10:3,' average needed seconds');
writeln(' calculated ');
end.</lang>
For i := 1 to 10 do
CheckDouble(i);
end.</syntaxhighlight>
{{Out|@ TIO.RUN}}
<pre>
 
Seconds steps total behind ahead
600 3100 21712260 929840
601 3105 21742264 931841
602 3110 21782269 932841
603 3115 21822275 933840
604 3120 21872281 933839
605 3125 21922285 933840
606 3130 21962291 934839
607 3135 22002295 935840
608 3140 22042300 936840
609 3145 22092302 936843
average stairs needed steps minimum maximum
1 14691 271.943090 271.100 239 7195 30765313
2 367.570 735.150 540 954
3 663.998 1992.003 1234 2911
4 1353.416 5413.674 2748 8980
5 2933.418 14667.099 6715 27210
6 6648.557 39891.354 18394 80050
7 15550.874 108856.130 42380 218892
 
calculated
1 170 270
2 317 734
3 633 1999
4 1333 5432
5 2933 14765
6 6673 40138
7 15573 109111
8 37063 296604
9 89573 806257
10 219154 2191640
 
Real time: 293855.387269 average needed secondss</pre>
 
=={{header|Phix}}==
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> <span style="color: #000080;font-style:italic;">-- (nb expect blank sccreenscreen for ~30s)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">total_seconds</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
Line 288 ⟶ 1,187:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Average seconds: %f, average steps: %f\n"</span><span style="color: #0000FF;">,</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">total_seconds</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">total_steps</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10000</span><span style="color: #0000FF;">})</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 305 ⟶ 1,204:
 
Average seconds: 2913.609300, average steps: 14668.046500
</pre>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">#!/usr/bin/perl
 
use strict; # https://rosettacode.org/wiki/Long_stairs
use warnings;
 
my $sumseconds = my $sumsizes = my $runs = 0;
for ( 1 .. 1e4 )
{
$runs++;
my $behind = 0;
my $ahead = 100;
my $seconds = 0;
while( $ahead > 0 )
{
rand() <= ($ahead / ($behind + $ahead)) ? $ahead++ : $behind++ for 1 .. 5;
$behind++; # one step up
$ahead--;
$seconds++;
$_ == 1 and 600 <= $seconds <= 609 and
print "step $seconds: $behind behind, $ahead ahead\n";
}
$sumsizes += $behind;
$sumseconds += $seconds;
}
printf "\naverage stair length %d average seconds %d\n",
$sumsizes / $runs, $sumseconds / $runs;</syntaxhighlight>
{{out}}
<pre>
step 600: 2233 behind, 867 ahead
step 601: 2237 behind, 868 ahead
step 602: 2241 behind, 869 ahead
step 603: 2247 behind, 868 ahead
step 604: 2249 behind, 871 ahead
step 605: 2254 behind, 871 ahead
step 606: 2258 behind, 872 ahead
step 607: 2262 behind, 873 ahead
step 608: 2268 behind, 872 ahead
step 609: 2273 behind, 872 ahead
 
average stair length 15438 average seconds 3067
</pre>
 
=={{header|Python}}==
<syntaxhighlight lang="python">""" https://rosettacode.org/wiki/Long_stairs """
 
from numpy import mean
from random import sample
 
def gen_long_stairs(start_step, start_length, climber_steps, add_steps):
secs, behind, total = 0, start_step, start_length
while True:
behind += climber_steps
behind += sum([behind > n for n in sample(range(total), add_steps)])
total += add_steps
secs += 1
yield (secs, behind, total)
 
ls = gen_long_stairs(1, 100, 1, 5)
 
print("Seconds Behind Ahead\n----------------------")
while True:
secs, pos, len = next(ls)
if 600 <= secs < 610:
print(secs, " ", pos, " ", len - pos)
elif secs == 610:
break
 
print("\nTen thousand trials to top:")
times, heights = [], []
for trial in range(10_000):
trialstairs = gen_long_stairs(1, 100, 1, 5)
while True:
sec, step, height = next(trialstairs)
if step >= height:
times.append(sec)
heights.append(height)
break
 
print("Mean time:", mean(times), "secs. Mean height:", mean(heights))
</syntaxhighlight>{{out}}
<pre>
Seconds Behind Ahead
----------------------
600 2122 978
601 2127 978
602 2130 980
603 2135 980
604 2139 981
605 2144 981
606 2149 981
607 2153 982
608 2157 983
609 2162 983
 
Ten thousand trials to top:
Mean time: 2780.502 secs. Mean height: 14002.51
</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="Quackery"> [ 0 100 0
[ 5 times
[ 2dup swap
random > +
dip 1+ ]
1+
rot 1+ unrot
2dup < until ]
drop ] is test ( --> n n )
 
( and again, with progress report )
 
[ 0 100 0
[ rot dup dip unrot
dup 600 610 within iff
[ say "After " echo
say " seconds, "
2dup dup
say "Behind: "
echo
say " Ahead: "
- echo cr ]
else drop
5 times
[ 2dup swap
random > +
dip 1+ ]
1+
rot 1+ unrot
2dup < until ]
drop 2drop ] is progress ( --> )
 
progress
cr
0 0 10000 times
[ test rot +
unrot + swap ]
swap
say "Mean time: "
number$ char . swap -4 stuff echo$ cr
say "Mean stairs: "
number$ char . swap -4 stuff echo$ cr</syntaxhighlight>
 
{{out}}
 
<pre>After 600 seconds, Behind: 2187 Ahead: 913
After 601 seconds, Behind: 2191 Ahead: 914
After 602 seconds, Behind: 2197 Ahead: 913
After 603 seconds, Behind: 2200 Ahead: 915
After 604 seconds, Behind: 2204 Ahead: 916
After 605 seconds, Behind: 2208 Ahead: 917
After 606 seconds, Behind: 2211 Ahead: 919
After 607 seconds, Behind: 2214 Ahead: 921
After 608 seconds, Behind: 2218 Ahead: 922
After 609 seconds, Behind: 2224 Ahead: 921
 
Mean time: 3063.7808
Mean stairs: 15418.9040
</pre>
 
=={{header|Raku}}==
<syntaxhighlight lang="raku" perl6line>my ($trials, $t-total, $s-total) = 10000;
 
say 'Seconds steps behind steps ahead';
Line 332 ⟶ 1,393:
}
 
say "Average seconds: {$t-total/$trials}, Average steps: {$s-total/$trials}";</langsyntaxhighlight>
{{out|Sample output}}
<pre>Seconds steps behind steps ahead
Line 346 ⟶ 1,407:
609 2187 958
Average seconds: 2716.0197, Average steps: 13677.143</pre>
 
=={{header|RPL}}==
« 0 (100,100)
'''DO''' SWAP 1 +
SWAP 1 -
1 5 '''START'''
RAND OVER RE LASTARG IM / <
1 R→C +
'''NEXT'''
'''IF''' OVER 599 > 3 PICK 610 < AND '''THEN''' OVER 1 DISP DUP 2 DISP '''END'''
'''UNTIL''' DUP RE NOT '''END'''
IM "steps" →TAG SWAP "secs" →TAG
» '<span style="color:blue">STAIRS</span>' STO
{{out}}
<pre>
2: steps:16135
1: secs:3207
</pre>
Executing 10,000 tests is far beyond the computing power of a basic calculator.
 
=={{header|V (Vlang)}}==
{{trans|Wren}}
{{libheader|Vlang-rand}}
<syntaxhighlight lang="v (vlang)">import rand
fn main() {
mut total_secs := 0
mut total_steps := 0
println("Seconds steps behind steps ahead")
println("------- ------------ -----------")
for trial in 1..10000 {
mut sbeh := 0
mut slen := 100
mut secs := 0
for sbeh < slen {
sbeh++
for _ in 1..5 {
if rand.intn(slen) or {0} < sbeh {
sbeh++
}
slen++
}
secs++
if trial == 1 && secs > 599 && secs < 610 {
println("$secs $sbeh ${slen-sbeh}")
}
}
total_secs += secs
total_steps += slen
}
println("\nAverage secs taken: ${total_secs/10000}")
println("Average final length of staircase: ${total_steps/10000}")
}</syntaxhighlight>
 
{{out}}
Sample run:
<pre>
Seconds steps behind steps ahead
------- ------------ -----------
600 2112 988
601 2115 990
602 2121 989
603 2126 989
604 2130 990
605 2135 990
606 2141 989
607 2146 989
608 2150 990
609 2155 990
 
Average secs taken: 2914.465
Average final length of staircase: 14672.325
</pre>
 
=={{header|Wren}}==
{{trans|C}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "random" for Random
import "./fmt" for Fmt
 
Line 377 ⟶ 1,511:
}
Fmt.print("\nAverage secs taken: $h", totalSecs/10000)
Fmt.print("Average final length of staircase: $h", totalSteps/10000)</langsyntaxhighlight>
 
{{out}}
Line 397 ⟶ 1,531:
Average secs taken: 2914.465
Average final length of staircase: 14672.325
</pre>
 
=={{header|XPL0}}==
{{trans|C}}
<syntaxhighlight lang "XPL0">include xpllib; \for Print
 
int Trial, SecsTotal, StepsTotal; \keep track of time and steps over all trials
int SBehind, SLen, Wiz, Secs; \all variables related to individual trial
[SecsTotal:= 0; StepsTotal:= 0;
Print("Seconds steps behind steps ahead\n");
for Trial:= 1 to 10000 do \10000 attempts for the runner
[SBehind:= 0; SLen:= 100; Secs:= 0; \initialise this Trial
while SBehind < SLen do \as long as runner is still on stairs
[SBehind:= SBehind+1; \runner climbs a step
for Wiz:= 1 to 6 do \evil Wizard conjures five new steps
[if Ran(SLen) < SBehind then
SBehind:= SBehind+1; \maybe a new step is behind us
SLen:= SLen+1; \either way, the staircase is longer
];
Secs:= Secs+1; \one second has passed
if Trial=1 & 599<Secs & Secs<610 then
Print("%d %d %d\n", Secs, SBehind, SLen-SBehind);
];
SecsTotal:= SecsTotal + Secs;
StepsTotal:= StepsTotal + SLen;
];
Print("Average seconds taken: %f\n", float(SecsTotal)/10000.0);
Print("Average final length of staircase: %f\n", float(StepsTotal)/10000.0);
]</syntaxhighlight>
{{out}}
<pre>
Seconds steps behind steps ahead
600 2275 1425
601 2278 1428
602 2283 1429
603 2289 1429
604 2294 1430
605 2299 1431
606 2304 1432
607 2306 1436
608 2311 1437
609 2316 1438
Average seconds taken: 6625.81730
Average final length of staircase: 39854.90380
</pre>
1,150

edits