Поради щодо гольфу в Röda


12

Röda - мова сценаріїв на основі потоку, створена fergusq .

Які загальні поради щодо гольфу в Röda? Я шукаю ідеї, які можна застосувати до проблем із кодом-гольфу та які також принаймні дещо специфічні для Röda (наприклад, "видалити коментарі" - це не відповідь).

Будь ласка, опублікуйте одну пораду на відповідь.


Ви намагаєтесь отримати поради, щоб побити мене в гольф? : P (я, мабуть, варто переглянути поради щодо сторінки Python)
HyperNeutrino

Нічого собі, запитання від PCG.SE, яке потрапило до питань гарячої мережі та не є головоломкою / викликом програмування! :)
Педро А

1
@HyperNeutrino Shhh .... :)
користувач41805

Відповіді:


7

Використовуйте підкреслення

Це, мабуть, найважливіша порада. Майже в кожній програмі Röda із гольфу використовується підкреслення.

Синтаксис підкреслення - це синтаксичний цукор для forциклів. Наступні рядки коду еквівалентні:

ls""|fileLength x for x|sort|pull
ls""|fileLength _|sort|pull

Кожне підкреслення додає нову змінну до невидимого forциклу, який знаходиться навколо оператора. Цикл витягує одне значення з потоку для кожної змінної / підкреслення і потім повторюється, поки не залишиться жодних значень.

Підкреслення можна використовувати будь-де у виписках:

a[x:y+1]=[1]*(1+y-x) /* Sets range x..y (inclusive) */
seq x,y|a[_]=1       /* 6 bytes less */

Якщо ви повинні посилатися на одне і те ж значення підкреслення більше одного разу або використовувати значення в зворотному порядку, ви можете поставити число після підкреслення:

a|[_^_1]  /* maps x to x^x */
a|[_2-_1] /* maps each pair (x,y) to y-x, eg. [1,2,4,8] -> [1, 4] */

3

Деякі крапки з комою / новим рядком необов’язкові

При написанні коду Röda, як правило, рекомендується використовувати нові рядки або крапки з комою для розділення всіх операторів. Однак, займаючись гольфом, варто знати, що справді потрібні не всі крапки з комою.

Ось неповний перелік місць, де крапки з комою / новинки необов’язкові . Більшість з них не застосовується , коли наступний оператор починається з оператором ( (, [, +і т.д.).

  • Після виконання завдань
  • Після викликів функцій, коли є щонайменше один аргумент (наприклад, f x) або коли використовуються круглі дужки (наприклад, f())
  • Скрізь, якщо такий рядок / заяву буде починатися з |, ), ]або}

Якщо наступне твердження починається з оператора, крапка з комою / новим рядком є необов’язковою, якщо

  • Оператор є викликом функції і використовуються круглі дужки, наприклад, {f(x)[y]}такий же, як {f(x);[y]}. Це працює лише в контексті оператора, а не тоді, коли виклик функції є виразом.
  • Оператор є присвоєнням і використовуються круглі дужки, наприклад, x=(y)[z]це те саме, що x=(y);[z](це не те саме, що x=((y)[z])).

І ось, на жаль, потрібні нові рядки :

  • Після ++і --.
  • Після [...].

Часто вдається зберегти байти шляхом реорганізації завдань. Наприклад:

a=0;b=""c=[""]
b=""c=[b]a=0

x=f()y=i;z=a[0]
x=f()z=a[0]y=i

1

Використовуйте структури управління суфіксом

Практично ніколи оптимально не використовувати суфіксні висловлювання, як ви можете використовувати {...}замість do...end.

Деякі приклади:

x|unless[not(_ in y)]do[0]else[1]done
x|[0]unless[not(_ in y)]else[1]

if[p<0]do c+=p;a-=p done
{c+=p;a-=p}if[p<0]

Ви можете зробити це if[_ in y]замість цього?
користувач41805

@KritixiLithos Ні, тому що я хочу, щоб умова була АБО, а не. В даний час він перевіряє, чи є принаймні одне значення, xяке також є y, але ваша умова перевіряє, чи всі значення xв y. (Приклад був скопійований звідси ).
fergusq

1

Використовуйте потік для введення

У випадках, коли вхід - це список елементів, може бути корисним витягнути значення з потоку, а не отримувати їх як масив.

У більшості випадків елементи масиву повторюються шляхом натискання на потік, а потім ітерації за допомогою forциклу (або підкреслення). Оскільки елементи все-таки повторюються з потоку, чому б не визначити, що вони повинні бути там з самого початку?

Наприклад, для обчислення суми квадратів чисел, що вводяться:

{|a|a|[_^2]|sum} /* Removing a redundant argument */
{[_^2]|sum}      /* saves 5 bytes */

1

Дужки в дужках в контексті заяви. Це застосовується, навіть якщо аргумент починається з оператора. Наприклад, [a()|sqrt-_]коротше, ніж [a()|sqrt(-_)]. Круглі дужки після aобов'язкові, як aі в контексті виразу, а не в контексті висловлювання.

Однак, лист [a()|sqrt(_+1)*2]НЕ представляється можливим, і додаткові дужки необхідні , щоб допомогти аналізатору: [a()|sqrt((_+1)*2)]. Часто можна переписати такий вираз, щоб він не починався з дужок:[a()|sqrt 2*(_+1)]


Чи можливо також передавати кілька параметрів функціям, не вимагаючи дужок?
користувач41805

@KritixiLithos Так. Напр. [a()|atan2 _,_]буде дозволено.
fergusq

1

Використовуйте ,замість ..in []/ pushзаяви

Пов'язані: Використовуйте ,замістьand

pushФункція (так само як і printфункція) може приймати будь-яке число аргументів, і виводить кожен з них без будь - яких роздільників.

Тож це означає щось подібне

["a"..b]        /*8 bytes (string "a" concatenated with variable b)*/

можна скоротити просто

["a",b]         /*7 bytes*/

економія 1 байта.


1

[]/ push>print

Ніколи не використовуйте printзаяви. []заяви про натискання завжди гріф. Різниця між printі pushполягає в тому, що перший виводить новий рядок, а другий - ні. Однак цього можна обійти.

print"a"              /* 8 bytes */
["a                   /* 6 bytes; uses a literal newline */
"]

print"a",b            /* 10 bytes */
[`a$b                 /* 8 bytes; uses a literal newline and `` strings */
`]

1

Використання ``рядків

У ""рядках вам доведеться уникати певних символів, щоб їх використовувати. Наприклад, щоб надрукувати зворотну косу рису, вам потрібно мати рядок типу "\\". Існує один доданий байт для уникнення зворотної косої риски. Однак якщо ви використовуєте ``, вам не доведеться уникати цього символу і ви можете зберегти один байт.

print"\\"     /* 9 bytes */
print`\`      /* 8 bytes */

Не тільки це, ви можете кодувати змінні та вирази всередині з ``рядків , використовуючи $variableNameабо ${expression}, функцію якої немає в ""рядках.

У цих прикладах ми виводимо рядок, "a"з'єднаний зі значенням змінної, bз останньою новою рядком.

["a",b,"      /* 11
"]               bytes   */
[`a$b         /* 8
`]               bytes; encodes b in the string using $b */

1

Використовуйте ,замістьand

Умови Röda є потоками, і вони можуть складатися з декількох значень. Ці значення зводяться до одного булевого значення за допомогою and.

Це означає , що ви можете замінити andз ,в умовах штовхнути кілька значень потоку:

x if[a and b]
x if[a,b]

Порожня умова - правда

Можливо також наявність умови, яка не містить значень, яка є правдою.

x while true
x while[]

1

Запишіть списки заміни у формі *"...;..."/";"

replaceФункція приймає зазвичай список рядків в якості аргументів. Однак, якщо список дуже довгий, вигідно просто зберегти параметри регулярних виразів / заміни в рядку, а потім розділити рядок і використовувати оператор зірки:

replace"a","b","c","d"
replace*"a;b;c;d"/";"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.