Pyth şehrinde golf için ipuçları


46

Pyth , PPCG kullanıcısı isaacg tarafından yaratılan Python'dan ilham alan bir yordamsal programlama dilidir .

Pyth'ta golf oynamak için hangi genel ipuçlarınız var? Golf problemlerini genel olarak kodlamak için en azından bir şekilde Pyth'e özgü olan fikirleri arıyorum.

Cevap başına bir ipucu lütfen.

Yanıtlar:


25

Önce kodu Python'a yazınız.

Pyth Python'a çok benzer, Python programlarını Pyth'a çevirmek oldukça kolaydır. Ancak, Pyth komut başına tek harfli bir dil olduğu için, bazen düz Pyth yazmak zordur. Önce Python'da yazarak, bir anda düşünülecek daha az şey var (çünkü Python kodlamak oldukça kolay bir dildir).


1
Pyth'te yine Python sözdizimini kullanabileceğinizi de belirtebilirsiniz, böylece programın bölümlerini ayrı ayrı dönüştürebilir veya yalnızca gerekirse python kullanabilirsiniz. (Senin yaptığın gibi burada )
FryAmTheEggman

@ mbomb007 Pyth yorumlayıcısını indirin ve dökümanları okuyun. Pyth programı yazmanın tek güvenilir yolu bu.
Justin,

@ mbomb007 Üzgünüz; Pyth (kaynak koduna bakarak) yazmayı bu şekilde öğrendim. Pyth hakkında hiçbir belge yok; temelde deneme yanılma yoluyla sözdizimini öğrenmek zorundasınız.
Justin,

22

Değişkenlerinizi bilin

Pyth, 3 değişken kategorisine sahiptir: genel önceden başlatılmış değişkenler, kullanıcı girişine göre önceden başlatılmış değişkenler ve ilk kullanımda dolaylı olarak bir atama oluşturan değişkenler.

Genel değişkenler:

b = "\n"
d = " "
k = ""
G = "abcdefghijklmnopqrstuvwxyz"
H = {}                            # (empty dict)
N = '"'
T = 10
Y = []
Z = 0

Giriş tarafından başlatılan değişkenler:

Q = eval(input())
z = input()

Bu başlatmaların yalnızca belirli bir programda, ilişkili değişken koddaki bir dizgenin dışında kullanıldığında çalıştırılacağını unutmayın. Ayrıca, her ikisi de kullanılıyorsa, sipariş de Qo zaman zolur.

İlk kullanım değişkenlerine atama:

Jve K. Her ikisini de aynı değerde başlatmak istiyorsanız, bunu KJ0uzunluğa eşdeğer gibi bir ifadeyle yapabilirsiniz J0K0.


18

Cevaplarınızı test etmek için daha yeni çevrimiçi tercümanı kullanın.

Bunun yeni bir yazılım olduğuna dikkat edin, bu nedenle buggy olabilir. Lütfen bana herhangi bir sorun bildirin.


2
Müthiş! Bunu ihtiyacım olan şeyle google'da bulamadım!
theonlygusti

12

Satırın sonundaki dizelerin son tırnaklara ihtiyacı yoktur. Örneğin:

"Hello, world!

Tamamen geçerli bir Hello World programıdır.


Gerçekten çok açık, bu "Pyth programlama dili" nin ilk google sonucudur. Sayfalarda kendi sayfalarını yarattın mı?
theonlygusti

3
@ theonlygusti Evet, yaptım. Ayrıca, geçen Ekim ayındaki ilk sonuç değildi.
isaacg

9

CBaz sıkıştırma için kullanın

Bu aslında bir dize C aslında, belgelenmemiş değil > int ama 256 yerine tabanı - - direkt chr> baz 10 (bir karakter dizeleri üzerinde aynıdır). Bu bir int sıkıştırmak için çok faydalıdır, sıkıştırmak için bu betiği kullanabiliriz:

sCMjQ256

Al 12345678910, sonuçlanır ßÜ>(orada bazı yazdırılamayanlar).

Ayrıca bir dizi diziyle, kod noktalarına dönüştürerek ve temel 128 sayı olarak değerlendirerek büyük dizelerle birleştirebilirsiniz.

Başka bir kullanımı C, teşekkürler bana bunu göstermek için @ xnor, keyfi bir çok sayıda yapıyor. Saf yolu:

^TT

Ancak bir baytı daha iyi yapabiliriz:

CG

bu taban (256) tüm alfabeyi temizler. Sonuçlar 156490583352162063278528710879425690470022892627113539022649722= ~ 1.56e62.


Şimdi doktora eklendi.
isaacg


8

Kısa işlevli ... err ... işlevlerini kullanın

Lambda argümanı argümanlara sadece bir işlemi uygularsa mapveya reduceuyguladığında, kısa formları kullanabilirsiniz Mve F. fMxeşittir mfdxve fFxaynı şeydir .UfbZx. Örneğin, her birinin artırdığı girdi ve çıktı olarak bir sayı listesi aldığımızı varsayalım. İlk yaklaşım şöyle olabilir:

mhdQ

Ancak, şu şekilde yeniden yazılabilir:

hMQ

Benzer bir şey için geçerlidir reduceile F. Örnek olarak, bir tamsayı listesinin ürününü hesaplamak için bir zorluk olduğunu varsayalım. Yine, ilk deneme olabilir:

.U*bZQ

Bununla birlikte F, bununla kısaltılabilir:

*FQ

Üç bayt Tıraş ... fena değil!


Ve Q, bir girdi eksik olduğunda, tamamlandığı gibi, buna gerek yok*F
Stan Strum

7

Pyth uygulamanızı güncel tutun.

Oldukça düzenli olarak Pyth'i geliştiriyorum, daha az kullanışlı özellikler kaldırıyorum ve daha kullanışlı özellikler ekliyorum, bu yüzden yeniliklere dikkat edin ve uygulamanın kopyasını düzenli olarak güncelleyin.

Son eklenen bazı özellikler: (10/19/14 itibariyle)

y: *2Rakamlar ve dizelerdeki ve listelerdeki tüm altkümelerin listesi gibi davranır. Örneğin:

pyth -c 'y"abc'
['', 'a', 'b', 'c', 'ab', 'ac', 'bc', 'abc']

f: fnormalde filtre komutudur. Şimdi, bir argümanla ikinci argümanı olarak çağrıldığında, o sayıyla başlayan ve sayılarla sayılan sonsuz diziyi süzecek, sonra ortaya çıkan dizinin ilk elemanını döndürecektir.

Örneğin, bir milyardan fazla en küçük prime bulan kod:

pyth -c 'f!tPT^T9'
1000000007

Bunlar yararlı eklemelere benziyor, fakat eskisinin yerine ne kullanabilirsiniz yz? mvdczden kısa yol olamaz ...
Dennis

1
@Dennis Eskisini fırlattım yçünkü Pyth'in süper kolay ayrıştırılmış girdi formatlarına sahip olması gerektiğini düşünmüyorum, sadece bir tane, örneğin Python formatı. Yani, evet, sanırım mvdczdne yazık ki yapmak zorunda kalacak.
isaacg

@Dennis Problem çözüldü, bunu sadece rstring işleme paketine ekledi .
isaacg

roldukça kullanışlı görünüyor.
Dennis,

@isaacg Bu konu dışıysa özür dilerim, ancak @Fdr1 + 1 @ Q2Iq% Qd0d içindeki kök işleminin bir faktör hesap makinesi yapmak için nasıl kullanıldığını merak ediyorum . Kullanmaya çalıştığımda, bunun indexyerine anlam varsayılanıdır . Bu davranış etrafında herhangi bir yolu var mı?
StardustGogeta

5

İşlevlerdeki ad argümanları (Artık desteklenmiyor)

Bazen, işlevlerdeki varsayılan değerler golf oynamak için yararlı olabilir. Pyth aslında bunu destekliyor (benim sürprizime göre). Örneğin:

DC=Z1RZ;C;C5

Yazdıracak:

1
5

Bunu yaparken karakterleri kaydetmek için J ve K tuşlarını da kullanabilirsiniz:

DgJ1K1R+JKg;g2;g2 3

baskılar:

2
3
5

Bu genellikle özyinelemeli algoritmalar için kullanışlıdır.

Bu artık işe yaramıyor, ancak birinin Pyth'in eski bir sürümünü kullanarak golf oynamak istemesi durumunda burada bıraktım.


16
Vay - Pyth'in bunu desteklediğini bile bilmiyordum ve dili yazdım!
isaacg,

Ne yazık ki, bu artık Pyth'in daha yeni sürümlerinde çalışmıyor.
isaacg

Bu ipucu, güncel olmayan ipuçlarından biri gibi mi silinmeli? Değilse, belki de bu ipucunun hangi sürümleri için geçerli olduğu ile işaretlenmelidir.
mbomb007

@ mbomb007 Sürümü bulmak için anlam ifade ettim, ancak çok tembelim. Bulana kadar bu yoldan daha iyi olduğunu düşünüyorsanız, silin.
FryAmTheEggman

@FryAmTheEggman başlıkta desteklenmediğini söylediğinden beri size bağlı.
mbomb007

5

2 eleman tüzüğünün açılması F

2 element aruple fonksiyonuna sahip olduğunuzu ve bazı 2 aritelik fonksiyonu r'yi J = (a, b)istediğinizi r(a,b)söyleyin.

Bunu yapmanın saf yolu rhJeJ.

Bunu yapmanın en süslü yolu r.*J, paket açma operatörünü kullanmaktır.

Bunu yapmanın gerçekten süslü yolu rFJ, katlama işlecini kullanmaktır.


bunun için kullanmak hala mümkün .umü? .uşimdi kümülatif azalma gibi görünüyor.
Ven

.u ->. * bu bir süre önce yapılan, ancak hiçbir zaman güncellenmeyen bir değişiklikti.
isaacg

4

Kısa aritmetik fonksiyonları kullan

h: Bir listenin ilk öğesini döndürmek dışında, bir sayıyı artırır, örneğin hTdeğerlendirir 11. Daha kısa +1T.

t: Bu sayıyı azaltır (bir listenin kuyruğunu döndürmek dışında), örneğin tTdeğerlendirir 9. Daha kısa -T1.

y: Bu sayıları iki katına çıkarır, örneğin: veya daha kısa olarak yTdeğerlendirir .20*T2+TT


4

mapListe oluşturmak için kullanın

Temelde, python'un fantezi listesi anlamalarının bir karşılığıdır. Değer önemli olmasa bile her değerin üzerinde yineleme yapmak ve eşlemek için mevcut bir listeyi veya aralığı kullanın.

İki örnek:

  • 8 sıfırdan oluşan bir liste oluşturun.

    mZ8 onun yerine *8]Z

  • 0 ile 9 arasında 5 rasgele sayının bir listesini oluşturun:

    mOT5 onun yerine V5~Y]OT)

    İkincisi listeyi otomatik olarak atar Y(aslında Y'ye eklenir ), ancak daha =YmOTU5da kısadır.


4

EOF'ta Örtülü Q

Bu, bugün itibariyle yeni bir değişiklik.

QDeğerlendirilen girişe otomatik olarak başlatılan değişkendir. Topluluğun çalışmasını sağlamak için gerekli olduğu kadar Pyth programının sonuna dolaylı olarak eklenir. Bunu golf oynamak için nasıl kullanacağımıza bir örnek görmek için , girdideki Collatz işlevini hesaplamak istediğimizi varsayalım .

Bunu yazmanın en kısa yolu şöyle:

@,/Q2h*3QQ

Ancak, Qs dosyasının sonunda kapalı olduğu için basitçe şunu yazabiliriz:

@,/Q2h*3

2 bayt kaydediliyor.

Gereksiz argümanlara sahip fonksiyonların doldurulmuş olan argümanlara sahip olmayacağına dikkat edin. Örneğin , sadece 1 argüman gerektirdiğinden , c"12 12"üstü kapalı olmayacaktır .Qc


3

Bir işlevi tekrar tekrar uygulamak için azaltma işlevini kullanın.

Bir değişkeni kendisinin bazı işlevlerine ayarlamanız ve belirli sayıda tekrarlamanız gerektiğini varsayalım. Örneğin, girişten gelen Collatz Dizisinde 100 sayısını daha sonra bulma problemini ele alalım. İlk sayı ise Q, sıradaki sonraki numarayı bulmanın en kısa yolu

@,/Q2h*Q3Q

Bunu 100 kez uygulamanın ve sonucu yazdırmanın en açık yolu,

V100=Q@,/Q2h*Q3Q;Q

Her seferinde Q değerini güncelleyerek 100 kez tekrar edin, ardından döngüyü sonlandırın ve Q yazdırın.

Bunun yerine, dizi değişkenini ( H) görmezden gelen bir azaltma işlevi kullanabiliriz .

u@,/G2h*G3GU100Q

Bu 2 karakter daha kısa. Bir sıradaki öğeler kadar çok döngü oluşturmaya çalışıyorsanız, 3 karakter daha kısadır.


3

Herhangi biri için genellikle daha kısa alternatifler vardır

Bir diziden herhangi birinin bir koşulu sağlayıp sağlamadığını bulmak istediğinizde, genellikle kullanırsınız .Em. Örneğin, bir listedeki herhangi birinin 5'ten büyük veya eşittir olup olmadığını öğrenmek istiyorsanız:

.Emgd5Q

Ancak, eğer bir hakikat / falsey olması gerekiyorsa, doğru / yanlış değil, smtoplam boollar üzerinde çalıştığından işe yarar .

smgd5Q

fİlter ile daha kısa bir şey bile yapabiliriz :

fgT5Q

Sonuncusu gerçekte çirkin görünüyor.

İçin .All, aklıma gelen tek şey üzerinde tasarruf bir char onu ters koşulunu kullanmak ve iptal etmektir .Am:

!f<T5Q

3

Tüm kontrol akışı seçeneklerine bakın

döngüler:

F: Döngü için. Tıpkı Python'unki gibi.

V: Bir aralıktaki döngü için. Ne değişken ne de aralık verilmelidir, bu nedenle 2 karakter daha kısadır.

W: Döngü sırasında. Tıpkı Python'unki gibi.

#: Döngü boyunca sonsuz. Hata veya açık ara ile kaçış. Sadece try ... exceptPyth artık mevcuttur.

Fonksiyonlar:

D: Genel tanım. Tıpkı Python gibi.

L: 1 argümanı, Python's lambda gibi hiçbir atama fonksiyonu yoktur, fakat adlandırılmıştır. Fonksiyon adı, değişken adı ve return ( R) verilmemesi gerekir, bu nedenle 3 karakter daha kısadır.

İşlevsel programlama:

f: Filtre - giriş lambdasında gerçekliği döndüren giriş dizisi öğelerini seçin.

f: İlke, truthy filtre sonucu veren girdiden büyük veya ona eşit tam sayı.

m: Harita - giriş lambdasını kullanarak giriş dizisinin elemanlarını dönüştürün.

u: Küçült - giriş sırasındaki giriş sırasını katla, toplayıcıyı üçüncü argümana başlat.

o: Sipariş - anahtar olarak giriş lambdası kullanılarak giriş dizisinin eski elemanları.

Genellikle, herhangi bir sorun için birden fazla olasılık olacaktır ve bunların her birine yalnızca en kısa test çözümlerini yazarak çözebilirsiniz.


.xdaha yakın zamanda deneyin hariç bloklar için kullanılabilir.
mbomb007

@ mbomb007 blok hariç ihmal etmenin bir yolu var, yani boş bırakılabilir mi? Örneğin: .x{some_statments}{except_block - can this be empty}.
Gurupad Mamadapur

@GurupadMamadapur # ... B, bir ifade içinde değilseniz, bu şekilde kullanılabilir
isaacg,

3

Listedeki iki öğeyi değiştirme

İki elemanı değiştirmek oldukça pahalı bir iş olabilir. İşte burada kullanmak istediğin iki yaklaşım var.

Tmp değişkenli yaklaşım

Hazırlıkta bir liste tanımlarız Yve bazı sayılarla doldururuz. Amaç, ikinci ve üçüncü unsurları değiştirmektir.

=Y[1 3 5 3 6 7)AGH,1 2

Basitçe tmp değişkenini atayacağız, J = Q[G]ilk liste atamasını Y[G] = Y[H]ve ardından ikinci atamayı yapalım Y[H] = J. Buradaki hile, iki liste ödevini yuvalamaktır, bu nedenle yazdırmayı bastırmanız gerekmez ve iki defa başvurmak zorunda kalmazsınız Y.

J@YGXXYG@YHHJ

onun yerine

J@YG XYG@YHXYHJ

Çeviri yaklaşımı

Değiştirmek istediğiniz öğeler listede benzersizse, bu yaklaşımı kullanın. Gerçekten çok kısa. Yani bu sefer birinci ve üçüncü elemanı değiştiriyoruz (değerler 1ve 5benzersiz).

=Y[1 3 5 3 6 7)K,Z2

Bu, listenin çeviri işlevini kullanır:

XYm@YdK)

Bu çeviri, her elemanı Y[0]ile Y[1]ve Y[1]ile değiştirir Y[0]. Eğer değerler benzersiz değilse, kötü şeyler olur. Mesela K,1 2sonuçlanır [1, 5, 3, 5, 6, 7].

İfade kodunuzdaki sonuncuysa, parantez kapanışının isteğe bağlı olduğunu unutmayın.


3

İle hata ayıklama <newline>

Kodunuz zorunlu programlama tarzında yazılmışsa, ara sonuçları kolayca yazdırabileceğinizden, hata ayıklamak oldukça kolaydır. ( kalıcı )

FN.:Q2                loop
      =Y+-Y-FNhN      some random command
                Y     print intermediate result
                 ;Y   end for loop and print result

Ancak, çok sayıda Pyth programı, bu kadar basit bir baskıya izin vermeyen, harita, filtre ve azaltma gibi işlevsel programlama öğelerini kullanır. Ancak bu \nkomutu kullanarak hala mümkündür .

Aynı (kodunu) kullanarak aynı kod uolacaktır: ( kalıcı bağlantı )

u        .:Q2Y   reduce .:Q2, start with G = Y
 +-G-FHhH        random command

Ara değerleri yazdırmak istiyorsanız, sadece şunu eklemek için \n: ( kalıcı bağlantı )

u         .:Q2Y   reduce
   \nG             print(G)
 +-\nG-FHhH        random command

\naayeni bir satıra yazdırır ve geri döner a. Böylece programın işlevselliğini değiştirmeden endişelenmeden herhangi bir yere ekleyebilirsiniz.


Bugünlerde bunun için yeni satırı kullanabilirsiniz; bu, yeni satırı da basar.
PurkkaKoodari

@ Pietu1998 Evet, her zaman kullanırım. Gönderiyi güncelleme zamanı.
Jakube,

3

En fazla iki tam sayı bulma

g#

Örneğin, varsayalım J=5ve K=12. Sonra g#JK= 12 ve g#KJ= 12 de.

Bu, bu şekilde ortaya koyan @ Pietu1998 tarafından keşfedildi:

Birisi zaten bulmuşsa emin değilim, ancak 2 baytta maks. (A, B) yapmanın harika bir yolu var, bunun için 3 kullanmaya gerek yok eS,AB. g#ABaynı şeyi yapar. (Çok verimsizdir, çünkü maksimum (1, A-B + 1) kez tekrar eder. Bir optimizasyon, sayıyı B olarak büyük olacak şekilde koyar.)


@ Jakube Bu doğru. Bunu sohbete yazarken bir şeyleri gizlice görüyorum.
PurkkaKoodari

2

Pyth joinyöntemi

joinSadece dizeleri katılır beri Python yöntem genellikle biraz can sıkıcı olabilir. Pyth joindaha cömert. Varsayılan olarak dizelerdeki tüm nesneleri dönüştürür.

Örneğin jkUTverir 0123456789veya jb["abc"4,5\f]7verir

abc
4
(5, 'f')
[7]

Son zamanlarda, dizgeye daha fazla dönüşüm işlevi eklendi - ilk argüman aynı zamanda bir dizgeye de zorlandı, örneğin j2\a\b->"a2b"
isaacg 27.05.05

1

Sayının Tam Sayı olup olmadığını söyleme

Düzgün bir numara, Ibir sayının tam sayı olup olmadığını söylemek için nvariant kullanıyor :

sI

Bu, siz onu kısaldığınızda sayının değişip değişmediğini kontrol eder, ki bu tam bir sayı olmaz.

Örneğin, bunu mükemmel bir kare kontrol olarak kullanabilirsiniz:

sI@Q2

1

Paketlenmiş Pyth Kullan

Paketlenmiş Pyth, Pyth ile tamamen aynı olan yeni bir "programlama dilidir", ancak karakter başına 8 bit yerine karakter başına 7 bit kullanır.

Kullanmak için, pyth deposunu klonlayın . Dosya packed-pyth.pytercümandır.

Kodunu söyle "Hello, world!.

İlk önce bir dosyaya koyun: echo -n '"Hello, world!' > code.pyth

Ardından, Pyth kodunu Paketlenmiş Pyth dosyasına paketleyin: python3 packed-pyth.py -p code.pyth code.ppyth

Son olarak, Paketlenmiş Pyth kodunu çalıştırın: python3 packed-pyth.py code.ppyth

Kod -dçalıştırırken, gerçekten çalıştırılmakta olan Pyth kodunun ne olduğunu görmek için bayrak sağlayabilir ve kodu içeren dosyadan sonra ikinci bir komut satırı argümanı olarak giriş sağlayabilirsiniz.

Üst taraf:

  • Kod 1/8 oranında daha kısa.

Dezavantaj:

  • Sadece ASCII.

  • Etkileşimli giriş yok.

  • Tam hata ayıklama seçenekleri kullanılamaz.

  • Daha kötü hata bildirimi.


1
Güvenli mod için yaptığımız gibi, bir bayrak haline getirebilir miyiz?
Maltysen

Bu harika btw: D
Maltysen

@Maltysen Bunun bayt skorunu birer birer artıracağını düşünüyorum.
isaacg,

Pyth yalnızca yazdırılabilir ASCII kullandığından daha fazla paketlenemiyor mu?
lirtosiast

1

IVe GCD kullanarak bölünebilirlik testi

Feragatname: Bu sadece negatif olmayan tamsayılar için işe yarar.

İki negatif olmayan tamsayının bölünebilir olup olmadığını kontrol etmek için aşağıdakileri yapabilirsiniz:

iI<divisor><dividend>

Eğer bir bölünemeyen b ve bir ≥ b ≥ 0 , daha sonra b = (a, b) GCD'nın .

Baytları mutlaka kurtarmaz !%<dividend><divisor>, ancak size bir tasarruf sağlayabilir, çünkü:

  • QTemettü ile çalışırken, Pyth programının sonunda (bırakma gibi ) örtük şeyleri çimdikleyebilirsiniz .
  • <pfn>Kendi başına bir fonksiyon olduğu için onu bir olarak kullanabilirsiniz .
  • Modül tarafından işler 0.

Dene!


Bir başka avantaj: iItek başına bir fonksiyondur, oysa !%değildir, bu yüzden önek fonksiyonu olarak kullanabilirsiniz.
Outgolfer Erik

@EriktheOutgolfer Teşekkürler, avantajlar listesine eklendi :)
Bay Xcoder

0

Kendisine uygulanan bir işleve değişken atama

Arity 1 işlevine sahipseniz ve bunu bir değişkene uygulamak ve kendisine uygulamak istiyorsanız, aşağıdaki sözdizimini kullanabilirsiniz:

=<function><variable>

Onun yerine:

=<variable><function><variable>

Örneğin, değişkeni artırmak istiyorsanız Z, şunları yapabilirsiniz:

=hZ

Hangi bir bayttan fazla tasarruf sağlar =ZhZ.

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.