Код Гольф: ваш собственный питомец ASCII змея

34

Итак, я написал себе однострочник, который распечатал змею на консоли. Это немного забавно, и мне было интересно, как я могу сжать мой код ...

Вот (короткий) пример вывода:

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

Вот технические характеристики:

  • В каждой строке один непробельный символ (какой вам нравится) выводится на консоль, первоначально с отступом от 29 до 31 пробела слева от него.
  • На каждой итерации между этими тремя действиями принимается случайное решение
    • Количество отступов уменьшается на 1
    • Количество отступов остается прежним
    • Количество отступов увеличивается на 1

Сделайте это 30 раз, чтобы напечатать 30-сегментную длинную змею на консоли.

Самый короткий ответ в байтах побеждает.

AJFaraday
источник
Можем ли мы вернуть массив строк? Разрешены ли начальные / конечные пробелы или переводы строки?
Лохматый
1
Я предполагаю, что пробелы в каждой строке разрешены, верно?
Луис Мендо
1
Что означает «случайный»? Равномерно случайный? Случайный из какого-либо распределения с положительной поддержкой по каждому из трех результатов? Случайный из любого распределения вообще? Должны ли результаты быть разными при каждом запуске программы?
Натаниэль
1
Обратите внимание, что по умолчанию случайные значения не означают единообразно . Например, вторая часть моего ответа «мозговой отстой» (на данный момент) совершенно верна, несмотря на то, что большую часть времени она генерирует прямую линию.
Джо Кинг
1
Прямо сейчас есть две неясные точки: 1) означает ли случайное равномерно случайное? (влияет на этот ответ ) и 2) Должен ли результат быть разным каждый раз? (то есть, может ли генератор случайных чисел быть отброшен? Влияет на этот ответ )
DJMcMayhem

Ответы:

14

05AB1E , 15 14 байтов

30DF2Ý<+ΩD0sú,

Попробуйте онлайн!

Использует 0.

объяснение

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
источник
39
05AB1E: 0 байт, попробуйте онлайн! ... подожди, нет, хотя.
Волшебная Урна Осьминога
14

Случайный Brainfuck , 123 122 121 байт

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

Попробуйте онлайн!

Random Brainfuck - это расширение brainfuck, с полезным добавлением ?команды, которая устанавливает текущую ячейку в случайный байт. Это печатает змею из !s, которая, как ни странно, больше похожа на шаги, чем на змею.

Как это работает:

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

Другое решение, которое придерживается буквы вопроса, а не духа.

87 байт

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

Попробуйте онлайн!

Этот сильно смещен в сторону того, чтобы оставить заполнение в покое, но увеличение или уменьшение заполнения оба одинаково возможны. Каждый из них имеет шанс чуть менее 1 к 256.

Джо Кинг
источник
Очень хорошо! Я не знал о ?команде. +1
Грант Миллер
@GrantMiller ?доступен только в случайном Brainfuck , не классический Brainfuck
Джо Кинг
8

С (ССЗ) , 61 58 56 байт

Ответ отредактирован, чтобы отразить изменения правил ...

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

Попробуйте онлайн!

cleblanc
источник
сохраните байт, перейдя s+=1-rand()%3к функции printf. i;f(s){for(s=i=31;--i;)printf("%*c\n",s+=1-rand()%3,43);}
Ваелус
@Vaelus Это делает в первой строке разное количество пробелов вместо 30, указанных в вопросе.
Steadybox
@Steadybox Что разрешено в комментариях, по- видимому ..
Кевин Круйссен
7

Сетчатка , 24 байта


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

Попробуйте онлайн!

объяснение


30* +

Инициализируйте рабочую строку в первой строке, то есть 30 пробелов и a +.

-29{¶<`^
 

Во второй строке есть пробел. -29{оборачивает оставшуюся часть программы в цикл, который выполняется 29 раз. ¶<печатает рабочую строку в начале каждой итерации цикла с завершающим переводом строки. Сам атомный этап вставляет пробел в начале строки (основная идея состоит в том, чтобы вставить один пробел, а затем случайным образом удалить 0–2 пробела, потому что это на байт короче, чем случайный выбор между удалением, вставкой и отсутствием операции).

S,2@1`

Это сопоставляет пустое регулярное выражение с вводом, что дает нам каждую позицию между символами (и началом и концом строки). Затем ,2сохраняются только первые три совпадения, то есть совпадения после нуля, одного и двух пробелов. @выбирает случайный один из этих трех матчей. Затем split stage ( S) разбивает входные данные вокруг этого совпадения. И это 1говорит о том, чтобы сохранить только вторую часть раскола. Другими словами, мы отбрасываем все до нашего случайного совпадения.

30-я строка, которая является результатом последней итерации цикла, печатается неявно в конце программы.

Мартин Эндер
источник
Вы знаете, что даже короче, чем удаление 0--2 пробелов? Перетасовывать пространства вокруг! , Кстати, новая Retina великолепна: D
Лев
7

VBA, 60 59 49 байт

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

Вставьте его в окно «Немедленно» и нажмите «Ввод». (Убедитесь, что явное объявление отключено!)

Гораздо вероятнее двигаться, чем оставаться в очереди (то есть действия не имеют одинакового веса), но это не было определенным требованием (К счастью!)

{РЕДАКТИРОВАТЬ} Сохранено 1 байт, удалив пробел между =1иTo

{EDIT2} Сохранено 10 байтов благодаря комментарию remoel

Старые версии:

'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
источник
5
Добро пожаловать в PPCG!
Мартин Эндер
2
Вы можете сохранить несколько байтов, заменив String(i," ")и Spc(30+i)затем удалив i=30:. Или -1 байт, удалив &. :)
remoel
7

C # (.NET Core), 112 110 106 100 99 98 байт

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

-1 байт благодаря @raznagul .
-1 байт благодаря @auhmaan .

Объяснение:

Попробуйте онлайн.

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
Кевин Круйссен
источник
Одна странная вещь: если я звоню new Random().Next()несколько раз локально (.net Framework версии 4.6.1), я всегда получаю один и тот же результат. Мне нужно добавить Thread.Sleep(10)между вызовами, чтобы надежно получить разные результаты. При времени сна менее 10 мс я иногда получаю тот же результат. Поэтому .net-Framework и TIO (.net-Core) имеют разные PRNG или, по крайней мере, используют разные начальные числа. Если я переключаю вашу программу в TIO на C # -mono, я получаю то же поведение, что и локально в .net-Framework.
Разнагул
@raznagul Хм, что вывод с C # (Mono C # компилятор) действительно странный ..
Кевин Круйссен
3
@raznagul new Random()использует время в качестве начального числа, поэтому в тесном цикле время одинаково, и поэтому результат одинаков.
TheLethalCoder
@TheLethalCoder: Да, именно этого я (более или менее) ожидал. Странно то, что 1) .net-Core (по крайней мере, на TIO) ведет себя по-разному. 2) То, что мне нужно, Thread.Sleep(10)чтобы надежно получить разные результаты, и Thread.Sleep(1)даже 9 мс недостаточно.
Разнагул
@raznagul Хорошо спать в течение 1, 9 или 10 мс должны все спать в одно и то же время, в зависимости от других запущенных процессов ... странно, действительно.
TheLethalCoder
7

C, 56 байтов

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

Попробуйте онлайн!

Объяснение:

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 байтов

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

Зависит от f, «возвращающей» значение, присвоенное n в функции, что является неопределенным поведением, но работает согласованно с gcc, когда оптимизация не включена.

Попробуйте онлайн!

Steadybox
источник
6

JavaScript (ES8), 63 62 60 байт

Включает завершающий перевод строки. *2-1может быть заменено -.5на 1-байтовое сохранение, но вероятность того, что длина каждой строки будет такой же, как и у предыдущей строки, будет значительно увеличена. Конечно, поскольку «случайный» не определен в задаче, RNG может быть заменен new Date%3-1на общее количество байтов 55 .

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

Спасла байт благодаря тому, кто удалил свой комментарий, прежде чем я смог поймать имя. Я бы на самом деле пытался это так с repeatи , padStartно не думаю , чтобы попробовать padEnd- не знаю , почему!


бонус

Для того же количества байтов, вот версия, которая принимает количество начальных пробелов и итераций в качестве входных данных.

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):``на один байт короче. (Примечание: Так как SO не допускает разрывы строк в комментариях, мне пришлось печатать \ n вместо фактического использования
перевода
Спасибо, @Stefnotch. К сожалению, даже при начальном значении y=31первая строка может быть слишком короткой. tio.run/##BcFLDsIgEADQvSeZkUCs7kzQE7hyqSYzKfRjKBCYGHp6fO/…
Лохматый
1
Поправьте меня, если я ошибаюсь, но разве ваше текущее решение также не пострадает от этой проблемы?
Stefnotch
1
В первой строке должно быть ровно 30 пробелов, в зависимости от задачи.
Нить
1
@Nit, ОП подтвердил, что первая строка может содержать 29-31 пробела, но еще не отредактировал этот факт в вызове, несмотря на неоднократные запросы об этом.
Лохматый
6

Java 8, 89 87 байт

Первый гольф, я уверен, что это может быть намного лучше ..

Редактировать: Исправлена ​​первая строка благодаря Steadybox .

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

Попробуйте онлайн!

 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
источник
5
Добро пожаловать в PPCG! :)
Лохматый
2
83 байта
Steadybox
6

Python 2 , 83 65 64 байта

Прямой подход:

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

Попробуйте онлайн!

Спасибо @Rod за сохранение нескольких байтов! Спасибо @ovs за -1 байт!

Редактировать: изменил имя переменной и строку вывода на букву 's'

Более змеевидный вывод для 88 байтов:

from random import*
s=[30,0]
exec"print' '*sum(s)+'(S)'[s[-1]+1];s+=[randint(-1,1)];"*30
Габор Фекете
источник
1
Мне это нравится. Действительно аккуратное решение.
Сделано
5

Древесный уголь , 14 байтов

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

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

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

Было бы только 10 байтов, если не было начального требования отступа.

Neil
источник
@KevinCruijssen Хм, это неловко, потому что уголь любит обрезать по умолчанию.
Нил
5

PHP, 61 bytes

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

Try it online!

chocochaos
источник
8
$i<30;$i++можно $i++<30;сохранить 2 байта.
Кевин Круйссен
2
55 байт: for($p=30;$i++<30;$p+=rand(-1,1))printf("%{$p}s\n",'+');( \nсчитается как 1 символ и должен быть заменен реальным переводом строки)
Исмаэль Мигель
2
Альтернатива длиной 55 байт без предупреждений: for($i=$p=30;$i--;$p+=rand(-1,1))printf("%{$p}s\n",'+');
Исмаэль Мигель
5

Ява 8, 131 129 127 126 119 108 101 байт

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

Объяснение:

Попробуйте онлайн.

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

Старый 119-байтовый ответ:

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

Объяснение:

Попробуйте онлайн.

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 байт

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

Спасибо Захиро Мор за 2 дополнительных байта!

Попробуйте онлайн!

plannapus
источник
Переключение с sample(3,29,T)-2на runif(29,-1,1)уменьшает число байтов на 2, но ходы уже не так вероятны. И не могли бы вы paste("%"вместо этого переключиться paste0("% "или я что-то здесь упускаю?
Рифт
@Rift, если бы я использовал вставить, результирующие строки были бы в форме, % 30 sа не % 30s. Как вы сказали runif, испортит вероятности.
plannapus
Локально sprintf("%30s"), sprintf("% 30s")и sprintf("% 30 s")вернуть те же результаты для меня. Но на TIO только первые два имеют одинаковые результаты, поэтому paste0("%"следует сохранить байт. И не требуется, чтобы каждый ход имел одинаковую вероятность.
Rift
4

Japt , 13 байт

Возвращает массив строк.

30ÆQù1nH±1n3ö

Попробуй это


объяснение

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

бонус

Для 2 байтов меньше , вот версия, которая принимает количество начальных пробелов и итераций в качестве входных данных.

U°ÆQùU±1n3ö

Попытайся


Альтернативные ГСЧ

Последние 4 байта можно заменить любым из следующих:

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
Вау, не могу поверить, что мы выигрываем в данный момент! Я думаю, что вы можете сохранить байт с этим (на мобильном телефоне, так что я не могу проверить)
ETHproductions
@ETHproductions: Ха! Это идентично тому, с чего я начал. Проблема, тем не менее, если -1RNG возвращает на первой итерации, мы получим общую длину строки, 29когда это должно быть 30, 31или 32.
Лохматый
Хм, я запутался в том, как ваша версия справляется с этим ... Кроме того, я считаю, что OP пояснил в комментариях, что им все равно, будет ли удален или добавлен дополнительный пробел в начальной итерации.
ETHproductions
На самом деле меня смущает «когда должно быть 30, 31 или 32» - где это требуется?
ETHproductions
@ETHproductions: Мы начинаем с , 30а затем добавить -1, 0или 1давая нам 29, 30 или 31- добавить "и что дает нам полную длину 30, 31или 32для первой линии.
Лохматый
4

Swift , 101 байт

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

объяснение

Полная программа. При этом используется довольно странный прием: arc4random()он входит в состав Darwinмодуля, но UIKitтакже поставляется с этой установленной функцией, поэтому он сохраняет байт :) Также используется один из моих советов по игре в гольф Swift для повторения строк произвольное количество раз.

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.
}
Мистер Xcoder
источник
не for _ in 0 ... g выполняет ли блок кода 29 раз вместо 30 (цикл от 0 до 29 (исключая))?
Кевин Круйссен
@KevinCruijssen Нет, 0...gгенерирует все целые числа в [0; г] . Мой плохой, исправил объяснение. 0..<gсгенерирует целые числа в [0; г) : P
г-н Xcoder
Ах, [0; g)ты редактировал [0; g]действительно смутил меня. :) Хм, но разве нельзя начать сg=30 и зацикливаться [1; g]в этом случае?
Кевин Круйссен
@KevinCruijssen Цикл по одному [0; g)или [1; g]определенно будет возможно, если я выберуg=30 вместо этого, но затем его print(...,0)нужно изменить на print(...+"0"), потому что перед (0) будет добавлен дополнительный (посторонний) пробел перед 0. В любом случае, количество байтов остается неизменным.
г-н Xcoder
4

Perl, 36 байт

perl -E '$#a=29;map{$#a+=rand(3)-say"@a -"}@a'
Тон Хоспел
источник
Очень хорошо. Я всегда забываю, что вы можете установить длину массива вот так ... и использовать sayдля вычитания. Правильно ли я думаю, что это не меняет количество прогонов при $#aувеличении, потому что это не ссылка?
Дом Гастингс
@DomHastings: Это потому, что я использую, mapкоторый, кажется, сначала размещает элементы в стеке. forне имеет и имел бы непредсказуемую длину цикла
Тон Хоспел
Это действительно полезно знать. Благодарность!
Дом Гастингс
Хороший гольф. Я пытался сбрить еще один байт perl -E 'map{$#a+=rand(3)-say"@a -"}@a=1..30', но это иногда (не каждый раз) приводило к ошибке сегментации. Может ли это быть ошибка в Perl v5.22.1 и v5.16.3?
Кжетил С.
@ Kjetil Да, это хорошо известная проблема, которая, вероятно, никогда не будет решена. При зацикливании массива записи не получают дополнительного refcount, поэтому, если вы удалите их, они будут освобождены к тому времени, когда цикл достигнет их, и вы нажмете на освобожденную память. К счастью, вы никогда не делаете это в реальных программах.
Тон Хоспел
4

Р, 54 53 байта

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

Идея та же, что и выше , но с укороченным sprintfкодом и более коротким символьным строковым литералом. Вместо \n(два байта) я использую буквальный разрыв строки (один байт).

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. Я использовал в sprintfтечение многих лет и почему-то всегда пропускал эту часть ... Спасибо за напоминание!
plannapus
1
Вторая строка иногда имеет два пробела вместо одного.
Скотт Милнер
@ScottMilner нашел время, чтобы это исправить.
Конрад Рудольф
4

Рубин , 45 39 байт

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

Попробуйте онлайн!

модифицирующий x во время цикла не влияет на счетчик цикла. Я выбрал S в качестве особенно змеиного выходного персонажа.

-6 байт: использовать rand(3)-1вместо [-1,0,1].sample. Спасибо, Эрик Думинил !

benj2240
источник
Вы можете сохранить два байта x.mapвместо x.times(эквивалентно, поскольку вы не используете возвращаемое значение)
RJHunter
1
Ой, ты прав, игнорируй меня!
RJHunter
1
Хорошо, у меня получше: rand -1..1на пять байтов короче, чем[-1,0,1].sample
RJHunter
1
@RJHunter: или rand(3)-1на 6 байтов меньше.
Эрик Думинил
1
(x=30).times{puts' '*x+?+;x+=rand(3)-1}(того же размера) напечатает ровно 30 пробелов для головы змеи в соответствии с
заданием
4

SenseTalk , 237 198 байт

Это язык, который я узнал и полюбил около десяти лет назад. Это язык сценариев, который управляет инструментом автоматического тестирования Eggplant Functional . Я много лет был заядлым пользователем инструмента, прежде чем некоторое время приходить в компанию. Это не самый подходящий язык для игры в гольф, но я считаю, что писать на нем очень приятно. Игра в гольф на самом деле довольно сложная, так как язык должен быть многословным и похожим на английский ... мне потребовалось немало времени, чтобы его освоить до 237 байт.

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 / Пояснение

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

Изменить: 36 байтов сохранено благодаря @mustachemoses

Аллен Фишер
источник
1
Нужны ли пробелы?
УсыMoses
Я очень уважаю это. Особенно на фоне «языков для игры в гольф», которые кажутся совершенно нечитаемыми, но короткими. Приятно иметь пример, который просто показывает, что вы можете сделать со своим языком.
AJFaraday
1
Хороший звонок @MustacheMoses! Обновлено.
Аллен Фишер
Я считаю 198 байт (ну, в пользовательском сценарии их столько)
HyperNeutrino
@AllenFisher У вас есть отдельный интерпретатор или компилятор для этого языка, который я могу использовать без демонстрации Eggplant?
УсыMoses
3

PowerShell , 42 байта

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

Попробуйте онлайн!

Петли от 1до $l=30. Каждая итерация мы помещаем $lпространство плюс xна трубопровод в виде строки, а затем +=либо из на -1, 0, 1основе Get-Randomв $lтечение следующего цикла. Эти строки собираются из конвейера, и неявный Write-Outputдает нам разделенный строкой список бесплатно.

AdmBorkBork
источник
3

Баш, 53

  • 3 байта сохранены благодаря @Dennis
for((i=p=30;i--;p+=RANDOM%3-1));{ printf %${p}s+\\n;}

Попробуйте онлайн .

Цифровая травма
источник
p+=RANDOM%3-1тоже работает
Деннис
@ Денис Да, конечно! Благодарность!
Цифровая травма
3

Желе , 18 байт

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

Попробуйте онлайн!

Выбранный персонаж - 0 . Если разрешен возврат списка списка символов, то Yможно отбросить, а отправка может быть превращена в цепочку niladic для 17 байтов . Альтернатива .

Как это работает

30Ç'С⁶ẋ; € 0Y | Niladic главная ссылка.
30 | Начиная с 30 ...
  |'С | ... Повторите вспомогательную ссылку 29 раз и соберите результаты в виде списка.
             | (Этот список включает в себя первые 30, так что на самом деле 30 номеров).
      ⁶ẋ | Повторите пробел столько раз, для каждого элемента в списке.
        ; € 0 | Добавить 0 к каждому.
           Y | И присоединяйтесь к новым строкам.
------------- +
1ŒRX + | Монадическая вспомогательная ссылка. Кроме того, вы можете использовать µ1ŒRX + µ вместо Ç.
1 | Буквальный.
 ŒR | Симметричный диапазон от –1 до 1.
   X + | Выберите случайное число и добавьте его к аргументу.

Желе , 16 байт

Объединяя мои решения, решения Эрика и Джонатана, мы можем увеличить это до 16 байт. Выбранный персонаж - 1 .

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

Попробуйте онлайн!

Спасибо Джонатану Аллану за хедз-ап (вкл Ṭ€o⁶).

Мистер Xcoder
источник
Вы можете использовать Ṭ€o⁶вместо того, ⁶ẋ;€0что делает мой 18-ти байтовый, и получать до 17.
Джонатан Аллан
@JonathanAllan Спасибо! Объединяя три ответа Jelly, я фактически получил 16 байтов. Но я опубликовал это как вторичное решение, потому что оно не полностью мое. :-)
Mr. Xcoder
3

Октава , 53 51 50 49 байтов

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

Попробуйте онлайн!

Сохранено 1 байт, больше не делать циклов. Сохраненный другой , как октава имеет printf, а также fprintf.

Этот новый код создает массив из 30 случайных чисел в диапазоне -1:1. Затем он кумулятивно суммирует массив и добавляет 30, что дает желаемую последовательность.

Результат распечатывается с использованием fprintf с использованием формата, который гласит: «Десятичное число, дополняемое до указанной ширины, за которым следует новая строка. Ширина будет первым введенным значением, а десятичное число будет вторым введенным значением. Если число Если значения введены больше, Octave будет автоматически повторять печать, чтобы получить желаемый результат.

Тогда, чтобы добиться зацикливания, нам нужно только чередовать нули между массивом последовательностей, поэтому fprintfфункция использует каждое значение в последовательности как ширину, а каждый ноль - как цифру для печати.

Печатает вывод как:

                              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

Приведенный выше код не всегда печатает ровно 30 пробелов в первой строке. Это будет либо 29, 30, либо 31. Чтобы исправить это, вы должны использовать эту 53-байтовую версию:

x=31;for i=2:x;fprintf('%*d\n',x,0);x+=randi(3)-2;end
Том Карпентер
источник
Вы можете сохранить два байта:x=31;for i=2:x;fprintf('%*d\n',x+=randi(3)-2,0);end
Кевин Круйссен
@KevinCruijssen Я думал об этом, но это не работает так же. Результатом будет первая строка, начинающаяся с 29, 30 или 31 пробела.
Том Карпентер
1
@KevinCruijssen на самом деле, неважно. Я только что заметил комментарии ОП, говорящие, что это разрешено.
Том Карпентер
Ага. Это немного раздражает правило в комментарии (тем более, что оно противоречит текущему описанию задачи ..). Я попросил OP отредактировать вызов, чтобы отразить, что вы можете начать с 29, 30 или 31, так как он, кажется, разрешает это в комментариях.
Кевин Круйссен,
3

Lua, 81 75 байтов

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

В for i=1,n ...на to_exp n вычисляется только один раз перед входом в цикл, экономя один байт.

-6 спасибо @ user202729

Попробуйте онлайн!

lqnrd
источник
1
Добро пожаловать в PPCG! Возможно, вы захотите добавить ссылку TIO в ваш пост, чтобы люди могли легче протестировать вашу программу.
user202729
Вы можете обработать свой ответ до 76 байтов . Помимо страницы Советы по игре в гольф в Lua могут быть полезны.
user202729
75 байтов .
user202729
3

Python 3.6 , 84 73 69 байтов

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

Спасибо @WheatWizard за -11 байтов. Спасибо @JoKing за -4 байта.

MustacheMoses
источник
Поскольку вы не используете, iвы можете использовать for i in[1]*30вместо этого для сохранения байтов.
Волшебник Пшеницы
Вы также можете, from random import*чтобы вам не нужно random.позже. И вы можете удалить символ новой строки после вашего :.
Пшеничный волшебник
И если вы измените 30к можно заменить . 29"+".rjust(x)" "*x+"+"
Волшебник Пшеницы
На самом деле в отношении моего последнего комментария это должно быть 30 пробелов, а не 29. Ваш текущий ответ только ставит 29 пробелов и, таким образом, не соответствует спецификации. Это можно исправить, изменив 30 на 31.
Wheat Wizard
1
@WheatWizard Спасибо! Я добавил ваши изменения и зачислил на ваш счет. Я изменился [1]*30на, [1]*xпотому что это на один байт короче.
УсыMoses
3

ES5, 97 95 81 байт

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

ES5, 11298 байт, если нужен формат функции:

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
Добро пожаловать в PPCG! Я думаю, что ваши переменные должны быть объявлены внутри функции_=>{p=30;for(i=0;i<p;i++){console.log(Array(p).join(" ")+"+\n");r=~~(Math.random()*3);p+=r==2?-1:r}}
Оливер
Это убьет байты, я скажу тебе это. ES5 не включает функции стрелок по умолчанию. Я
обновлю
@Oliver, добавлен формат функции :)
Кайл Фэрнс,
Ницца! Я не уверен, когда это было введено, но я думаю, что вы можете заменить join(" ")наjoin` `
Оливер
@ Оливер Я не уверен, что ты можешь сделать это в ES5, не так ли? Я думал, что шаблонный литерал добавлен в ES6?
Кайл Фэрнс,