Code Golf: con rắn ASCII thú cưng của riêng bạn


34

Vì vậy, tôi đã viết cho mình một tấm lót có in hình con rắn trên bàn điều khiển. Đó là một niềm vui và tôi tự hỏi làm thế nào tôi có thể ngưng tụ mã của mình ...

Đây là một ví dụ đầu ra (ngắn):

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

Đây là thông số kỹ thuật:

  • Trong mỗi dòng, một ký tự không phải khoảng trắng (tùy theo ý thích của bạn) được in ra bàn điều khiển, ban đầu có 29 đến 31 khoảng trắng ở bên trái của nó.
  • Mỗi lần lặp lại, một quyết định ngẫu nhiên được đưa ra giữa ba hành động này
    • Số lượng đệm giảm đi 1
    • Số lượng đệm vẫn giữ nguyên
    • Số lượng đệm tăng thêm 1

Làm điều này 30 lần, để in một con rắn dài 30 đoạn lên bàn điều khiển.

Câu trả lời ngắn nhất trong byte thắng.


Chúng ta có thể trả về một mảng các dòng không? Là không gian hàng đầu / dấu hoặc dòng mới được phép?
Xù xì

1
Tôi giả sử không gian dấu trên mỗi dòng được cho phép, phải không?
Luis Mendo

1
"Ngẫu nhiên" có nghĩa là gì? Thống nhất ngẫu nhiên? Ngẫu nhiên từ bất kỳ phân phối với sự hỗ trợ tích cực trên mỗi trong ba kết quả? Ngẫu nhiên từ bất kỳ phân phối nào? Các kết quả có phải khác nhau trên mỗi lần chạy chương trình không?
Nathaniel

1
Lưu ý rằng, theo mặc định, ngẫu nhiên không có nghĩa là thống nhất như vậy . Ví dụ, phần thứ hai của tôi câu trả lời brainfuck là (tính đến thời điểm hiện tại) hoàn toàn hợp lệ, mặc dù nó tạo ra một đường thẳng hầu hết thời gian.
Jo King

1
Ngay bây giờ, có hai điểm không rõ ràng: 1) Liệu ngẫu nhiên có nghĩa là ngẫu nhiên đồng nhất? (ảnh hưởng đến câu trả lời này ) và 2) Đầu ra phải khác nhau mỗi lần? (nghĩa là, trình tạo số ngẫu nhiên có thể không được phát hiện không? Ảnh hưởng đến câu trả lời này )
DJMcMayhem

Câu trả lời:


14

05AB1E , 15 14 byte

30DF2Ý<+ΩD0sú,

Hãy thử trực tuyến!

Công dụng 0.

Giải trình

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

38
05AB1E: 0 byte, Hãy thử trực tuyến! ... Đợi đã, không, gần như vậy.
Bạch tuộc ma thuật Urn

14

Brainfuck ngẫu nhiên , 123 122 121 byte

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

Hãy thử trực tuyến!

Random Brainfuck là một phần mở rộng của brainfuck, với sự bổ sung hữu ích của ?lệnh, đặt ô hiện tại thành một byte ngẫu nhiên. Điều này in một con rắn làm bằng !s, trông giống như bước chân hơn là một con rắn đủ vui.

Làm thế nào nó hoạt động:

+[--[<]>>+<-]>+ 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

Một giải pháp khác dính vào thư của câu hỏi, hơn là tinh thần.

87 byte

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

Hãy thử trực tuyến!

Điều này rất thiên về việc để lại phần đệm một mình, nhưng tăng hoặc giảm phần đệm đều có thể như nhau. Mỗi người có ít hơn 1 trên 256 cơ hội xảy ra.


Rất đẹp! Tôi đã không biết ?lệnh. +1
Grant Miller

@GrantMiller ?chỉ khả dụng trong Random Brainfuck , không phải là trò chơi trí tuệ cổ điển
Jo King

8

C (gcc) , 61 58 56 byte

Trả lời chỉnh sửa để phản ánh các thay đổi quy tắc ...

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

Hãy thử trực tuyến!


lưu một byte bằng cách di chuyển s+=1-rand()%3đến hàm printf. i;f(s){for(s=i=31;--i;)printf("%*c\n",s+=1-rand()%3,43);}
Vaelus

@Vaelus Điều đó làm cho dòng đầu tiên có số lượng khoảng trắng khác nhau thay vì 30 được chỉ định trong câu hỏi.
Steadybox

@Steadybox Được phép trong các bình luận rõ ràng ..
Kevin Cruijssen

7

Võng mạc , 24 byte


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

Hãy thử trực tuyến!

Giải trình


30* +

Khởi tạo chuỗi làm việc đến dòng đầu tiên, tức là 30 khoảng trắng và a +.

-29{¶<`^
 

Có một khoảng trống trên dòng thứ hai. -29{kết thúc phần còn lại của chương trình trong một vòng lặp, được chạy 29 lần. ¶<in chuỗi làm việc ở đầu mỗi vòng lặp với một dòng cấp dữ liệu. Chính giai đoạn nguyên tử chèn một khoảng trắng ở đầu chuỗi (ý tưởng cơ bản là chèn một khoảng trắng, sau đó xóa ngẫu nhiên 0 không gian 2, bởi vì đó là một byte ngắn hơn so với việc chọn ngẫu nhiên giữa xóa, chèn và không op).

S,2@1`

Điều này khớp với regex trống so với đầu vào, cung cấp cho chúng ta mọi vị trí giữa các ký tự (và bắt đầu và kết thúc chuỗi). Sau đó ,2chỉ giữ lại ba trận đấu đầu tiên, tức là các trận đấu sau 0, một và hai khoảng trắng. @chọn ngẫu nhiên một trong ba trận đấu đó Sau đó, giai đoạn phân chia ( S) phân tách đầu vào xung quanh trận đấu đó. Và1 bảo nó chỉ giữ lại phần thứ hai của sự phân chia. Nói cách khác, chúng tôi loại bỏ mọi thứ cho đến trận đấu ngẫu nhiên của chúng tôi.

Dòng thứ 30, là kết quả của lần lặp vòng lặp cuối cùng, được in ngầm ở cuối chương trình.


Bạn biết những gì thậm chí ngắn hơn so với loại bỏ khoảng 0-2-2? Xáo trộn không gian xung quanh! . Nhân tiện, Retina mới rất tuyệt: D
Leo

7

VBA, 60 59 49 Bytes

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

Dán nó trong cửa sổ Ngay lập tức và nhấn enter. (Đảm bảo tắt khai báo rõ ràng!)

khả năng di chuyển nhiều hơn là ở trong một dòng (nghĩa là các hành động không có trọng số như nhau) nhưng đó không phải là một yêu cầu cụ thể (May mắn thay!)

{EDIT} đã lưu 1 byte bằng cách xóa khoảng trắng giữa =1To

{EDIT2} Đã lưu 10 byte nhờ nhận xét của remoel

Phiên bản cũ:

'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

5
Chào mừng đến với PPCG!
Martin Ender

2
Bạn có thể lưu một vài byte bằng cách thay thế String(i," ")để Spc(30+i)xóa i=30:. Hoặc -1 byte bằng cách loại bỏ &. :)
làm lại

7

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

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 nhờ @raznagul .
-1 byte nhờ @auhmaan .

Giải trình:

Hãy thử trực tuyến.

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

Một điều kỳ lạ: Nếu tôi gọi new Random().Next()nhiều lần cục bộ (.net Framework Phiên bản 4.6.1) tôi luôn nhận được kết quả tương tự. Tôi cần thêm một Thread.Sleep(10)cuộc gọi giữa các cuộc gọi để có được kết quả khác nhau. Với thời gian ngủ dưới 10ms đôi khi tôi vẫn nhận được kết quả tương tự. Vì vậy .net-Framework và TIO (.net-Core) có các PRNG khác nhau hoặc ít nhất sử dụng các hạt giống khác nhau. Nếu tôi chuyển đổi chương trình của bạn trong TIO sang C # -mono, tôi sẽ có hành vi tương tự như tôi nhận được cục bộ trong .net-Framework.
raznagul

@raznagul Hmm, đầu ra đó với C # (trình biên dịch Mono C #) thực sự kỳ lạ ..
Kevin Cruijssen

3
@raznagul new Random()sử dụng thời gian làm hạt giống nên trong một vòng lặp chặt chẽ thời gian là như nhau và do đó kết quả là như nhau.
TheLethalCoder

@TheLethalCoder: Vâng, đó là những gì tôi (ít nhiều) mong đợi. Điều kỳ lạ là 1) .net-Core (ít nhất là trên TIO) hoạt động khác đi. 2) Điều đó tôi Thread.Sleep(10)đáng tin cậy để có được kết quả khác nhau và Thread.Sleep(1)thậm chí 9ms là không đủ.
raznagul

@raznagul Ngủ ngon trong 1, 9 hoặc 10ms nên ngủ cùng một lúc tùy thuộc vào các quá trình khác đang chạy ... thực sự kỳ quặc.
TheLethalCoder

7

C, 56 byte

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

Hãy thử trực tuyến!

Giải trình:

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 byte

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

Phụ thuộc vào f "trả lại" giá trị được gán cho n trong hàm, đây là hành vi không xác định, nhưng hoạt động ổn định với gcc khi không bật tối ưu hóa.

Hãy thử trực tuyến!


6

JavaScript (ES8), 63 62 60 byte

Bao gồm một dòng mới. *2-1có thể được thay thế bằng -.5để tiết kiệm 1 byte nhưng cơ hội của mỗi dòng có cùng độ dài với dòng trước đó sẽ được tăng lên rất nhiều. Tất nhiên, vì "ngẫu nhiên" không được xác định trong thử thách, RNG có thể được thay thế bằng new Date%3-1tổng số byte là 55 .

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

Đã lưu một byte nhờ một người đã xóa bình luận của họ trước khi tôi có thể bắt được tên. Tôi thực sự đã thử nó theo cách này repeatpadStartnhưng không nghĩ sẽ thửpadEnd - không biết tại sao!


Tiền thưởng

Với cùng số byte, đây là phiên bản lấy số lượng không gian bắt đầu & lặp lại làm đầu vào.

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


f=(x=y=30)=>x?`+\n`.padStart(y+=Math.random()*2-1)+f(--x):``ngắn hơn một byte. (Lưu ý: Vì SO không cho phép ngắt dòng trong các nhận xét, tôi đã phải nhập \ n thay vì thực sự sử dụng ngắt dòng.)
Stefnotch

Cảm ơn, @Stefnotch. Thật không may, ngay cả với giá trị ban đầu là y=31, sẽ có khả năng dòng đầu tiên quá ngắn. tio.run/##BcFLDsIgEADQvSeZkUCs7kzQE7hyqSYzKfRjKBCYGHp6fO/
Shaggy

1
Chỉnh sửa cho tôi nếu tôi sai, nhưng không phải giải pháp hiện tại của bạn cũng gặp phải vấn đề đó?
Stefnotch

1
Các dòng đầu tiên nên có chính xác 30 không gian, theo thách thức.
Nit

1
@Nit, OP đã xác nhận rằng dòng đầu tiên có thể chứa 29-31 khoảng trống nhưng vẫn chưa chỉnh sửa thực tế đó thành thách thức, mặc dù nhiều lần yêu cầu phải làm như vậy.
Xù xì

6

Java 8, 89 87 byte

Golf đầu tiên, tôi chắc chắn rằng nó có thể tốt hơn nhiều ..

Chỉnh sửa: Đã sửa lỗi dòng đầu tiên nhờ Steadybox .

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

Hãy thử trực tuyến!

 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
    }

5
Chào mừng đến với PPCG! :)
Xù xì


6

Python 2 , 83 65 64 byte

Cách tiếp cận đơn giản:

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

Hãy thử trực tuyến!

Cảm ơn @Rod vì đã lưu một số byte! Cảm ơn @ovs cho -1 byte!

Chỉnh sửa: đã thay đổi tên biến và chuỗi đầu ra thành chữ 's'

Đầu ra giống rắn hơn cho 88 byte:

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

1
Tôi thích điều này. Giải pháp thực sự gọn gàng.
linemade


5

Than , 14 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

× ³⁰            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

Sẽ chỉ có 10 byte nếu không có yêu cầu thụt đầu tiên.


@KevinCruijssen Hmm, thật là khó xử, vì Char than thích cắt tỉa theo mặc định.
Neil

5

PHP, 61 byte

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

Hãy thử trực tuyến!


8
$i<30;$i++có thể $i++<30;để lưu 2 byte.
Kevin Cruijssen

2
55 byte: for($p=30;$i++<30;$p+=rand(-1,1))printf("%{$p}s\n",'+');( \nđược tính là 1 char và nên được thay thế bằng một dòng mới thực sự)
Ismael Miguel

2
Thay thế dài 55 byte, không có cảnh báo:for($i=$p=30;$i--;$p+=rand(-1,1))printf("%{$p}s\n",'+');
Ismael Miguel

5

Java 8, 131 129 127 126 119 108 101 byte

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

Giải trình:

Hãy thử trực tuyến.

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

Câu trả lời cũ 119 byte:

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

Giải trình:

Hãy thử trực tuyến.

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

4

R , 72 69 67 byte

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

Cảm ơn Zahiro Mor vì đã có thêm 2 byte!

Hãy thử trực tuyến!


Chuyển từ sample(3,29,T)-2sang runif(29,-1,1)sẽ giảm số byte xuống 2 nhưng di chuyển không còn khả năng như nhau nữa. Và bạn cũng có thể chuyển sang paste("%"thay vì paste0("% "hoặc tôi đang thiếu một cái gì đó ở đây?
Rift

@Rift nếu tôi đang sử dụng dán chuỗi kết quả sẽ có dạng % 30 sthay vì % 30s. Như bạn đã nói runifsẽ làm rối tung các vấn đề.
plannapus

Tại địa phương sprintf("%30s"), sprintf("% 30s")sprintf("% 30 s")trả lại kết quả tương tự cho tôi. Nhưng trên TIO chỉ có hai cái đầu tiên có kết quả giống hệt nhau, vì vậy paste0("%"nên lưu một byte. Và không có yêu cầu rằng mọi di chuyển đều có xác suất như nhau.
Rift

4

Japt , 13 byte

Trả về một mảng các dòng.

30ÆQù1nH±1n3ö

Kiểm tra nó


Giải trình

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

Tiền thưởng

Đối với 2 byte ít hơn , đây là phiên bản lấy số lượng không gian bắt đầu & lặp lại làm đầu vào.

U°ÆQùU±1n3ö

Thử nó


RNG thay thế

4 byte cuối cùng có thể được thay thế bằng bất kỳ điều nào sau đây:

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

1
Wow, không thể tin rằng chúng tôi đang chiến thắng vào lúc này! Tôi nghĩ rằng bạn có thể lưu một byte bằng cái này (trên thiết bị di động để tôi thực sự không thể xác minh)
ETHproductions

@ETHản phẩm: Ha! Điều đó giống hệt với những gì tôi bắt đầu. Tuy nhiên, vấn đề là nếu -1được RNG trả về ở lần lặp đầu tiên, chúng ta sẽ kết thúc với tổng chiều dài của dòng 29khi nó nên 30, 31hoặc 32.
Xù xì

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

Actually I'm confused by "when it should be 30, 31, or 32"—where is that required?
ETHproductions

@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

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

Doesn't for _ in 0 ... g execute the code block 29 times now instead of 30 (loop from 0 to 29 (exclusive))?
Kevin Cruijssen

@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

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

@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

4

Perl, 36 bytes

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

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

@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

That's really useful to know. Thanks!
Dom Hastings

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.

@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

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!


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

1
The second line is sometimes indented two spaces instead of one.
Scott Milner

@ScottMilner Found some time to fix it.
Konrad Rudolph

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!


You can save two bytes with x.map instead of x.times (equivalent since you don't use the return value)
RJHunter

1
Oops, you're right, ignore me!
RJHunter

1
OK I've got a better one: rand -1..1 is five bytes shorter than [-1,0,1].sample
RJHunter

1
@RJHunter: Or rand(3)-1 for 6 bytes less.
Eric Duminil

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

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


1
Is the whitespace necessary?
MustacheMoses

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

1
Good call @MustacheMoses! Updated.
Allen Fisher

I count 198 bytes (well, the userscript counts that many)
HyperNeutrino

@AllenFisher Do you have a standalone interpreter or compiler for this language that I can use without getting a Eggplant demo?
MustacheMoses


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.



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


You could use Ṭ€o⁶ in place of ⁶ẋ;€0 like my 18 byter does and get to down to 17.
Jonathan Allan

@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

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

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

@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

1
@KevinCruijssen in fact, never mind. I've just noticed the OPs comments saying that is allowed.
Tom Carpenter

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

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!


1
Welcome to PPCG! You may want to add a TIO link to your post so people can test your program more easily.
user202729

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


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.


Since you don't end up using i you can use for i in[1]*30 instead to save bytes.
Wheat Wizard

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 :.
Wheat Wizard

And if you change 30 to 29 the "+".rjust(x) can be replaced with " "*x+"+".
Wheat Wizard

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

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

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


2
Welcome 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

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

@Oliver, function format added :)
Kyle Fairns

Nice! I'm not sure when it was introduced, but I think you can replace join(" ") with join` `
Oliver

@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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.