# Code Golf: Your own pet ASCII snake

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.

• Can we return an array of lines? Are leading/trailing spaces or newlines allowed? – Shaggy Feb 20 '18 at 12:07
• I assume trailing spaces on each line are allowed, right? – Luis Mendo Feb 20 '18 at 13:20
• What 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 Feb 21 '18 at 9:02
• 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 Feb 21 '18 at 15:11
• 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 Mar 2 '18 at 20:41

# Python 2, 73 bytes

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


Try it online!

• I really like the idea of creating a snake in Python – LuudJacobs Feb 21 '18 at 13:56
• I must have been half asleep yesterday - I didn't even think about that ;-) – ElPedro Feb 21 '18 at 14:14

# Pyth, 211916 15 bytes

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

Uses 0

VK30p*KdZ=+KtO3


Try it online!

# Mathematica, 74 bytes

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


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

# 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


Bonus:

27 byte version in K (oK):

0:(-31+\0,-1+29?3)$\:,"*";  Try it online! • oK 22 bytes: 0:(-31+\1-30?3)$\:$0; – zgrep Feb 27 '18 at 8:40 • @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 Feb 28 '18 at 22:11 # Icon, 51 bytes -2 bytes thanks to Kevin Cruijssen n:=30;every 1to 30do{write(repl(" ",n),8);n+:=?3-2}  Try it online! # 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! • 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 Feb 21 '18 at 11:55 # 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! # SmileBASIC, 40 bytes This answer turned out to be pretty boring. X=30FOR I=1TO 30?" "*X;0X=X+RND(3)-1NEXT  # 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  # PHP, 58 56 bytes for($a=$b=30;$a--;)echo str_pad('',$b+=rand(-1,1))."+ ";  Try it online! -2 bytes thanks to @Shaggy • Welcome to PPCG! :) Seeing as the first line can contain 29-31 spaces, I think you could do this to save 2 bytes. – Shaggy Feb 23 '18 at 11:59 • 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 Feb 23 '18 at 12:01 # Jelly, 18 bytes 30µ3ẋX€_2+\+⁸Ṭ€o⁶Y  Uses 1 as the character. Try it online! • Your first line does not always start with 30 spaces. – chocochaos Feb 20 '18 at 12:31 • See my comment under the OP – Jonathan Allan Feb 20 '18 at 12:35 # Jelly, 17 bytes 30µ’r‘Xµ’Ð¡⁶ẋp”.Y  Try it online! Full program. # 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. # SOGL V0.12, 14 bytes '∑:{:@*O2ψH+╗p  Try it Here! # 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. # 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  • 21 bytes: Try it online! – Esolanging Fruit Feb 22 '18 at 7:23 • Clearly, I still have a lot of practicing to do. – Marcos Feb 24 '18 at 12:23 ## 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.

# Go, 123107 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!