Code Golf: Your own pet ASCII snake

34

6

So, I wrote myself a one-liner which printed out a snake on the console. It's a bit of fun, and I wondered how I might condense my code...

Here's a (short) example output:

                +
                 +
                  +
                   +
                   +
                   +
                  +
                   +
                    +
                    +
                    +
                     +
                     +
                      +
                      +
                       +
                      +
                     +
                     +
                    +

Here's the specs:

  • In each line, a single non-whitespace character (whichever you like) is printed to the console, initially with 29 to 31 spaces padding to the left of it.
  • Each iteration, a random decision is made between these three actions
    • The amount of padding decreases by 1
    • The amount of padding remains the same
    • The amount of padding increases by 1

Do this 30 times, to print 30-segment long a snake to the console.

The shortest answer in bytes wins.

AJFaraday

Posted 2018-02-20T12:01:08.157

Reputation: 10 466

Can we return an array of lines? Are leading/trailing spaces or newlines allowed? – Shaggy – 2018-02-20T12:07:00.357

@Shaggy I want to see the snake. I don't care if it's an array, as long as it's printed to a console and you can see it. – AJFaraday – 2018-02-20T12:09:13.270

"is printed to the console" implies a full-program only, but the default on PPCG is to allow functions too (which I recommend) – Jonathan Allan – 2018-02-20T12:09:20.810

1I assume trailing spaces on each line are allowed, right? – Luis Mendo – 2018-02-20T13:20:25.570

What should happen on a screen with less than 30 columns for text? Can we start with cols/2 padding and iterate cols/2 times, or should the snake just wrap around? – kamoroso94 – 2018-02-20T22:32:45.353

1What does "random" mean? Uniformly random? Random from any distribution with positive support on each of the three outcomes? Random from any distribution whatsoever? Do the results have to be different on each run of the program? – Nathaniel – 2018-02-21T09:02:02.410

1

Note that, by default, random does not mean uniformly so. For example, the second part of my brainfuck answer is (as of now) perfectly valid, despite it generating a straight line most of the time.

– Jo King – 2018-02-21T15:11:02.510

Seriously has nobody made a golfing language yet that takes as input a Stack Exchange question ID number? – Lightness Races with Monica – 2018-02-21T15:41:14.950

1

Right now, there are two points that are unclear: 1) Does random mean uniformly random? (affects this answer) and 2) Must the output be different every time? (i.e., can the random number generator be unseeded? Affects this answer)

– James – 2018-03-02T20:41:12.033

Answers

14

05AB1E, 15 14 bytes

30DF2Ý<+ΩD0sú,

Try it online!

Uses 0.

Explanation

30DF2Ý<+ΩD0sú,
30D            # Push 30 to the stack (One for the amount of iterations we are going to perform and one for the initial padding)
   F           # Pop one of the 30s and perform the following that many times...
    2Ý          # Push [0,1,2] ...
      <         # and create [-1,0,1] from that
       +        # Add the last padding to every entry (e.g. 30 in the beginning resulting in [29,30,31]
        Ω       # Pick one of the results at random ...
         D      # and push it to the stack twice
          0     # Push 0 (Any character will work fine here) ...
           sú   # and pad it with the randomly chosen amount of spaces in the front
             ,  # Finally print the result with a trailing newline

Datboi

Posted 2018-02-20T12:01:08.157

Reputation: 1 213

39

05AB1E: 0-bytes, Try it online!... wait, no, almost though.

– Magic Octopus Urn – 2018-02-20T14:36:50.103

14

Random Brainfuck, 123 122 121 bytes

+[--[<]>>+<-]>+[->+>+>+<<<]++++++++++>>++<[>>[->+<<.>]>[-<+>]>?>+++<[>->+<[>]>[<+>-]<<[<]>-]>-->,<[-<<<+>>>]<<<<+.-<<.>-]

Try it online!

Random Brainfuck is an extension of brainfuck, with the helpful addition of the ? command, which sets the current cell to a random byte. This prints a snake made of !s, which looks more like footsteps than a snake funnily enough.

How It Works:

+[--[<]>>+<-]>+ Create the value 30
[->+>+>+<<<]    Copy it three times
++++++++++      Create a newline cell
>>++<            Adds 2 to the second copy to make it a space and move to the counter
[ While counter
  >>[->+<<.>]>[-<+>] Print out the padding cell number of spaces
  ?>+++<[>->+<[>]>[<+>-]<<[<]>-] Get 3-(random byte%3)
  >-->,<[-<<<+>>>]   Add (result-2) to the padding cell
  <<<<+.-<           Print an exclamation mark
  <<.                Print a newline
  >-                 Decrement counter
] end loop

Another solution that sticks to the letter of the question, rather than the spirit.

87 bytes

+[--[<]>>+<-]>+[->+>+>+<<<]++++++++++>++>[>[->+<<<.>>]>[-<+>]?[,<+>]?[,<->]<<<+.-<.>>-]

Try it online!

This one is heavily biased towards leaving the padding alone, but increasing or decreasing the padding are both equally possible. Each one has a slightly less than 1 in 256 chance to happen.

Jo King

Posted 2018-02-20T12:01:08.157

Reputation: 38 234

Very nice! I was unaware of the ? command. +1 – Grant Miller – 2018-02-23T16:39:58.440

@GrantMiller ? is only available in Random Brainfuck, not classic brainfuck – Jo King – 2018-02-23T23:01:51.957

8

C (gcc), 61 58 56 bytes

Answer edited to reflect rules changes...

i;f(s){for(s=i=31;--i;printf("%*d\n",s+=1-rand()%3,8));}

Try it online!

cleblanc

Posted 2018-02-20T12:01:08.157

Reputation: 3 360

save a byte by moving s+=1-rand()%3 to the printf function. i;f(s){for(s=i=31;--i;)printf("%*c\n",s+=1-rand()%3,43);} – Vaelus – 2018-02-21T02:37:08.537

@Vaelus That makes the first line have a varying amount of spaces instead of the 30 specified in the question. – Steadybox – 2018-02-21T07:52:38.947

@Steadybox Which is allowed in the comments apparently..

– Kevin Cruijssen – 2018-02-21T08:03:54.527

7

C# (.NET Core), 112 110 106 100 99 98 bytes

v=>{var r="";for(int t=30,i=t;i-->0;r+="+\n".PadLeft(t+=new System.Random().Next(3)-1));return r;}

-1 byte thanks to @raznagul.
-1 byte thanks to @auhmaan.

Explanation:

Try it online.

v=>{                      // Method with empty unused parameter and no return-type
  var r="";               //  Result-string, starting empty
  for(int t=30,           //  Temp-integer, starting at 30
      i=t;i-->0;          //  Loop 30 times
    r+=                   //   Append the result-String with:
       "+\n"              //    The character and a new-line,
            .PadLeft(     //    left-padded with `t` spaces,
                     t+=new System.Random().Next(3)-1));
                          //    after `t` first has been changed with -1, 0, or 1 randomly
  return r;}              //  Return the result-string

Kevin Cruijssen

Posted 2018-02-20T12:01:08.157

Reputation: 67 575

One strange thing: If I call new Random().Next() multiple times locally (.net Framework Version 4.6.1) I always get the same result. I need to add a Thread.Sleep(10) between the call to reliably get different results. With a sleep time of less than 10ms I sometimes still get the same result. So .net-Framework and TIO (.net-Core) have different PRNGs or at least use different seeds. If I switch your program in TIO to C#-mono I get the same behavior as I get locally in .net-Framework. – raznagul – 2018-02-20T13:26:14.860

@raznagul Hmm, that output with C# (Mono C# compiler) is indeed weird.. – Kevin Cruijssen – 2018-02-20T13:30:48.360

3@raznagul new Random() uses the time as the seed so in a tight loop the time is the same and so the result is the same. – TheLethalCoder – 2018-02-20T15:28:01.037

@TheLethalCoder: Yes, that is what I (more or less) expected. The strange things are that 1) .net-Core (at least on TIO) behaves differently. 2) That I need Thread.Sleep(10) to reliably get different results and Thread.Sleep(1) or even 9ms is not enough. – raznagul – 2018-02-20T15:33:22.210

@raznagul Well sleeping for 1, 9 or 10ms should all sleep for the same time depending on other processes running... odd indeed. – TheLethalCoder – 2018-02-20T15:37:47.817

7

Retina, 24 bytes


30* +
-29{¶<`^
 
S,2@1`

Try it online!

Explanation


30* +

Initialise the working string to the first line, i.e. 30 spaces and a +.

-29{¶<`^
 

There's a space on the second line. -29{ wraps the remainder of the program in a loop, which is run 29 times. ¶< prints the working string at the beginning of each loop iteration with a trailing linefeed. The atomic stage itself inserts a space at the beginning of the string (the basic idea is to insert one space, and then randomly remove 0–2 spaces, because that's a byte shorter than randomly choosing between deletion, inserting and no-op).

S,2@1`

This matches the empty regex against the input, which gives us every position between characters (and the start and end of the string). Then ,2 keeps only the first three matches, i.e. the matches after zero, one and two spaces. @ selects a random one of those three matches. Then the split stage (S) splits the input around that match. And the 1 tells it to keep only the second part of the split. In other words, we discard everything up to our random match.

The 30th line, which is the result of the final loop iteration, is printed implicitly at the end of the program.

Martin Ender

Posted 2018-02-20T12:01:08.157

Reputation: 184 808

You know what's even shorter than removing 0--2 spaces? Shuffling spaces around!. By the way, the new Retina is great :D

– Leo – 2018-02-22T05:48:01.203

7

VBA, 60 59 49 Bytes

For l=1To 30:?Spc(30+i)"+":i=i+Sgn(Rnd()-.5):Next

Paste it in the Immediate window and hit enter. (Make sure explicit declaration is turned off!)

Far more likely to move than to stay in a line (i.e. actions are not equally weighted) but that was not a specified requirement (Fortunately!)

{EDIT} Saved 1 byte by removing the space between =1 and To

{EDIT2} Saved 10 bytes thanks to remoel's comment

Old Versions:

'V1
i=30:For l=1 To 30:?String(i," ")&"+":i=i+Sgn(Rnd()-.5):Next
'V2
i=30:For l=1To 30:?String(i," ")&"+":i=i+Sgn(Rnd()-.5):Next

Chronocidal

Posted 2018-02-20T12:01:08.157

Reputation: 571

5Welcome to PPCG! – Martin Ender – 2018-02-20T14:53:24.613

2You can save a few bytes by replacing String(i," ") to Spc(30+i) then remove i=30: . Or -1 byte by removing & . :) – remoel – 2018-02-21T05:28:55.577

7

C, 56 bytes

n;f(p){n>29?n=0:f(printf("%*d\n",n++?p-rand()%3:31,0));}

Try it online!

Explanation:

n; // As a global variable, n is initialized to zero.
f(p)
{
    // Call the function recursively until n > 29.
    n > 29

        // At the end, set n back to zero.
        ? n=0

        // On the first iteration, n == 0 and p has an indeterminate value.
        // 'n++ ? p-rand()%3 : 31' returns 31 (without reading p), and thus
        // 30 spaces get printed. printf() returns the number of characters
        // printed, 32 (30 spaces + '0' + '\n').
        //    On subsequent iterations, p has the value the previous printf
        // call returned, which is the padding on last iteration + 2. Also,
        // n > 0, so the same expression now returns p-rand()%3, and thus
        // the padding changes either by -1, 0, or 1 spaces. The function
        // is again called with the value of the current line's padding + 2.
        : f(printf("%*d\n", n++ ? p-rand()%3 : 31, 0));
}

C (gcc), 55 bytes

n;f(p){n=n<30&&f(printf("%*d\n",n++?p-rand()%3:31,0));}

Depends on f "returning" the value assigned to n in the function, which is undefined behaviour, but works consistently with gcc when no optimizations are enabled.

Try it online!

Steadybox

Posted 2018-02-20T12:01:08.157

Reputation: 15 798

6

APL (Dyalog), 20 bytes

1 byte saved thanks to ngn

↑'+'↑⍨¨-+\30,2-?29⍴3

Try it online!

Uriel

Posted 2018-02-20T12:01:08.157

Reputation: 11 708

¯2+ ---> 2- – ngn – 2018-02-20T12:23:13.260

6

JavaScript (ES8), 63 62 60 bytes

Includes a trailing newline. *2-1 could be replaced with -.5 for a 1 byte saving but the chances of each line being the same length as the previous line would be greatly increased. Of course, as "random" isn't defined in the challenge, the RNG could be replaced with new Date%3-1 for a total byte count of 55.

f=(x=y=30)=>x?``.padEnd(y+=Math.random()*2-1)+`+
`+f(--x):``

Saved a byte thanks to someone who deleted their comment before I could catch the name. I'd actually tried it this way with repeat and padStart but didn't think to try padEnd - don't know why!

o.innerText=(
f=(x=y=30)=>x?``.padEnd(y+=Math.random()*2-1)+`+
`+f(--x):``
)()
<pre id=o>

Bonus

For the same number of bytes, here's a version that takes the number of starting spaces & iterations as input.

f=(x,y=x)=>x?``.padEnd(y)+`+
`+f(--x,y+Math.random()*2-1):``

o.innerText=(
f=(x,y=x)=>x?``.padEnd(y)+`+
`+f(--x,y+Math.random()*2-1):``
)(i.value=30);oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o>

Shaggy

Posted 2018-02-20T12:01:08.157

Reputation: 24 623

f=(x=y=30)=>x?\+\n`.padStart(y+=Math.random()*2-1)+f(--x):``` is one byte shorter.

(Note: Since SO doesn't allow line breaks in comments, I had to type \n instead of actually using a line break.) – Stefnotch – 2018-02-20T18:52:39.700

Thanks, @Stefnotch. Unfortunately, even with an initial value of y=31, there would be a possibility of the first line being too short. https://tio.run/##BcFLDsIgEADQvSeZkUCs7kzQE7hyqSYzKfRjKBCYGHp6fO/LP65jWbPomJzvY4o1BW9CmgH6ZKHZ3V4GtDet253UgUxm9xQuAruyD5bFFI4ubYDHsx5QTdDwStQR0NQcVqF3pNfpY4KPsyzY/w

– Shaggy – 2018-02-20T19:01:22.053

1Correct me if I'm wrong, but doesn't your current solution also suffer from that issue? – Stefnotch – 2018-02-21T20:55:47.113

Not quite, @Stefnotch. The first line should contain 29-31 spaces. In my version, we start with y=30, add -1, 0 or 1 to that and then pad an empty string out to that length, giving us the required number of spaces. In your version, though, the string we're padding is already 2 characters long so the padStart would only add 27-29 spaces to it. Even if the initial value of y was raised to 31, which wouldn't cost any bytes, we'd still only end up with 28-30 spaces. – Shaggy – 2018-02-21T21:15:33.167

Oh, I see. Then, couldn't you just use an initial value of 32? (29-31 spaces) – Stefnotch – 2018-02-21T21:16:48.610

@Stefnotch, I could but it would cost me more than the 1 byte saving as x and y would have to be initiated individually. – Shaggy – 2018-02-21T21:18:49.230

1The first line should have exactly 30 spaces, according to the challenge. – Nit – 2018-02-23T13:34:08.420

1@Nit, the OP has confirmed that the first line may contain 29-31 spaces but has yet to edit that fact into the challenge, despite repeated requests to do so. – Shaggy – 2018-02-23T13:45:12.757

6

Python 2 , 83 65 64 bytes

Straightforward approach:

import os
k=30
exec"print' '*k+'+';k+=ord(os.urandom(1))%3-1;"*k

Try it online!

Thanks to @Rod for saving some bytes! Thanks to @ovs for -1 byte!

Edit: changed variable name and output string to the letter 's'

More snake-like output for 88 bytes:

from random import*
s=[30,0]
exec"print' '*sum(s)+'(S)'[s[-1]+1];s+=[randint(-1,1)];"*30

Gábor Fekete

Posted 2018-02-20T12:01:08.157

Reputation: 2 809

1I like this. Really neat solution. – linemade – 2018-02-20T14:01:25.307

6

Java 8, 89 87 bytes

First golf, I'm sure it could be much better..

Edit: Fixed first line thanks to Steadybox.

l->{for(int a=31,b=a;--a>0;){System.out.printf("%"+b+"c\n",'+');b+=2-Math.random()*3;}}

Try it online!

 l->{                                           //Begin lambda
    for(int a=31,b=a;--a>0;)                  //Initialise vars, loop through 30 lines
    {
        System.out.printf("%"+b+"c\n",'+');     //Print result
        b+=2-Math.random()*3;                   //Change padding by -1, 0, or 1
    }

JSchiff

Posted 2018-02-20T12:01:08.157

Reputation: 61

5Welcome to PPCG! :) – Shaggy – 2018-02-20T22:27:05.750

283 bytes – Steadybox – 2018-02-20T22:43:08.980

5

Java 8, 131 129 127 126 119 108 101 bytes

v->{String r="";for(int i=30,j,t=i;i-->0;r+="+\n")for(j=t+=Math.random()*3-1;j-->0;r+=" ");return r;}

Explanation:

Try it online.

v->{                     // Method with empty unused parameter and String return-type
  String r="";           //  Result-String, starting empty
  for(int i=30,j,t=i;    //  Two index integers, and a temp integer (starting at 30)
      i-->0;             //  Loop 30 times:
      r+="+\n")          //    After every iteration: Append the character and a new-line
    for(j=t+=Math.random()*3-1;
                         //   Change `t` with -1, 0, or 1 randomly
        j-->0;r+=" ");   //    And append that many spaces to the result-String
  return r;}             //  Return the result-String

Old 119 byte answer:

v->{String s="",r=s;int i=90,t=30;for(;i-->t;s+=" ");for(;i-->0;t+=Math.random()*3-1)r+=s.substring(t)+"+\n";return r;}

Explanation:

Try it online.

v->{                      // Method with empty unused parameter and String return-type
  String s="",            //  Temp-String, starting empty
         r=s;             //  Result-String, starting empty
  int i=90,t=30;          //  Temp integer, starting at 30
  for(;i-->t;s+=" ");     //  Fill the temp String with 60 spaces
  for(;i-->0;             //  Loop 30 times:
      t+=Math.random()*3-1//    After every iteration: Change `t` with -1, 0, or 1 randomly
    r+=s.substring(t)     //   Append the result with `60-t` amount of spaces
       +"+\n";            //   + the character and a new-line
  return r;}              //  Return the result-String

Kevin Cruijssen

Posted 2018-02-20T12:01:08.157

Reputation: 67 575

5

PHP, 61 bytes

for($p=32;$i<30;$i++)echo str_pad("+
",$p+=rand(-1,1),' ',0);

Try it online!

chocochaos

Posted 2018-02-20T12:01:08.157

Reputation: 547

8$i<30;$i++ can be $i++<30; to save 2 bytes. – Kevin Cruijssen – 2018-02-20T13:44:10.920

255 bytes: for($p=30;$i++<30;$p+=rand(-1,1))printf("%{$p}s\n",'+'); (the \n is counted as 1 char, and should be replaced by a real newline) – Ismael Miguel – 2018-02-23T15:37:32.860

2Alternative 55-byte long, without warnings: for($i=$p=30;$i--;$p+=rand(-1,1))printf("%{$p}s\n",'+'); – Ismael Miguel – 2018-02-23T15:41:08.920

5

Charcoal, 14 bytes

× ³⁰F³⁰«↙+M‽³→

Try it online! Link is to verbose version of code. Explanation:

× ³⁰            Print 30 spaces (forces the desired indentation)
    F³⁰«        Repeat 30 times
        ↙+      Print a `+` and move down and left one square
          M‽³→  Move right a random number of squares from 0 to 2

Would be only 10 bytes if there was no initial indentation requirement.

Neil

Posted 2018-02-20T12:01:08.157

Reputation: 95 035

@KevinCruijssen Hmm, that's awkward, because Charcoal likes to trim by default. – Neil – 2018-02-20T12:26:37.683

4

R, 72 69 67 bytes

cat(sprintf(paste0("% ",cumsum(c(30,sample(3,29,T)-2)),"s"),"+\n"))

Thanks to Zahiro Mor for 2 extra bytes!

Try it online!

plannapus

Posted 2018-02-20T12:01:08.157

Reputation: 8 610

Switching from sample(3,29,T)-2 to runif(29,-1,1) will reduce byte count by 2 but moves are not equally likely anymore. And could you also switch to paste("%" instead of paste0("% " or am I missing something here? – Rift – 2018-02-20T16:45:13.827

@Rift if i was using paste the resulting strings would be of the form % 30 s instead of % 30s. As you said runif would mess up the probabiities. – plannapus – 2018-02-20T17:46:00.357

Locally sprintf("%30s"), sprintf("% 30s") and sprintf("% 30 s") return the same results for me. But on TIO only the first two have identical results, so paste0("%" should save a byte. And there is no requirement that every move has the same probability. – Rift – 2018-02-21T12:41:59.023

4

Perl, 36 bytes

perl -E '$#a=29;map{$#a+=rand(3)-say"@a -"}@a'

Ton Hospel

Posted 2018-02-20T12:01:08.157

Reputation: 14 114

So good. I always forget you can set an array length like that... and using say for subtraction. Am I right in thinking it doesn't change the number of runs when $#a is incremented because it's not a reference? – Dom Hastings – 2018-02-20T16:38:47.747

@DomHastings: It's because I use map which seems to first lay out the elements on the stack. for does not and would have had an unpredictable loop length – Ton Hospel – 2018-02-20T18:11:34.510

That's really useful to know. Thanks! – Dom Hastings – 2018-02-20T19:54:52.110

Nice golfing. I tried to shave off another byte with perl -E 'map{$#a+=rand(3)-say"@a -"}@a=1..30', but that sometimes (not every time) resulted in segmentation fault. Could it be a bug in perl v5.22.1 and v5.16.3? – Kjetil S. – 2018-02-21T16:49:18.430

@Kjetil Yes, that is a well known problem that probably will never be fixed. When looping an array the entries don't get an extra refcount, so if you delete them they are freed by the time the loop reaches them and you hit freed memory. Fortunately you never do this in real programs. – Ton Hospel – 2018-02-21T18:20:39.843

4

Japt, 13 bytes

Returns an array of lines.

30ÆQù1nH±1n3ö

Test it


Explanation

30Æ               :Create the range [0,30) and pass each through a function
   Q              :  The " character
    ù             :  Pad start to length...
           3ö     :    Random element from the range [0,3)
         1n       :    Subtract 1
       H±         :    Add the result of that to H (inititally 32)
     1n           :    Subtract 1 to avoid the possibility of the first line being 33 characters long in total

Bonus

For 2 bytes less, here's a version that takes the number of starting spaces & iterations as input.

U°ÆQùU±1n3ö

Try it


Alternative RNGs

The last 4 bytes can be replaced with any of the following:

MrJ1     :A random float between -1 and 1
Jõ ö     :Generate the range [-1,1] and return a random element
3ö É     :An alternative way of writing the method used above
½nMr     :0.5 subtracted from a random float between 0 and 1

Shaggy

Posted 2018-02-20T12:01:08.157

Reputation: 24 623

1

Wow, can't believe we're winning at the moment! I think you can save a byte with this (on mobile so I can't really verify)

– ETHproductions – 2018-02-20T13:52:04.607

@ETHproductions: Ha! That's identical to what I started out with. The problem is, though, if -1 is returned by the RNG on the first iteration, we'll end up with a total line length of 29 when it should be 30, 31 or 32. – Shaggy – 2018-02-20T13:55:07.353

Hmm, I'm confused about how your version gets around that then... Also, I believe OP has clarified in the comments that they don't care if an extra space is removed or added in the initial iteration. – ETHproductions – 2018-02-20T13:59:02.017

Actually I'm confused by "when it should be 30, 31, or 32"—where is that required? – ETHproductions – 2018-02-20T14:01:09.723

@ETHproductions: We start with 30 and then add -1, 0 or 1 giving us 29, 30 or 31 - add the " and that gives us a total length of 30, 31 or 32 for the first line. – Shaggy – 2018-02-20T14:04:38.470

Oh ok, I didn't realize you meant the length of the entire line. Sorry if this is another dumb question, but how could my suggestion end up with an initial line length of 29 (28 spaces)? – ETHproductions – 2018-02-20T14:14:41.810

@ETHproductions: if the RNG gives us -1 on the first iteration, U becomes 29 and ù would pad the start of the line with spaces until the total line length is 29 - 28 spaces plus the " character. – Shaggy – 2018-02-20T14:40:32.177

Hah, I thought the quote was just appended at the end of the string—sorry for my ignorance :P – ETHproductions – 2018-02-20T16:44:17.593

Doors Japt really not have a decrement command??? – caird coinheringaahing – 2018-02-23T07:16:35.383

@cairdcoinheringaahing, ± is the Japt shortcut for +=. It could be replaced with µ, which is the shortcut for -=, but the results would be the same. – Shaggy – 2018-02-23T07:25:19.677

4

Ruby, 45 39 bytes

x=30
x.times{puts' '*(x+=rand(3)-1)+?S}

Try it online!

Modifying x during the loop does not affect the loop counter. I chose S as a particularly snakelike output character.

-6 bytes: Use rand(3)-1 instead of [-1,0,1].sample. Thanks, Eric Duminil!

benj2240

Posted 2018-02-20T12:01:08.157

Reputation: 801

You can save two bytes with x.map instead of x.times (equivalent since you don't use the return value) – RJHunter – 2018-02-21T02:11:26.400

I don't think I can... map is defined on Enumerable, which Integer isn't. – benj2240 – 2018-02-21T02:44:37.973

1Oops, you're right, ignore me! – RJHunter – 2018-02-21T03:34:08.527

1OK I've got a better one: rand -1..1 is five bytes shorter than [-1,0,1].sample – RJHunter – 2018-02-21T04:36:14.960

1@RJHunter: Or rand(3)-1 for 6 bytes less. – Eric Duminil – 2018-02-21T07:52:59.067

You can get a one-liner : (x=30).times{puts' '*(x+=rand(3)-1)+?S} without changing the byte-count. – Eric Duminil – 2018-02-21T07:59:43.010

1(x=30).times{puts' '*x+?+;x+=rand(3)-1} (same size) will print exactly 30 spaces for the head of the snake as requested by the challenge – Asone Tuhid – 2018-02-28T09:54:01.310

4

Swift, 101 bytes

import UIKit
var g=29;for _ in 0...g{print((0..<g).map{_ in" "}.joined(),0);g+=Int(arc4random()%3)-1}

Explanation

A full program. This uses a rather odd trick: arc4random() is a member of the Darwin module, but UIKit also comes with this function installed, so it saves a byte :) Also uses one of my Swift golfing tips for repeating strings an arbitrary number of times.

import UIKit        // Imports the UIKit module, necessary for the RNG.
var g=29;           // Declares an integer variable g by assigning it to 30.
for _ in 0 ... g {  // Execute the code block 30 times (for each integer in [0; g]):
 print(             // Output the following:
  (0..<g).map       // For each integer in [0; g)...
   {_ in" "}        // ... return a literal space character. 
    .joined()       // ... And join the result to a single string.
             ,0     // Also print a "0" preceded by a single space (g starts from 29).
 );
g+=                 // Increment the variable g by...
   arc4random()%3   // ... A random integer, modulo 3...
   Int(...)-1       // ... Casted to an integer (yes, this is needed!) and decremented.
}

Mr. Xcoder

Posted 2018-02-20T12:01:08.157

Reputation: 39 774

Doesn't for _ in 0 ... g execute the code block 29 times now instead of 30 (loop from 0 to 29 (exclusive))? – Kevin Cruijssen – 2018-02-20T16:21:05.860

@KevinCruijssen No, 0...g generates all the integers in [0; g]. My bad, fixed the explanation. 0..<g would generate the integers in [0; g) :P – Mr. Xcoder – 2018-02-20T16:22:05.697

Ah, the [0; g) you've edited to [0; g] indeed confused me. :) Hmm, but isn't it possible to start at g=30 and loop [1; g] in that case? – Kevin Cruijssen – 2018-02-20T17:55:20.903

@KevinCruijssen Looping over either [0; g) or [1; g] would definitely be possible if I choose g=30 instead, but then print(...,0) needs to be changed to print(...+"0"), because an additional (extraneous) space would be prepended before the 0 otherwise. Either way, the byte count remains the same. – Mr. Xcoder – 2018-02-20T17:58:06.107

4

R, 54 53 bytes

cat(sprintf('
%*s',cumsum(c(30,sample(3,29,T)-2)),0))

Similar idea as above, but with shortened sprintf code and a shorter character string literal. Instead of \n (two bytes) I’m using a literal line break (one byte).

Try it online!

Konrad Rudolph

Posted 2018-02-20T12:01:08.157

Reputation: 1 067

A field width or precision (but not both) may be indicated by an asterisk *: in this case an argument specifies the desired number. I've been using sprintf for years and somehow always missed that part... Thanks for the reminder! – plannapus – 2018-02-20T18:51:52.853

1The second line is sometimes indented two spaces instead of one. – Scott Milner – 2018-02-21T05:18:56.473

@ScottMilner Found some time to fix it. – Konrad Rudolph – 2018-02-21T14:54:09.593

4

SenseTalk, 237 198 Bytes

This is a language that I came to know and love about a decade ago. It's the scripting language that drives the automated testing tool Eggplant Functional. I was an avid user of the tool for many years before joining the company for a while. It's not the most golf-capable language, but I find it very enjoyable to write in. Golfing in it is actually quite challenging as the language is meant to be verbose and English-like... took me quite a while to get it down to 237 bytes.

set s to "                              +"&lf
set p to s
repeat 30
set a to random(0,2)
if a equals 0
delete first char of p
else if a equals 1
put " " before p
end if
put p after s
end repeat
put s

Ungolfed/Explanation

set the_snake to "                              +"&lf #assign the first line of the snake
set previous_line to the_snake                        #set up for the loop

repeat 30 times                                       #loop 30x
    set action to random(0,2)                         #random add/subtract/stay the same

    if action equals 0
        delete the first character of previous_line   #SenseTalk really shines at string manipulation
    else if action equals 1
        put " " before previous_line                  #insert a character at the beginning
    end if

    put previous_line after the_snake                 #plop the new segment into the string
end repeat                                            #close the loop

put the_snake                                         #print to standard out

Edit: Saved 36 bytes thanks to @mustachemoses

Allen Fisher

Posted 2018-02-20T12:01:08.157

Reputation: 219

1Is the whitespace necessary? – MustacheMoses – 2018-02-27T05:52:38.497

I've a lot of respect for this. Particularly against the background of 'golfing languages' which seem to exist to be utterly unreadable, but short. It's nice to have an example that's just showing what you can do with your language. – AJFaraday – 2018-02-27T09:11:15.343

1Good call @MustacheMoses! Updated. – Allen Fisher – 2018-02-28T04:17:55.867

I count 198 bytes (well, the userscript counts that many) – HyperNeutrino – 2018-02-28T05:16:55.490

@AllenFisher Do you have a standalone interpreter or compiler for this language that I can use without getting a Eggplant demo? – MustacheMoses – 2018-02-28T18:15:57.297

@MustacheMoses I wish I did. They used to have one, but when TestPlant acquired the EP tool, they shelved it. – Allen Fisher – 2018-02-28T21:55:12.437

@HyperNeutrino yeah I realized I was using the wrong operator in my counting script... updated – Allen Fisher – 2018-02-28T22:00:54.200

3

J, 23 bytes

echo(8":~+/)\31,1-?29$3

Try it online!

FrownyFrog

Posted 2018-02-20T12:01:08.157

Reputation: 3 112

3

PowerShell, 42 bytes

1..($l=30)|%{" "*$l+"x";$l+=-1,0,1|Random}

Try it online!

Loops from 1 to $l=30. Each iteration we put $l spaces plus an x onto the pipeline as a string, then += either of -1, 0, 1 based on Get-Random into $l for the next loop. Those strings are gathered from the pipeline and an implicit Write-Output gives us a newline-separated list for free.

AdmBorkBork

Posted 2018-02-20T12:01:08.157

Reputation: 41 581

3

Jelly, 18 bytes

1ŒRX+
30ǒС⁶ẋ;€0Y

Try it online!

The chosen character is 0. If returning a list of list of characters is allowed, then the Y can be dropped and the submission can be turned into a niladic chain for 17 bytes. Alternative.

How it works

30ǒС⁶ẋ;€0Y | Niladic main link.
30           | Starting from 30...
  ǒС       | ... Repeat the helper link 29 times and collect the results in a list.
             | (This list includes the first 30, so there are actually 30 numbers).
      ⁶ẋ     | Repeat a space that many times, for each item in the list.
        ;€0  | Append a 0 to each.
           Y | And join by newlines.
-------------+
1ŒRX+        | Monadic helper link. Alternatively, you can use µ1ŒRX+µ instead of the Ç.
1            | The literal one.
 ŒR          | Symmetric range from –1 to 1.
   X+        | Choose a random number therein and add it to the argument.

Jelly, 16 bytes

Combining mine, Erik’s and Jonathan’s solutions, we can golf this down to 16 bytes. The chosen character is 1.

’r‘X
30ǒСṬ€o⁶Y

Try it online!

Thanks to Jonathan Allan for the heads-up (on Ṭ€o⁶).

Mr. Xcoder

Posted 2018-02-20T12:01:08.157

Reputation: 39 774

You could use Ṭ€o⁶ in place of ⁶ẋ;€0 like my 18 byter does and get to down to 17. – Jonathan Allan – 2018-02-21T01:00:40.217

@JonathanAllan Thank you! Combining the three Jelly answers, I actually ended up having 16 bytes. But I posted that as a secondary solution because it is not entirely mine. :-) – Mr. Xcoder – 2018-02-21T05:16:45.333

3

Bash, 53

  • 3 bytes saved thanks to @Dennis
for((i=p=30;i--;p+=RANDOM%3-1));{ printf %${p}s+\\n;}

Try it online.

Digital Trauma

Posted 2018-02-20T12:01:08.157

Reputation: 64 644

p+=RANDOM%3-1 works too. – Dennis – 2018-02-20T18:47:14.630

@Dennis Yes of course! Thanks! – Digital Trauma – 2018-02-20T19:35:14.493

3

Octave, 53 51 50 49 bytes

printf('%*d\n',[a=31+cumsum(randi(3,1,30)-2);~a])

Try it online!

Saved 1 byte by no longer doing any looping. Saved another as Octave has printf as well as fprintf.

This new code creates an array of 30 random integers in the range -1:1. It then cumulatively sums the array and adds 30, which gives the desired sequence.

The result is printed using fprintf with a format that says "A decimal number, padded to a specified width, followed by a new line. The width will be the first value input, and the decimal number will be the second value input. If the number of values input is more than this, Octave will keep repeating the print automatically to get the desired output.

To achieve the looping then, we need only interleave zeros between the sequence array so the fprintf function uses each value in the sequence as a width, and each zero as the digit to be printed.

Prints an output like:

                              0
                             0
                              0
                             0
                              0
                               0
                              0
                               0
                              0
                              0
                             0
                            0
                           0
                           0
                           0
                          0
                           0
                            0
                             0
                              0
                              0
                             0
                             0
                              0
                               0
                              0
                              0
                               0
                               0
                                0

The above code doesn't always print exactly 30 spaces on the first line. It will be either 29, 30, or 31. To correct that, you would use this 53 byte version:

x=31;for i=2:x;fprintf('%*d\n',x,0);x+=randi(3)-2;end

Tom Carpenter

Posted 2018-02-20T12:01:08.157

Reputation: 3 990

You can save two bytes: x=31;for i=2:x;fprintf('%*d\n',x+=randi(3)-2,0);end – Kevin Cruijssen – 2018-02-21T09:11:51.120

@KevinCruijssen I thought about that, but it doesn't work the same. It would result in the first line starting with either 29, 30, or 31 spaces. – Tom Carpenter – 2018-02-21T09:13:16.073

1@KevinCruijssen in fact, never mind. I've just noticed the OPs comments saying that is allowed. – Tom Carpenter – 2018-02-21T09:14:07.023

Yep. It's a bit annoying a rule is in the comment (especially since it contradicts with the current challenge description..). I've asked OP to edit the challenge to reflect you can start with 29, 30 or 31, since he seems to allow it in the comments. – Kevin Cruijssen – 2018-02-21T09:19:34.357

3

Python 3.6, 84 73 69 bytes

from random import*
x=30
exec("print(' '*x+'+');x+=randint(-1,1);"*x)

Thanks to @WheatWizard for -11 bytes. Thanks to @JoKing for -4 bytes.

MustacheMoses

Posted 2018-02-20T12:01:08.157

Reputation: 131

Since you don't end up using i you can use for i in[1]*30 instead to save bytes. – Post Rock Garf Hunter – 2018-02-23T06:31:35.083

You can also from random import* so that you don't need the random. later on. And you can remove the newline space after your :. – Post Rock Garf Hunter – 2018-02-23T06:32:18.790

And if you change 30 to 29 the "+".rjust(x) can be replaced with " "*x+"+". – Post Rock Garf Hunter – 2018-02-23T06:35:20.110

Actually regarding my last comment it should be 30 spaces not 29. Your current answer only puts 29 spaces and thus fails to meet the spec. This can be fixed by changing 30 to 31. – Post Rock Garf Hunter – 2018-02-23T06:59:33.797

1@WheatWizard Thanks! I've added your changes and credited you as well. I changed [1]*30 to [1]*x because it's one byte shorter. – MustacheMoses – 2018-02-23T19:32:01.097

69 bytes – Jo King – 2018-02-27T03:12:20.337

@JoKing Thanks I'll edit in your changes. – MustacheMoses – 2018-02-27T05:50:04.600

3

ES5, 97 95 81 bytes

for(p=i=30;i--;)console.log(Array(p).join(" ",r=Math.random()*3|0,p+=r>1?-1:r)+0)

ES5, 112 98 bytes if function format is needed:

function a(){for(p=i=30;i--;)console.log(Array(p).join(" ",r=Math.random()*3|0,p+=r>1?-1:r)+0)}a()

Kyle Fairns

Posted 2018-02-20T12:01:08.157

Reputation: 131

2Welcome to PPCG! I think your variables have to be declared inside of a function - _=>{p=30;for(i=0;i<p;i++){console.log(Array(p).join(" ")+"+\n");r=~~(Math.random()*3);p+=r==2?-1:r}} – Oliver – 2018-02-23T16:37:45.047

That'll kill the bytes, I'll tell you that. ES5 doesn't include the arrow functions by default.

I'll update – Kyle Fairns – 2018-02-23T16:46:44.190

@Oliver, function format added :) – Kyle Fairns – 2018-02-23T16:52:42.767

Nice! I'm not sure when it was introduced, but I think you can replace join(" ") with join\ `` – Oliver – 2018-02-23T16:54:33.313

@Oliver I'm not sure you could do that in ES5, could you? I thought that was a template literal added in ES6? – Kyle Fairns – 2018-02-23T16:56:07.060

Maybe, I'm not sure when that was introduced. Why not use ES6? – Oliver – 2018-02-23T16:56:57.713

@Oliver It's more of a challenge, and there was already an ES8 answer which takes the full syntactical sugar of Javascript and turns it into some awesome. – Kyle Fairns – 2018-02-23T16:59:28.110

Welcome to PPCG! Here are some quick improvements to get you down to 81 bytes.

– Shaggy – 2018-02-24T09:19:09.487

@Shaggy .repeat is an ES6 function, so won't work for this version. – Kyle Fairns – 2018-02-26T10:13:37.653

Huh, it looks like repeat has already become so invaluable I'd completely forgotten it wasn't introduced until ES6. Here's an alternative 81 byte version, so.

– Shaggy – 2018-02-26T10:26:32.133

@Shaggy, looks good, and has shaved 14 bytes off of the answer I gave, nice job – Kyle Fairns – 2018-02-26T11:26:54.443

3

Lua, 81 75 bytes

n=30;for i=1,n do print(("%-"..n.."s+"):format(" "))n=n-2+math.random(3)end

In for i=1,n ... the to_exp n is evaluated only once before entering the loop, saving one byte.

-6 thanks to @user202729

Try it online!

lqnrd

Posted 2018-02-20T12:01:08.157

Reputation: 31

1Welcome to PPCG! You may want to add a TIO link to your post so people can test your program more easily. – user202729 – 2018-02-26T15:53:10.220

You can golf your answer down to 76 bytes. Besides the page Tips for golfing in Lua may be useful.

– user202729 – 2018-02-26T15:54:42.327

75 bytes. – user202729 – 2018-02-26T15:58:52.980

2

Red, 54 bytes

loop n: 30[loop n[prin" "]print"+"n: n - 2 + random 3]

Try it online!

Galen Ivanov

Posted 2018-02-20T12:01:08.157

Reputation: 13 815

2

Pyth, 21 19 16 15 bytes

Thanks to Rod for saving 2 bytes and Mr. Xcoder for saving another 3 :)

Uses 0

VK30p*KdZ=+KtO3

Try it online!

robbie

Posted 2018-02-20T12:01:08.157

Reputation: 427

2

Python 2, 73 bytes

from random import*
l=c=30
while c>0:l+=randint(-1,1);print' '*l+"+";c-=1

Try it online!

ElPedro

Posted 2018-02-20T12:01:08.157

Reputation: 5 301

1I really like the idea of creating a snake in Python – LuudJacobs – 2018-02-21T13:56:26.760

I must have been half asleep yesterday - I didn't even think about that ;-) – ElPedro – 2018-02-21T14:14:00.203

2

Mathematica, 74 bytes

""<>(" "&~Array~#<>"+
"&)/@Accumulate@Prepend[{-1,1}~RandomInteger~29,30]&

Pure function. Takes no input and returns a string as output.

LegionMammal978

Posted 2018-02-20T12:01:08.157

Reputation: 15 731

2

Julia 0.6, 52 49 bytes

Full program, prints a snake with 0. I usually prefer comprehensions to for...end blocks because comprehensions return things. But since I'm printing anyway this is shorter, and you can use newlines at no cost (meaning equal to ;) for a nice readable golf. Saved a byte by using 1:n instead of 1:30 and two bytes with println(" "^n,0) instead of println(" "^n*"+").

n=30
for i=1:n
println(" "^n,0)
n+=rand(-1:1)
end

Try it online!

gggg

Posted 2018-02-20T12:01:08.157

Reputation: 1 715

2

K4, 26 bytes

Solution:

-1(-31+\0,-1+29?3)$\:,"$";

Example:

q)k)-1(-31+\0,-1+29?3)$\:,"$";
                              $
                             $
                             $
                            $
                           $
                            $
                             $
                              $
                              $
                              $
                              $
                              $
                               $
                                $
                               $
                              $
                               $
                              $
                              $
                               $
                                $
                                 $
                                 $
                                $
                                 $
                                $
                               $
                                $
                                $
                                 $

Explanation:

Build a list of negative numbers to left-pad "$", perform padding and print to stdout.

-1(-31+\0,-1+29?3)$\:,"*"; / the solution
-1                       ; / print to stdout and swallow return
                     ,"$"  / enlist "$" (e.g. ["$"])
  (              )$\:      / pad right with each-left
             29?3          / 29 choose 3, takes from 0 1 2
          -1+              / subtract 1, so range is -1 0 1
        0,                 / join 0
      +\                   / sums
   -31                     / add to -31

Bonus:

27 byte version in K (oK):

`0:(-31+\0,-1+29?3)$\:,"*";

Try it online!

streetster

Posted 2018-02-20T12:01:08.157

Reputation: 3 635

oK 22 bytes: \0:(-31+\1-30?3)$:$0;` – zgrep – 2018-02-27T08:40:28.623

@zgrep, probably worth posting as a separate oK solution :) stringing 0 in K4 gives an atom rather than an enlisted char (so you can't pad it) and the above solution always pads the first line with 30 chars - a requirement which was removed as a comment. – streetster – 2018-02-28T22:11:35.873

2

Icon, 51 bytes

-2 bytes thanks to Kevin Cruijssen

n:=30;every 1to 30do{write(repl(" ",n),8);n+:=?3-2}

Try it online!

Galen Ivanov

Posted 2018-02-20T12:01:08.157

Reputation: 13 815

2

Clojure, 88 77 bytes

Always happy to provide a Clojure answer. Always sad, it's quite long.

(loop[x 30 p x](when(> x 0)(printf(str "%"p"d\n")1)(recur(dec x)(+(-(rand-int 3)1)p))))

Ungolfed:

(loop [x 30 p x]
  (when (> x 0) 
    (printf (str "%" p "d\n") 1)
    (recur (dec x) (+ (- (rand-int 3) 1) p))))

Update 1

Managed to shave off 11 bytes by making the code more idiomatic. Who would have thought that making things "more right" would end up being more effective in a Code Golf challenge.

(doseq[p(take 30(iterate #(+ %(-(rand-int 3)1))30))](printf(str "%"p"d\n")1))

Ungolfed:

(doseq [p (take 30
            (iterate
              #(+ % (- (rand-int 3) 1))
              30))]
  (printf (str "%" p "d\n") 1))

Try it online!

Joshua

Posted 2018-02-20T12:01:08.157

Reputation: 231

Hi, I added a TIO link of your solution to your post. According to TIO, it's 77 bytes long, so I updated this also. – Galen Ivanov – 2018-02-21T11:55:33.573

2

SmileBASIC, 40 bytes

This answer turned out to be pretty boring.

X=30FOR I=1TO 30?" "*X;0X=X+RND(3)-1NEXT

12Me21

Posted 2018-02-20T12:01:08.157

Reputation: 6 110

2

Pip, 21 bytes

Ln:30{PsXn.0--n+:RR3}

Try it online!

Explanation

                       s is space (implicit)
 n:30                  Set n to 30
L    {              }  Loop that many times:
      P                 Print, with trailing newline:
       sXn               space, repeated n times
          .0             with "0" concatenated
            --n         Decrement n
               +:       and add to it (in-place)
                 RR3    randrange(3), i.e. a random integer between 0 and 2

DLosc

Posted 2018-02-20T12:01:08.157

Reputation: 21 213

2

PHP, 58 56 bytes

for($a=$b=30;$a--;)echo str_pad('',$b+=rand(-1,1))."+
";

Try it online!

-2 bytes thanks to @Shaggy

Ethan

Posted 2018-02-20T12:01:08.157

Reputation: 435

Welcome to PPCG! :) Seeing as the first line can contain 29-31 spaces, I think you could do this to save 2 bytes.

– Shaggy – 2018-02-23T11:59:42.150

Thx @Shaggy. Yeah, I only just read the comments on the question saying I could do that xD. Thanks for helping me shave 2 bytes! – Ethan – 2018-02-23T12:01:48.957

1

Jelly, 18 bytes

30µ3ẋX€_2+\+⁸Ṭ€o⁶Y

Uses 1 as the character.

Try it online!

Jonathan Allan

Posted 2018-02-20T12:01:08.157

Reputation: 67 804

Your first line does not always start with 30 spaces. – chocochaos – 2018-02-20T12:31:13.480

See my comment under the OP – Jonathan Allan – 2018-02-20T12:35:17.520

1

Jelly, 17 bytes

30µ’r‘Xµ’С⁶ẋp”.Y

Try it online!

Full program.

Erik the Outgolfer

Posted 2018-02-20T12:01:08.157

Reputation: 38 134

1

Haskell, 108 bytes

import System.Random
0%_=pure()
n%p=putStrLn(([1..p]>>" ")++"+")>>randomRIO(-1,1::Int)>>=((n-1)%).(p+)
30%30

Try it online! I was surprised to find that this code works in GHCi without the explicit type annotation but not on TIO, until BMO told me about the ExtendedDefaultRules flag which is set by GHCi.

Laikoni

Posted 2018-02-20T12:01:08.157

Reputation: 23 676

1

SOGL V0.12, 14 bytes

'∑:{:@*O2ψH+╗p

Try it Here!

dzaima

Posted 2018-02-20T12:01:08.157

Reputation: 19 048

1

AWK, 54 bytes

{for(f=30;a++<30;f+=int(4*rand()-2))printf"%"f"s\n",1}

Try it online!

Very straightforward. This requires a 1 line input to run. Could make it a "program" by using a BEGIN label.

Robert Benson

Posted 2018-02-20T12:01:08.157

Reputation: 1 339

1

CJam, 31 bytes

{S*TN}:F;30:V{3,{V1-+}%mRz:VF}*

Try it online!

Sort of a port of @Datboi's answer

Explanation

{S*TN}:F                         -The padded string function
{                                -Start block
 S*                              -Multiply space string by argument and push to stack
   T                             -Push integer 0 to stack
    N                            -Push newline string to stack
     }                           -End block
      :F                         -Store top of stack(the block) in variable F
        ;                        -Pop from stack
         30:V                    -Push integer 30 to stack and store in variable V
             {3,{V1-+}%mRz:VF}   -The main loop
              3                  -Push integer 3 to stack
               ,                 -Array range from 0 to n-1
                {V1-+}%          -Map to array
                 V               -Push variable V to stack
                  1              -Push integer 1
                   -+            -subtract values from each other and add to array index
                       mR        -Random choice
                         z       -Absolute value
                          :V     -Store in variable V
                            F    - Execute function in F
                              *  -pop stack and repeat block

Marcos

Posted 2018-02-20T12:01:08.157

Reputation: 171

21 bytes: Try it online!

– Esolanging Fruit – 2018-02-22T07:23:30.853

Clearly, I still have a lot of practicing to do. – Marcos – 2018-02-24T12:23:04.473

1

Go, 123 107 94 bytes

import(."fmt"
."math/rand")
func s(){s:=30
for i:=0;i<30;i++{Printf(`%*d
`,s,4)
s+=Intn(3)-1}}

call function s

Try it online!

user78508

Posted 2018-02-20T12:01:08.157

Reputation:

1

Perl 6, 39 bytes

$_=30;say(" "x($_+=^3 .roll-1)~"x")xx$_

Explanation:

$_=30: Sets the number of spaces to prefix to 30.

say(" "x($_+=^3 .roll-1)~"x"): Outputs that number of spaces and updates it (^3 .roll-1: pick a random integer from 0 to 2 and subtract it by 1), followed by x and a newline.

xx$_: Does this 30 times. Using $_ instead of 30 saves one space before 30.

bb94

Posted 2018-02-20T12:01:08.157

Reputation: 1 831