Golf için ipuçları in Perl 6


16

Perl 6'da golf oynamak için hangi genel ipuçlarınız var? Genel olarak en az biraz Perl 6 (örneğin "yorumları kaldırmak" bir cevap değildir) belirli olan golf sorunları kod uygulanabilir uygulanabilir fikirler arıyorum. Lütfen cevap başına bir ipucu gönderin.

Lütfen Perl 6'nın Perl 5 olmadığını unutmayın, bu nedenle bu soru yinelenmemektedir. Perl 5 golf için ipuçlarının çoğu Perl 6 için geçerli değildir.

Yanıtlar:


9

Değişmez subdeğerlerden kaçının . Çoğu durumda, {}kod blokları için kullanabilirsiniz . Örneğin, aşağıdaki kodu yazmayın.

sub ($a){$a*2}

Bunun yerine, blok sözdizimini kullanın. Bu aynı zamanda kullanmak sağlar $_, @_ve %_sadece tek bir değişken gerekiyorsa tutucu değişkenleri. Daha fazlasına ihtiyacınız varsa $^a, $^bdeğişkenleri vb. Kullanabilirsiniz .

{$_*2}

Ayrıca, bazı nadir durumlarda, herhangi bir kodu kullanmak mümkündür (özellikle basit ifadeleriniz olduğunda). Yer *tutucu argümanının yerini alır.

* *2

8

Perl 6, Nd , Nl ve  No kategorilerindeki tüm Unicode karakterlerin rasyonel sayı değişmezleri olarak kullanılmasına izin verdiği gerçekten tuhaf bir özelliğe sahiptir . Bunlardan bazıları ASCII'de sayısal değerlerini yazmaktan daha kısadır:

  • ¼(2 bayt) .25veya 1/4(3 bayt) ' dan daha kısadır .
  • ¾(2 bayt) .75veya 3/4(3 bayt) ' dan daha kısadır .
  • (3 bayt), 1/16(4 bayt) ' dan daha kısadır .
  • 𐦼(4 bayt), 11/12(5 bayt) ' dan daha kısadır .
  • 𒐲(4 bayt), 216e3(5 bayt) ' dan daha kısadır .
  • 𒐳(4 bayt), 432e3(5 bayt) ' dan daha kısadır .

Bunun bir takibi olarak, birden fazla basamak ve / veya eksi: say (3² + 4², 2²⁰, 5⁻²)==> olsa bile Unicode üslerini de kullanabilirsiniz (25 1048576 0.04). Bunun gibi kötüye kullanabileceğiniz Unicode'un tam listesi: docs.perl6.org/language/unicode_texas .
Ramillies

8

Girişi okuma fonksiyonlarını öğrenir. Perl 6, ARGV veya STDIN (ARGV'de hiçbir şey belirtilmemişse) girişlerini kolayca okuyabilen birçok ilginç fonksiyona sahiptir, bu da doğru kullanıldığında kodunuzu kısaltabilir. Bunları dosya tanıtıcısı yöntemleri olarak çağırırsanız, bunları belirli dosya tanıtıcısı üzerinde çalışmaya zorlayabilirsiniz (örneğin STDIN, okuyorsanız yararlı olur , ancak ARGV'deki bağımsız değişkenleri okumalısınız).

get

Bu işlev tek bir satır alır ve otomatik olarak parçalar, böylece zorunda kalmazsınız. Bu yalnızca bir satırı okumanız gerektiğinde yararlıdır.

lines

Bu işlev tüm satırları dosyadan veya STDIN'den alır. Tembel bir liste, bu yüzden kullanırsanız for, sadece ihtiyacınız olanı okuyacaktır. Örneğin.

say "<$_>"for lines

slurp

Bu, tüm dosyayı veya STDIN'i okuyacak ve sonucu tek bir dize olarak döndürecektir.


Bu hata düzeltildi - ne zaman olduğunu bilmiyorum, ama say "<$_>" for linesşimdi çalışıyor
kedi

5

Uyarı : Metin yaklaşıyor. Zamanla topladığım birçok küçük numara.

Çözümlerinizi anonim bloklar olarak yazın

Bu zaten belirtilmişti ama tekrarlamak istiyorum. TIO'da my $f =başlığa, bloğu uygun koda yazabilir ve altbilgiyi a ile başlatabilirsiniz ;. Bu, işi bitirmenin en kısa yolu gibi görünüyor (herhangi bir girdiyi okumayı önemsemeniz gerekmediğinden, argümanlarda size verilmiştir).

Başka bir güzel yol da -nveya -panahtarı kullanmaktır, ancak TIO'da çalışmasını sağlamak için bir yol bulamadım.

Bağımsız değişkenleri iletmek için iki nokta sözdizimini kullanın

Yani, 1 karakter thing.method(foo,bar)yapabilir thing.method:foo,barve kaydedebilirsiniz. Ne yazık ki, bariz nedenlerle sonuçta başka bir yöntem çağıramazsınız, bu nedenle bir bloktaki yalnızca son yöntem için kullanmak mantıklıdır.

Mümkün $_olduğunca kullanın

Bazen tek bir liste argümanı almak bu nedenle birkaç ayrı argümandan daha iyidir. Erişirken $_, yalnızca bir nokta ile başlayarak yöntemleri çağırabilirsiniz: örneğin .sort, eşittir $_.sort.

Bununla birlikte, her bloğun kendine ait olduğunu unutmayın $_, bu nedenle dış bloğun parametreleri iç bloklara yayılmaz. Ana fonksiyonun parametrelerine bir iç bloktan erişmeniz gerekiyorsa, ...

Kullanamıyorsanız ^değişkenleri kullanın$_

Bir ekleme ^desene ve bunun gibi değişken adı arasında: $^a. Bunlar sadece bir blok içinde çalışır. Derleyici, ilk önce blokta bunlardan kaç tanenizi olduğunu sayar, sözlükbilimsel olarak sıralar ve sonra ilk argümanı ilkine, ikincisini ikincisine, vb. Atar. ^Sadece, bir değişken ilk oluşum içinde kullanılır. Bu yüzden {$^a - $^b}2 skaler alır ve çıkarır. Önemli olan tek şey alfabetik düzen, {-$^b + $^a}aynı şey.

Eğer sivri blok sözdizimini (gibi ->$a,$b {$a.map:{$_+$b}}) kullanmak ^istiyorsanız, ana blokta kullanmayacağınız her bir argümanı (gibi {$^b;$^a.map:{$_+$b}}) kullanarak bloğun başlangıcında sahte ifade yazmaktan daha iyi olursunuz (Not) Bu golf oynamak için daha iyi bir yol {$^a.map(*+$^b)}. Sadece konsepti göstermek istedim.)

Operatör belgelerini dikkatlice okuyun

Operatörler çok güçlüdür ve çoğu zaman işleri halletmenin en kısa yoludur. Özellikle meta operatörleri (bağımsız değişken olarak operatörleri almak operatörler) [], [\], X, <</ >>ve Zdikkatinizi değer. Bir meta-op'un argüman olarak başka bir meta-op alabileceğini unutmayın ( buradaXZ%% kullanmayı başardığım gibi ). Sen kullanabilirsiniz bir harita daha çok daha ucuz olabilen, çok bir yöntem çağrısı için ( yerine , ama dikkat, bunlar aynı değiliz! ). Ve son olarak, bir ikili kullanmadan önce , aynı şeyi çok daha az karakterde yapacağını unutmayın .>>@list>>.method@list.map(*.method)<< >>Z

Birbirine çok fazla meta-op yığarsanız, köşeli parantez kullanarak önceliği belirleyebilirsiniz []. Bu, derleyiciyi karıştırdığı kadar çok operatör yığtığınızda sizi kurtaracaktır. (Bu çok sık gerçekleşmez.)

Son olarak,, Bool, Int veya Str için zorlamak için şeylere gerek yöntemlerini kullanmak istemiyorsanız .Bool, .Intve .Str, daha ziyade operatörleri ?, +ve ~. Ya da daha iyisi, onları Int'ye zorlamak için onları aritmetik bir ifadeye koyun. Bir listenin uzunluğunu almanın en kısa yolu +@list. Bir listenin uzunluğunun gücüne 2 hesaplamak istiyorsanız, sadece söyleyin 2**@listve doğru şeyi yapacak.

Serbest devlet değişkenlerini kullanma $, @ve%

Her blok, her oluşumu $(veya @veya %) yepyeni bir sayısal (veya dizi veya karma) durum değişkeni (değeri devam ederse çağrılar arasında bloğuna bir değişken) karşılık gelir. Kaynak kodda yalnızca bir kez referans verilmesi gereken bir durum değişkenine ihtiyacınız varsa , bu üç arkadaş sizin büyük arkadaşlarınızdır. (Çoğu zaman $.) Örneğin, Ters Matematik Döngüleri yarışmasında, dizinleri dizinin oluşturduğu bir diziden döngüsel olarak seçmek için kullanılabilir $++%6.

Alt formları kullanın map, grepvd.

Araçlarla Yani: ziyade yapmak map {my block},listdaha list.map({my block}). Kullanmayı başarsanız bile list.map:{my block}, bu iki yaklaşım aynı sayıda baytta ortaya çıkar. Ve çoğu zaman, bir yöntemi çağırırken listeyi parantez içine almanız gerekir, ancak bir alt çağırırken değil. Bu nedenle alt yaklaşım her zaman daha iyi veya en azından yöntemle aynı şekilde ortaya çıkar.

Buradaki tek istisna, mapped, grepped vb. Olacak nesnenin bulunduğu zamandır $_. Sonra .map:{}belli ki atıyor map {},$_.

Kullanım kavşakları ( &ve |) yerine &&ve ||.

Açıkçası, onlar 1 byte daha kısadır. Öte yandan, bir boole bağlamına zorlanarak daraltılmaları gerekir. Bu her zaman a ile yapılabilir ?. Burada !op, bool bağlamını zorlayan op, sonucu kullanan ve reddeden bir meta-op'in farkında olmalısınız .

Bir liste var ve kullanmıyorum, bir kavşak çevirmek istiyorsanız [&]ve [|]. Bunun yerine .anyve kullanın .all. Ayrıca .nonekavşak ops tarafından bu kadar kolay taklit edilemez de vardır.


1
Bence &&ve ||hala kısa devre için yararlıdır?
ASCII-sadece

@ Yalnızca ASCII: Evet, kesinlikle öyleler.
Ramillies

4

Değişkenler için kullanılan alanı azaltın

Bunun birkaç kısmı var.

Boşluğu kaldır

Kullanarak bildirilen değişkenler mygenellikle arasındaki boşluk myve değişken adı olmadan bildirilebilir . my @aeşittir my@a.

Sigil içermeyen değişkenler kullanma

Değişken adından önce sigil'i kaldırmak için ters eğik çizgi kullanarak değişkenleri bildirebilirsiniz, şöyle:

my \a=1;

(maalesef alanı kaldıramazsınız :()

Bu, daha sonra bunlara sadece çıplak değişken adı olarak başvurabileceğiniz için yararlıdır.

 a=5;
 a.say

Temelde bu, değişkeni kodunuzda başka bir yerde birden fazla kullanırsanız bayt tasarrufu sağlar. Dezavantajı, değişkenin başlatılması gerektiğidir.

Kullan $!ve$/

Bu önceden bildirilmiş değişkenler genellikle istisnalar ve normal ifade eşleşmeleri için kullanılır, ancak kullanılarak tanımlanmaları gerekmez my.

$!=1;
$/=5;

Özellikle kullanışlı $/bir dizi olarak kullanmak ve dizi kısayollarını ve $ardından $/dizinin o öğesine erişmek için bir sayı kullanmaktır ;

$/=100..200;
say $5;  #105
say $99; #199

2

Yerine ...kullanınfirst

Genellikle, bir koşulla eşleşen ilk sayıyı bulmak istiyorsanız &f, bunu aşağıdaki gibi temsil edebilirsiniz:

first &f,1..*

Ancak bunun yerine ...operatörü kullanabilirsiniz :

+(1...&f)

Başlamak 0zorundaysanız, daha -1sonra bunun yerine sahip olabilirsiniz +.

@aKoşullu bir listedeki ilk öğenin dizinini istiyorsanız &f, normalde şunları yaparsınız:

first &f,@a,:k

Yerine:

(@a...&f)-1

(veya 0 dizine eklenmesini istiyorsanız tam tersi). Aynı şekilde, tüm öğeleri koşulu geçen ilk öğeye kadar alabilirsiniz.

Buna Downsides liste olmasıdır vardır aksi takdirde bir noktada durumun geçmek ...operatör listesinin sonuna kapalı tahmin çalışacağız ve büyük olasılıkla bir hata atmak. Ayrıca, sol taraftaki Ne olursa olsun kodu kullanamazsınız, çünkü dizinin bir parçası olarak yorumlanır.

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.