The Random Walker Printer

24

3

Draw a program or function that will write to STDOUT n times (each for one step) a string that contains a dot . at the location of the walker. The program also needs to write a line every s seconds (or wait s seconds after each line).

A random walk is a mathematical formalization of a path that consists of a succession of random steps (wiki), such that every new step will be the last step plus a new value, so any tstep value is just the sum of all the random values before ir plus the initial value.

The program should take 2 inputs and will use only spaces " " and dots "." on the output. The start value of the walker will be 20 such that the output should be a dot after 19 spaces.

                  . #19 spaces then a dot

Every new step the value will be the last value of the walker plus one of these[-2-1,0,1,2](20% chance each). After the new position is printed the program should wait s seconds and the go to the next step. If the step takes the walker outsite the range 1 to 40 it should be just ignored and the walker position stays the same. The number of spaces will always be a number from 0 to 39.

Example

#input
Mywalk(s = 0.1, n = 30)

#output
                     .
                    .
                      .
                        .
                          .
                           .
                            .
                          .
                         .
                          .
                           .
                            .
                           .
                          .
                           .
                           .
                         .
                         .
                          .
                            .
                           .
                          .
                           .
                           .
                           .
                         .
                          .
                         .
                          .
                          .

Considerations

  • You may take the input as any reasonable format

  • The shortest code wins

  • It's okay if your program only accept the seconds as integers

Mutador

Posted 2015-12-18T17:21:32.793

Reputation: 1 361

2I assume n is the number of steps? – ASCIIThenANSI – 2015-12-18T17:27:05.927

Yeah, I've clarified that, thanks. – Mutador – 2015-12-18T17:33:11.630

I think you should say that the range is 1 to 40, because the number of spaces is always position-1. – geokavel – 2015-12-18T18:09:15.453

@geokavel that seems better, fixed ! – Mutador – 2015-12-18T18:29:29.563

10*Draw a program*??? ;-) – Digital Trauma – 2015-12-18T20:13:06.463

Answers

6

Pyth, 39

J19VEK+.d0QW<.d0K)+*d=JhtS[Z39-+O5J2)\.

Takes s as the first line of input and n as the second. Works on the command line but not with the online interpreter. My first Pyth program ever! Golfing tips are appreciated.

Luke

Posted 2015-12-18T17:21:32.793

Reputation: 5 091

Welcome to Pyth! The only golfing tip I can see is that you can use Q and E for the two inputs instead fo hQ and eQ, if you newline separate the inputs. – isaacg – 2015-12-18T23:58:11.700

13

Matlab, 112

The core idea is generating a list of possible next positions and then uniformly drawing one of them. If we are e.g. at position $l=1$ the possible steps would be [-1,0,1,2,3] Of course if we would chose -1 that would be invalid and we would have to stay at the same position. Thats why we replace the invalid positions with the current position, [1,0,1,2,3], and then randomly chose an element from this updated list.

The OP asked us tho draw the program, so here we go:

enter image description here

The transcription:

function c(n,s);
l=19;                             %initialize position
for k=1:n;                          
    disp([ones(1,l)*32,'.']);     %print the line
    z=(-2:2)+l;                   %get vector of possible next steps (for l=1 we get [-1,0,1,2,3])
    z(z<0)=l;                     %prune invalids: here we just replace the the invalid positions with the current position
    z(z>39)=l;                    %   this ensures the same behaivour as staying in the same spot when going outside of the range
    l=z(randi(5));                %draw random sample of those
    pause(s);
end

flawr

Posted 2015-12-18T17:21:32.793

Reputation: 40 560

1-1 uses MathJax in a non-MathJax environment ;) – Conor O'Brien – 2015-12-18T19:16:41.217

2O.o You know, equations that are not written in latex are just not quite as trustable, they might even be not true! Better be on the safe side. – flawr – 2015-12-18T21:05:59.037

3Drawn programs should be measured in volume of ink, rather than bytes... – Darrel Hoffman – 2015-12-20T15:45:19.173

8

Perl, 136 128 116 106 101 90 86

$p=19;map{say$"x$p.".";sleep $ARGV[0];$x=rand(5)+$p-2;$p=$x>0&&$x<40?$x:$p}1..$ARGV[1]

Requires the seconds to be an integer.

Run with perl <filename> <second delay> <number of steps>.

There may be more golfing potential here, although honestly, I'm surprised it got this far. (Come on, only 6 more bytes to beat the bash answer...)

Changes

  • Saved 8 bytes by removing unneeded parentheses and spelling out ARGV (it's actually shorter that way)
  • Saved 12 more bytes by removing $s and $n and just using the plain $ARGV[0] and $ARGV[1]
  • Saved another 10 bytes when I realized I could use $" and didn't need to specifically define $u as $undef.
  • Saved 5 more bytes by rearranging the ternary and how $x is used and by using map instead of for.
  • Saved 11 bytes by no longer accepting the seconds as decimals (challenge spec says it's OK.)
  • Saved another 5 bytes by using say instead of print.

ASCIIThenANSI

Posted 2015-12-18T17:21:32.793

Reputation: 1 935

6

Python 2, 124 119 bytes

@janrn and @Steve Eckert: I don't have enough reputation to comment your answer but here's essentially your version shortened down. The task is to draw a program or a function, so by using f(s,x) you can save quite some bits, as well you can use max(0,min(x,39)) to avoid an extra if clause. Got it down to:

import time,random as r
def f(s,x):
 n=19
 while x:print' '*n+'.';time.sleep(s);n=max(0,min(n+r.randint(-2,2),39));x-=1

ბიმო

Posted 2015-12-18T17:21:32.793

Reputation: 15 345

5

Bash, 81

for((s=20;i++<$1;t=s,s+=RANDOM%5-2,s=s<0|s>39?t:s)){
printf %${s}s.\\n
sleep $2
}

Edit: If the step takes the walker outsite the range 1 to 40 it should be just ignored and the walker position stays the same handled correctly.

Input from command-line options. E.g.:

$ ./randwalk.sh 5 0.5
                    .
                     .
                    .
                  .
                 .
$ 

Digital Trauma

Posted 2015-12-18T17:21:32.793

Reputation: 64 644

4

Processing, 150 147

void w(int n,int s){int x=20,i,y,c=0;for(;c<n;c++){x+=y=int(random(5)-2);if(x>40||x<0)x-=y;for(i=1;i<x;i++)print(" ");println(".");delay(s*1000);}}

Usage:

void setup() {
    w(10,1);
}

Note: 1000 can't be changed to 1e3 for type reasons.

geokavel

Posted 2015-12-18T17:21:32.793

Reputation: 6 352

4

Python 2.7, 198 162 143 133

import time,random as r;p=20;s=0;d=input();w=input()
while s<d:
 print' '*p+'.';s+=1;p=max(1,min(p+r.randint(-2,2),40));time.sleep(w)

When calling the script with python script.py, the first input is the amount of steps, second input the time between steps (accepts float or int). Any suggestions for improving?

Edits

  • saved 36 bytes due to now using print ' '*p+'.', thanks to @corsiKlause Ho Ho Ho
  • down another 19 bytes by removing tab indents, replaced them with one space or ; where possible
  • 10 bytes less thanks to @Bruce_Forte idea with p=max(1,min(p+r.randint(-2,2),40)) (I can't comment on your answer as well, but thanks; don't want to copy it completely)

janrn

Posted 2015-12-18T17:21:32.793

Reputation: 51

In Python, can't you just go ' '*p to repeat the string? – corsiKa – 2015-12-18T23:35:45.950

Actually yes, didn't know that. Editing now, thanks – janrn – 2015-12-18T23:42:15.190

4

Ruby, 84

def w(s,n)q=19;n.times{puts ' '*q+'.';sleep s;q+=rand(5)-2;q=[[q,0].max,39].min};end

gryzelda

Posted 2015-12-18T17:21:32.793

Reputation: 41

3

Lua, 140 Bytes

Note: This program requires the LuaSocket package.

require"socket"p=19 for i=1,arg[2]+0 do print((" "):rep(p)..".")p=p+math.random(-2,2)p=p<0 and 0 or p>39 and 39 or p socket.sleep(arg[1])end

Nikolai97

Posted 2015-12-18T17:21:32.793

Reputation: 653

3

Perl 6, 92 bytes

my (\n,\s)=@*ARGS;$/=19;for (-2..2).roll(n) {put ' 'x($/+=(40>$/+$_>=0??$_!!0)),'.';sleep s} # 92
my (\n,\s)=@*ARGS;
$/=19;
for (-2..2).roll(n) {
  put ' 'x($/+=(40>$/+$_>=0??$_!!0)),'.';
  sleep s
}

Usage:

$ perl6 -e 'my (\n,\s)=@*ARGS;$/=19;for (-2..2).roll(n) {put " "x($/+=(40>$/+$_>=0??$_!!0)),".",;sleep s}' 10 0.001
                  .
                .
               .
              .
               .
                .
               .
                .
                  .
                 .

Brad Gilbert b2gills

Posted 2015-12-18T17:21:32.793

Reputation: 12 713

3

Mathematica, 122 117 bytes

$RecursionLimit=∞;If[#2>0,Print[Indent[a=Min[#3+RandomInteger@{-2,2},39]~Max~0],"."];Pause@#;#0[#,#2-1,a]]&[##,19]&

Recursive anonymous function, takes input in the order specified. Could probably be golfed further.

LegionMammal978

Posted 2015-12-18T17:21:32.793

Reputation: 15 731

3

JavaScript (ES6), 125 bytes

(s,n)=>(t=setTimeout)(c=`console.log(" ".repeat(p)+".");p+=m=Math.random()*5|0;p-=p>41|p<2?m:2;--i&&t(c,d)`,d=s*1e3,p=19,i=n)

Explanation

(s,n)=>
  (t=setTimeout)(                     // set inital timeout
    c=`                               // c = code for timeout to execute
      console.log(" ".repeat(p)+"."); // print the current line
      p+=m=Math.random()*5|0;         // move walker 0 - 4 positions to the right
      p-=p>41|p<2?                    // if walker was moved out of bounds (2 - 41 instead
                                      //     of 0 - 39 because the random move of 0 - 4 to
                                      //     the right has not had the 2 subtracted yet)
        m:                            // undo the move
        2;                            // else subtract 2 to make the move -2 to 2
      --i&&t(c,d)                     // while we have steps remaining schedule next one
    `,
    d=s*1e3,                          // d = milliseconds to wait between steps
    p=19,                             // p = position of walker (0 indexed)
    i=n                               // i = steps remaining (needed to make n global)
  )

Test

console.log = s => result.textContent += s + "\n";
var solution = (s,n)=>(t=setTimeout)(c=`console.log(" ".repeat(p)+".");p+=m=Math.random()*5|0;p-=p>41|p<2?m:2;--i&&t(c,d)`,d=s*1e3,p=19,i=n)
<input type="number" id="seconds" value="0.1" /><br />
<input type="number" id="steps" value="30" /><br />
<button onclick="solution(+seconds.value,+steps.value)">Go</button>
<pre id="result"></pre>

user81655

Posted 2015-12-18T17:21:32.793

Reputation: 10 181

3

k4, 61 characters

f:{y{-1((y:1|40&y+-2+*1?5)#" "),".";."\\sleep ",$x;y}[x]\20;}

sample run:

  f[.1]30
                      .
                    .
                    .
                   .
                   .
                  .
                  .
                   .
                   .
                     .
                    .
                  .
                  .
                    .
                   .
                   .
                 .
                .
               .
               .
              .
            .
          .
         .
         .
          .
            .
              .
              .
                .

Aaron Davies

Posted 2015-12-18T17:21:32.793

Reputation: 881

2

Python 3, 154 bytes

import time
from random import*
w=int(input())
z=int(input())
g=19
c=6
s=" "
while c:
    c-=1
    s+=s
while z:
    z-=1
    if -1<g<40:
        print(s[:g]+'.')
    time.sleep(w)
    g+=randint(-2,2)

Generate a string of spaces greater than the maximum required length, then print that string ONLY up to the char at index 'g', then print a '.'. Finish by incrementing g by a random value in the range [-2:2], and repeat.

If anyone could help me golf down that horrific input block, I'd appreciate it.

Steve Eckert

Posted 2015-12-18T17:21:32.793

Reputation: 216

To golf the input, why not use sys.argv? – ASCIIThenANSI – 2015-12-18T19:06:58.523

1Also, instead of while z:, why not use for i in range(1,z)? – ASCIIThenANSI – 2015-12-19T01:44:47.703

I'm curious, how did you get that this is 154 bytes? http://bytesizematters.com/ gives a different count (even if you disable counting whitespace)

– p1xel – 2015-12-20T22:37:52.910

@ASCIIThenANSI: Hmm...by the time I add in the initial call to sys.argv and the import, I can't see how I can save any bytes doing that. And even with the extra lines to declare c then decrement c and z, it's still cheaper to do it this way, by my count. – Steve Eckert – 2015-12-21T16:47:57.000

@p1xel: I counted whitespaces internal to the line, just not leading or trailing whitespaces. Is there a different scoring standard that I'm unaware of? – Steve Eckert – 2015-12-21T16:50:05.470

@SteveEckert What exactly does c do? – ASCIIThenANSI – 2015-12-21T19:35:32.900

@ASCIIThenANSI c is regulating length when I'm generating my string of spaces s that I'm outputting a substring of prior to the .. It could be pretty much anything that won't make the string longer than whatever python's max string length is, but I haven't yet figured out how to do that using existing variables without increasing byte count. – Steve Eckert – 2015-12-21T20:20:24.090

@SteveEckert I'm pretty sure most people also count newlines: this is why you see golfed solutions compressed onto one line. Someone can correct me if I'm wrong. – p1xel – 2015-12-21T22:27:16.440

Whitespace counts, just an any other character. Assuming those 4 leading spaces are actually tabs, your code appears to be 177 bytes long. – Dennis – 2016-02-19T17:58:11.150

1

C funtion, 114

s=20,i,t;w(int n,float f){for(;i++<n;t=s,s+=rand()%5-2,s=s<0||s>39?t:s,usleep((int)(f*1e6)))printf("%*c.\n",s,0);}

Pretty much a direct translation of my bash answer.

Full test program:

s=20,i,t;w(int n,float f){for(;i++<n;t=s,s+=rand()%5-2,s=s<0||s>39?t:s,usleep((int)(f*1e6)))printf("%*c.\n",s,0);}

int main (int argc, char **argv) {
  w(10, 0.2);
  return 0;
}

Digital Trauma

Posted 2015-12-18T17:21:32.793

Reputation: 64 644