Röda'da golf için ipuçları


12

Röda , fergusq tarafından oluşturulan akış tabanlı bir betik dilidir .

Röda'da golf oynamak için hangi genel ipuçlarınız var? Ben kod-golf sorunları uygulanabilir ve aynı zamanda en azından biraz Röda (örneğin "yorumları kaldırmak" bir cevap değildir) için özel olabilir fikirler arıyorum.

Lütfen cevap başına bir ipucu gönderin.


Golfte beni yenmek için ipuçları almaya mı çalışıyorsun? : P (Muhtemelen Python sayfası için ipuçlarına
bakmalıyım

Vay be, PCG.SE bir soru Hot Network Sorular girdi ve bir programlama bulmaca / meydan okuma değil! :)
Pedro A

1
@HyperNeutrino Shhh .... :)
user41805

Yanıtlar:


7

Alt çizgi kullan

Bu muhtemelen en önemli ipucu. Neredeyse her golf sahası Röda programı alt çizgi kullanır.

Alt çizgi sözdizimi fordöngüler için sözdizimsel şekerdir . Aşağıdaki kod satırları eşdeğerdir:

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

Her alt çizgi for, ifadenin etrafındaki görünmez bir döngüye yeni bir değişken ekler . Döngü, her değişken / alt çizgi için akıştan bir değer alır ve hiçbir değer kalmayana kadar tekrar eder.

Alt çizgiler ifadelerde herhangi bir yerde kullanılabilir:

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

Aynı alt çizgi değerine birden çok kez başvurmanız veya değerleri ters sırada kullanmanız gerekiyorsa alt çizgiden sonra bir sayı koyabilirsiniz:

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

Bazı noktalı virgüller / yeni satırlar isteğe bağlıdır

Röda kodunu yazarken, tüm ifadeleri ayırmak için genellikle satırsonu veya noktalı virgül kullanılması önerilir. Ancak, golf yaparken, tüm noktalı virgüllerin gerçekten gerekli olmadığını bilmek önemlidir.

Noktalı virgüllerin / yeni satırların isteğe bağlı olduğu yerlerin eksik bir listesi . Aşağıdaki deyim bir operatörün (ile başladığında Çoğu geçerli değildir (, [, +vb.)

  • Ödevlerden sonra
  • İşlev çağrılarından sonra, en az bir bağımsız değişken (ör. f x) Veya parantez kullanıldığında (ör. f())
  • Her yerde, bir sonraki satır / deyimi ile başlaması durumunda |, ), ]veya}

Bir sonraki deyimi bir operatörün, noktalı virgül / yeni satır is ile başlıyorsa opsiyonel eğer

  • İfade bir işlev çağrısıdır ve parantez kullanılır, örn . İle {f(x)[y]}aynıdır {f(x);[y]}. İşlev çağrısı bir ifade olduğunda bu yalnızca ifade bağlamında çalışır.
  • İfade bir ödevdir ve parantez kullanılır, örn. x=(y)[z]İle aynıdır x=(y);[z](aynı değildir x=((y)[z])).

İşte yeni satırların maalesef gerekli olduğu bazı yerler :

  • Sonra ++ve --.
  • Sonra [...].

Atamaları yeniden düzenleyerek baytları kaydetmek genellikle mümkündür. Örneğin:

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

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

1

Sonek kontrol yapılarını kullanma

Neredeyse olduğunu asla kullanabileceğiniz gibi uygun değildir eki ifadeleri kullanmak {...}yerine do...end.

Bazı örnekler:

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]Bunun yerine yapabilir misin ?
user41805

@KritixiLithos Hayır, çünkü koşulun VE olmasını değil OR olmasını istiyorum. Şu anda kontroller varsa en azından bir değer xki de y, fakat eğer durum kontrol ediyorum tüm değerler xde bulunmaktadır y. (Örnek buradan kopyalanmıştır ).
fergusq

1

Giriş için akışı kullanın

Girdinin bir öğe listesi olduğu durumlarda, değerleri bir dizi olarak almak yerine akıştan almak yararlı olabilir.

Çoğu durumda, dizi öğeleri akışa iterek ve daha sonra bir fordöngü (veya alt çizgi) kullanarak yineleyerek yinelenir . Öğeler yine de akıştan yinelendiğinden, neden en baştan orada olmaları gerektiğini tanımlamıyorsunuz ?

Örneğin, girişteki sayıların karelerinin toplamını hesaplamak için:

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

1

Parantezler ifade bağlamında isteğe bağlıdır. Bu, argüman bir operatörle başlasa bile geçerlidir. Örneğin, [a()|sqrt-_]daha kısadır [a()|sqrt(-_)]. Sonraki parantezler , ifade bağlamında değil, ifade bağlamında olduğu agibi zorunludur a.

Ancak, yazma [a()|sqrt(_+1)*2]mümkün değildir ve ekstra parantezler ayrıştırıcı yardımcı olmak için gereklidir: [a()|sqrt((_+1)*2)]. Genellikle böyle bir ifadeyi bir parantez ile başlamamak için yeniden yazmak mümkündür:[a()|sqrt 2*(_+1)]


Parantez gerektirmeden işlevlere birden çok parametre iletmek de mümkün müdür?
user41805

@KritixiLithos Evet. Örneğin. [a()|atan2 _,_]izin verilir.
fergusq

1

Kullanım ,yerine ..de []/ pushifadeleri

İlgili: Yerine ,kullanınand

pushFonksiyonu (aynı zamanda printfonksiyonu) bağımsız değişken herhangi bir sayıda almak ve bir sınırlayıcı ile bunların her biri çıkışın.

Yani böyle bir şey demek

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

sadece kısaltılabilir

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

1 bayt tasarrufu.


1

[]/ push>print

Asla printifadeler kullanmayın . []push ifadeleri her zaman golfçüdür. Arasındaki fark printve pusheski çıkışları bir arka satır ikinci değil ise olmasıdır. Ancak bu önlenebilir.

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

``Dizeleri kullanma

Gelen ""dizeleri, bunları kullanmak için bazı karakterlerden kurtulmak gerekir. Örneğin, ters eğik çizgiyi yazdırmak için aşağıdaki gibi bir dizeye sahip olmanız gerekir "\\". Ters eğik çizgiden kaçmak için eklenen bir bayt var. Kullanmak Ancak, ``, sen do not bu karakteri kaçmak zorunda ve bir bayt kaydedebilirsiniz.

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

Sadece bu da değil, veya ``dizeleri içinde bulunmayan bir özelliği kullanarak dizelerin içindeki değişkenleri ve ifadeleri kodlayabilirsiniz .$variableName${expression}""

Bu örneklerde "a", değişkenin değeri ile bitiştirilmiş dizgenin sonundaki bsatırsonu ile çıkıyoruz.

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

1

Yerine ,kullanınand

Röda'daki koşullar akıştır ve birden fazla değerden oluşabilir. Bu değerler ile bir boole değerine düşürülür and.

Eğer takabilmek Bu araçlar andile ,akışına birden fazla değer itmek koşullarda:

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

Boş durum doğrudur

Değer içermeyen bir koşula sahip olmak da mümkündür, bu doğrudur.

x while true
x while[]

1

Değiştirme listelerini formda yazın *"...;..."/";"

replaceFonksiyonu normal argüman olarak dizeleri listesini alır. Bununla birlikte, liste çok uzunsa, normal ifade / değiştirme çiftlerini bir dizede saklamak ve sonra dizeyi bölmek ve yıldız operatörünü kullanmak yararlıdır:

replace"a","b","c","d"
replace*"a;b;c;d"/";"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.