Wskazówki do gry w golfa w Röda


12

Röda to oparty na strumieniu język skryptowy stworzony przez fergusq .

Jakie masz ogólne wskazówki na temat gry w golfa w Röda? Szukam pomysłów, które można zastosować do problemów z golfem i które są przynajmniej w pewnym stopniu specyficzne dla Rödy (np. „Usuń komentarze” nie jest odpowiedzią).

Proszę zamieścić jedną wskazówkę na odpowiedź.


Próbujesz uzyskać wskazówki, jak pokonać mnie w golfie? : P (prawdopodobnie powinienem spojrzeć na wskazówki dotyczące strony Python)
HyperNeutrino

Wow, pytanie od PCG.SE, które dostało się do gorących pytań sieciowych i nie jest łamigłówką / wyzwaniem programistycznym! :)
Pedro A

1
@HyperNeutrino Shhh .... :)
user41805

Odpowiedzi:


7

Użyj podkreślników

To chyba najważniejsza wskazówka. Prawie każdy program Röda z golfem wykorzystuje podkreślenia.

Podkreśleniem jest składniowy cukier dla forpętli. Poniższe wiersze kodu są równoważne:

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

Każdy znak podkreślenia dodaje nową zmienną do niewidzialnej forpętli wokół instrukcji. Pętla pobiera jedną wartość ze strumienia dla każdej zmiennej / podkreślenia, a następnie powtarza, aż nie pozostaną żadne wartości.

Podkreślenia można stosować w dowolnym miejscu instrukcji:

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

Jeśli musisz odwoływać się do tej samej wartości podkreślenia więcej niż jeden raz lub użyć wartości w odwrotnej kolejności, możesz wstawić liczbę po podkreśleniu:

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

Niektóre średniki / znaki nowej linii są opcjonalne

Podczas pisania kodu Rödy zaleca się stosowanie znaku nowej linii lub średnika do oddzielenia wszystkich instrukcji. Jednak podczas gry w golfa warto wiedzieć, że nie wszystkie średniki są naprawdę wymagane.

Oto niepełna lista miejsc, w których średniki / znaki nowej linii są opcjonalne . Większość z nich nie stosuje się, gdy zaczyna się następujące oświadczenie operatora ( (, [, +, itd.).

  • Po zadaniach
  • Po wywołaniu funkcji, gdy występuje co najmniej jeden argument (np. f x) Lub gdy używane są nawiasy (np. f())
  • Wszędzie, jeśli następny wiersz / oświadczenie byłoby zacząć |, ), ]lub}

Jeśli następna instrukcja zaczyna się od operatora, średnik / nowa linia jest opcjonalna, jeśli

  • Instrukcja jest wywołaniem funkcji i używane są nawiasy, np. {f(x)[y]}Jest taka sama jak {f(x);[y]}. Działa to tylko w kontekście instrukcji, a nie wtedy, gdy wywołanie funkcji jest wyrażeniem.
  • Instrukcja jest przypisaniem i używane są nawiasy, np. x=(y)[z]Jest taka sama jak x=(y);[z](to nie to samo, co x=((y)[z])).

A oto kilka miejsc, w których niestety wymagane są nowe linie :

  • Po ++i --.
  • Po [...].

Często możliwe jest zapisanie bajtów poprzez reorganizację przypisań. Na przykład:

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

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

1

Użyj struktur kontrolnych sufiksów

Prawie nigdy nie jest optymalne, aby nie używać instrukcji sufiksowych, ponieważ można ich używać {...}zamiast do...end.

Kilka przykładów:

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]

Czy możesz to zrobić if[_ in y]zamiast tego?
user41805

@KritixiLithos Nie, ponieważ chcę, aby warunek był OR, a nie AND. Obecnie sprawdza, czy istnieje co najmniej jedna wartość x, która jest również y, ale twój stan będzie sprawdzić, czy wszystkie wartości w xsą również w y. (Przykład został skopiowany stąd ).
fergusq

1

Użyj strumienia do wprowadzania danych

W przypadkach, gdy dane wejściowe są listą elementów, może być korzystne pobranie wartości ze strumienia zamiast pobierania ich jako tablicy.

W większości przypadków elementy tablicy są iterowane przez wypychanie ich do strumienia, a następnie iterowanie za pomocą forpętli (lub podkreślenia). Ponieważ elementy i tak są iterowane ze strumienia, dlaczego nie zdefiniować , że powinny być tam od samego początku?

Na przykład, aby obliczyć sumę kwadratów liczb na wejściu:

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

1

Nawiasy są opcjonalne w kontekście instrukcji. Ma to zastosowanie, nawet jeśli argument zaczyna się od operatora. Na przykład [a()|sqrt-_]jest krótszy niż [a()|sqrt(-_)]. Nawiasy po asą obowiązkowe, tak jak aw kontekście wyrażenia, a nie w kontekście instrukcji.

Jednak pisanie [a()|sqrt(_+1)*2]nie jest to możliwe, i potrzebne są dodatkowe nawiasy pomóc parser: [a()|sqrt((_+1)*2)]. Często można przepisać takie wyrażenie, aby nie zaczynało się od nawiasu:[a()|sqrt 2*(_+1)]


Czy możliwe jest również przekazanie wielu parametrów do funkcji bez konieczności podawania nawiasów?
user41805 18.04.17

@KritixiLithos Tak. Na przykład. [a()|atan2 _,_]byłoby dozwolone.
fergusq 18.04.17

1

Użyj ,zamiast ..w []/ pushoświadczenia

Powiązane: Użyj ,zamiastand

pushFunkcja (jak również printfunkcja) może przyjąć dowolną liczbę argumentów, i wysyła każdy z nich bez separatora.

To oznacza coś takiego

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

można skrócić do sprawiedliwego

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

oszczędzając 1 bajt.


1

[]/ push>print

Nigdy nie używaj printinstrukcji. []instrukcje push są zawsze bardziej golfowe. Różnica między printi pushpolega na tym, że pierwsza generuje końcowy znak nowej linii, a druga nie. Można to jednak obejść.

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

Używanie ``ciągów

W ""ciągach będziesz musiał uciec od niektórych znaków, aby ich użyć. Na przykład, aby wydrukować ukośnik odwrotny, musisz mieć ciąg znaków podobny do "\\". Dodano jeden bajt do ucieczki przed odwrotnym ukośnikiem. Jeśli jednak użyjesz ``, nie musisz uciekać od tej postaci i możesz zapisać jeden bajt.

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

Mało tego, możesz kodować zmienne i wyrażenia wewnątrz ``ciągów, używając $variableNamelub ${expression}, funkcji nieobecnej w ""ciągach.

W tych przykładach wyprowadzamy ciąg "a"połączony z wartością zmiennej bz końcowym znakiem nowej linii.

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

1

Użyj ,zamiastand

Warunki w Röda są strumieniami i mogą składać się z wielu wartości. Wartości te są redukowane do jednej wartości logicznej za pomocą and.

Oznacza to, że można zastąpić andz ,warunków do popychają wielu wartości do strumienia:

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

Pusty stan jest prawdą

Możliwe jest również, aby warunek nie zawierał żadnych wartości, co jest prawdą.

x while true
x while[]

1

Napisz listy zastępcze w formie *"...;..."/";"

replaceFunkcja przyjmuje zwykle listę ciągów jako argumenty. Jeśli jednak lista jest bardzo długa, korzystne jest po prostu przechowywanie par wyrażenia regularnego / zamiennego w ciągu, a następnie podzielenie ciągu i użycie operatora gwiazdy:

replace"a","b","c","d"
replace*"a;b;c;d"/";"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.