Tips untuk bermain golf di Pyth

46

Pyth adalah bahasa pemrograman prosedural yang diilhami oleh Python, dibuat oleh pengguna PPCG isaacg .

Apa tips umum yang Anda miliki untuk bermain golf di Pyth? Saya mencari ide yang dapat diterapkan pada masalah kode golf secara umum yang setidaknya agak spesifik untuk Pyth.

Tolong, satu tip per jawaban.

isaacg
sumber

Jawaban:

25

Tulis kode dengan Python terlebih dahulu

Pyth sangat mirip dengan Python sehingga cukup mudah untuk menerjemahkan program Python ke Pyth. Namun, karena Pyth adalah bahasa satu huruf per perintah, terkadang sulit untuk menulis Pyth yang lurus. Dengan menulis dengan Python terlebih dahulu, ada sedikit yang perlu dipikirkan pada suatu waktu (karena Python adalah bahasa yang cukup mudah untuk dikodekan).

Justin
sumber
1
Anda juga bisa menyebutkan bahwa Anda masih dapat menggunakan sintaks Python di Pyth, sehingga Anda dapat mengonversi bagian-bagian dari program secara individual atau hanya menggunakan python jika perlu. (Seperti yang Anda lakukan di sini )
FryAmTheEggman
@ mbomb007 Unduh interpreter Pyth dan baca seluruh dokumen. Itu satu-satunya cara yang dapat diandalkan yang saya tahu untuk menulis program Pyth.
Justin
@ mbomb007 Maaf; itulah cara saya belajar cara menulis Pyth (melihat melalui kode sumber). Pada dasarnya tidak ada dokumentasi tentang Pyth; Anda pada dasarnya harus mempelajari sintaksis dengan coba-coba.
Justin
22

Ketahui Variabel Anda

Pyth memiliki 3 kategori variabel: variabel pra-inisialisasi generik, variabel pra-inisialisasi berdasarkan input pengguna, dan variabel yang secara implisit menghasilkan tugas pada penggunaan pertama.

Variabel umum:

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

Variabel input-diinisialisasi:

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

Perhatikan bahwa inisialisasi ini hanya akan dijalankan dalam program yang diberikan jika variabel terkait digunakan di luar string dalam kode. Selain itu, urutannya adalah Q, kemudian z, jika keduanya digunakan.

Penugasan pada variabel penggunaan pertama:

Jdan K. Jika Anda ingin menginisialisasi keduanya ke nilai yang sama, Anda dapat melakukannya dengan ekspresi seperti KJ0, yang setara dengan yang lebih panjang J0K0.

isaacg
sumber
18

Gunakan juru bahasa online yang lebih baru untuk menguji jawaban Anda.

Perhatikan bahwa ini adalah perangkat lunak baru, jadi mungkin bermasalah. Silakan laporkan masalah apa pun kepada saya.

isaacg
sumber
2
Luar biasa! Saya tidak dapat menemukan ini dengan google, hanya apa yang saya butuhkan!
theonlygusti
12

String di akhir baris tidak perlu kutipan akhir. Sebagai contoh:

"Hello, world!

adalah program Hello World yang sepenuhnya valid.

isaacg
sumber
Cukup jelas, ini adalah hasil google pertama untuk "bahasa pemrograman Pyth". Apakah Anda membuat halaman Anda sendiri di esolangs?
theonlygusti
3
@ theonlygusti Ya, saya lakukan. Juga, itu bukan hasil pertama Oktober lalu.
isaacg
9

Gunakan Cuntuk kompresi dasar

Ini sebenarnya tidak berdokumen, C pada string sebenarnya bukan direct chr -> int tetapi sebaliknya 256 -> base 10 (yang sama pada satu string char). Ini sangat membantu dalam mengompresi int, kita dapat menggunakan skrip ini untuk kompres:

sCMjQ256

Ambillah 12345678910, itu menghasilkan ßÜ>(beberapa tidak dapat dicetak di sana).

Juga dengan array int, Anda dapat menggabungkannya, dan dengan string besar dengan mengonversi ke poin kode dan memperlakukan sebagai basis 128 angka.

Penggunaan lain C, terima kasih @xnor karena menunjukkan ini kepada saya, membuat angka besar sewenang-wenang. Cara naif adalah:

^TT

Tetapi kita bisa melakukan satu byte lebih baik dengan:

CG

pangkalan ini 256 mendekonversi seluruh alfabet. Hasil 156490583352162063278528710879425690470022892627113539022649722= ~ 1.56e62.

Maltysen
sumber
Ditambahkan ke doc sekarang.
isaacg
8

Sekarang ada tutorial online untuk Pyth.

Dokumentasi lengkap akan ditambahkan kemudian.

Maltysen
sumber
8

Gunakan fungsi pendek ... err ... fungsi

Ketika argumen lambda mapatau reducehanya menerapkan satu operasi untuk argumen ,, Anda dapat menggunakan formulir pendek, Mdan F. fMxsama dengan mfdx, dan fFxsama dengan .UfbZx. Misalnya, kita ambil daftar angka sebagai input dan output masing-masing bertambah. Pendekatan pertama mungkin:

mhdQ

Namun, itu dapat ditulis ulang sebagai:

hMQ

Hal serupa berlaku untuk reducedengan F. Sebagai contoh, katakan ada tantangan untuk menghitung produk dari daftar bilangan bulat. Sekali lagi, percobaan pertama mungkin:

.U*bZQ

Namun, dengan F, itu dapat disingkat menjadi:

*FQ

Menghilangkan tiga byte ... tidak buruk!

kirbyfan64sos
sumber
Dan Anda tidak perlu Q, karena ditambah ketika fungsi tidak ada input, membuatnya*F
Stan Strum
7

Tetap perbarui implementasi Pyth Anda.

Saya secara teratur meningkatkan Pyth, menghapus fitur yang kurang berguna dan menambahkan yang lebih berguna, jadi perhatikan apa yang baru dan perbarui salinan implementasi Anda secara teratur.

Beberapa fitur yang baru ditambahkan: (per 10/19/14)

y: Bertindak seperti *2pada angka, dan sebagai daftar semua himpunan bagian pada string dan daftar. Misalnya:

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

f: fbiasanya perintah filter. Sekarang, ketika dipanggil dengan angka sebagai argumen kedua, ia akan memfilter urutan tak terbatas yang dimulai dengan angka itu dan menghitungnya, lalu mengembalikan elemen pertama dari urutan yang dihasilkan.

Misalnya, inilah kode untuk menemukan perdana terkecil di atas satu miliar:

pyth -c 'f!tPT^T9'
1000000007
isaacg
sumber
Itu terlihat seperti tambahan yang bermanfaat, tetapi apa yang bisa Anda gunakan daripada yang lama yz? mvdczdtidak mungkin jalan terpendek ...
Dennis
1
@ Dennis Saya membuang yang lama ykarena saya tidak berpikir Pyth perlu memiliki beberapa format input yang sangat mudah diurai, hanya satu, misalnya format Python. Jadi, ya, saya pikir mvdczdharus dilakukan, sayangnya.
isaacg
@Dennis Masalah terpecahkan, baru saja menambahkan ini ke rrangkaian pemrosesan string.
isaacg
rterlihat cukup bermanfaat.
Dennis
@isaacg Maaf jika ini di luar topik, tapi saya ingin tahu bagaimana menggunakan operasi root @di Fdr1 + 1 @ Q2Iq% Qd0d untuk membuat faktor kalkulator. Ketika saya mencoba menggunakannya, itu default ke indexartinya sebagai gantinya. Apakah ada cara untuk mengatasi perilaku ini?
StardustGogeta
5

Argumen yang disebutkan dalam fungsi (Tidak lagi didukung)

Terkadang, nilai-nilai standar dalam fungsi bisa berguna untuk bermain golf. Pyth sebenarnya mendukung ini (sangat mengejutkan saya). Sebagai contoh:

DC=Z1RZ;C;C5

Akan dicetak:

1
5

Anda juga dapat menggunakan J dan K untuk menyimpan karakter saat melakukan ini:

DgJ1K1R+JKg;g2;g2 3

cetakan:

2
3
5

Ini biasanya berguna untuk algoritma rekursif.

Ini tidak lagi berfungsi, tetapi saya telah meninggalkannya di sini jika seseorang ingin bermain golf menggunakan versi lama Pyth.

FryAmTheEggman
sumber
16
Wow - Bahkan saya tidak menyadari Pyth mendukung ini, dan saya menulis bahasanya!
isaacg
Sayangnya, ini tidak lagi berfungsi di versi Pyth yang lebih baru.
isaacg
Haruskah kiat ini dihapus seperti salah satu kiat kedaluwarsa lainnya? Jika tidak, mungkin harus ditandai dengan versi apa tip ini berlaku.
mbomb007
@ mbomb007 Saya sudah bermaksud mencari versi, tapi saya sudah terlalu malas. Saya akan menghapusnya jika Anda berpikir lebih baik seperti itu sampai saya menemukannya.
FryAmTheEggman
@FryAmTheEggman Saya pikir itu terserah Anda, karena ia mengatakan dalam judul bahwa itu tidak didukung.
mbomb007
5

Membongkar 2 elemen tuple dengan F

Katakanlah Anda memiliki 2 elemen tuple J = (a, b),, dan Anda ingin r(a,b), untuk beberapa fungsi 2 arity r.

Cara naif untuk melakukan ini adalah rhJeJ.

Cara mewah untuk melakukan ini adalah r.*J, menggunakan operator membongkar.

Cara yang sangat mewah untuk melakukan ini adalah rFJ, menggunakan operator lipat.

isaacg
sumber
apakah masih mungkin digunakan .uuntuk itu? .utampaknya mengurangi kumulatif sekarang.
Ven
.u ->. * ini adalah perubahan yang dibuat beberapa waktu lalu, tetapi tidak pernah diperbarui.
isaacg
4

Gunakan fungsi aritmatika singkat

h: Selain mengembalikan elemen pertama dari daftar, itu menambah angka, misalnya hTdievaluasi menjadi 11. Lebih pendek dari +1T.

t: Ini mengurangi angka (selain mengembalikan ekor daftar), misalnya tTdievaluasi menjadi 9. Lebih pendek dari -T1.

y: Ini menggandakan angka, misalnya yTdievaluasi menjadi 20, lebih pendek dari *T2atau +TT.

Jakube
sumber
4

Gunakan mapuntuk menghasilkan daftar

Ini pada dasarnya setara dengan pemahaman daftar fancy python. Gunakan daftar atau rentang yang ada untuk beralih dan memetakan setiap nilai, meskipun nilainya tidak masalah.

Dua contoh:

  • Buat daftar 8 nol.

    mZ8 dari pada *8]Z

  • Buat daftar 5 angka acak antara 0 dan 9:

    mOT5 dari pada V5~Y]OT)

    Yang kedua secara otomatis menetapkan daftar untuk Y(sebenarnya sebenarnya ditambahkan ke Y), tetapi bahkan =YmOTU5lebih pendek.

Jakube
sumber
4

Q implisit di EOF

Ini adalah perubahan baru, seperti hari ini.

Qadalah variabel yang diinisialisasi-otomatis ke input yang dievaluasi. Secara implisit ditambahkan ke akhir program Pyth, sebanyak yang diperlukan untuk membuat arity bekerja. Untuk melihat contoh cara menggunakan ini untuk bermain golf, katakanlah kita ingin menghitung fungsi Collatz dari input.

Cara terpendek untuk menulisnya adalah seperti ini:

@,/Q2h*3QQ

Namun, karena Qs adalah implisit di akhir file, kita cukup menulis:

@,/Q2h*3

Menyimpan 2 byte.

Perhatikan bahwa fungsi dengan argumen yang tidak diperlukan tidak akan diisi dengan argumen tersebut. Misalnya, c"12 12"tidak akan memiliki implisit Q, karena chanya membutuhkan 1 argumen.

isaacg
sumber
3

Gunakan perkecil untuk menerapkan fungsi berulang kali.

Misalkan Anda perlu mengatur variabel ke beberapa fungsi itu sendiri, dan ulangi beberapa kali. Ambil, misalnya, masalah menemukan nomor 100 nanti dalam Urutan Collatz dari input. Cara terpendek untuk menemukan nomor berikutnya dalam urutan, jika nomor awal adalah Q, adalah

@,/Q2h*Q3Q

Cara paling jelas untuk menerapkan ini 100 kali dan mencetak hasilnya adalah

V100=Q@,/Q2h*Q3Q;Q

Ulangi 100 kali, perbarui nilai Q setiap kali, lalu akhiri loop dan cetak Q.

Sebagai gantinya, kita bisa menggunakan fungsi pengurangan yang mengabaikan variabel urutan ( H).

u@,/G2h*G3GU100Q

Ini lebih pendek 2 karakter. Ini lebih pendek 3 karakter jika Anda mencoba untuk mengulang sebanyak yang ada elemen dalam urutan.

isaacg
sumber
3

Biasanya ada alternatif yang lebih pendek dari Any

Saat Anda ingin mengetahui apakah ada urutan yang memenuhi syarat, Anda biasanya akan menggunakannya .Em. Misalnya, jika Anda ingin mengetahui apakah ada dalam daftar lebih besar dari atau sama dengan 5:

.Emgd5Q

Tetapi, jika itu hanya perlu kebenaran / kesalahan, tidak benar / salah, smakan berhasil karena jumlah bekerja pada bools.

smgd5Q

Kita bahkan dapat melakukan yang lebih pendek, dengan filter:

fgT5Q

Yang terakhir terlihat sangat jelek.

Untuk .All, satu-satunya hal yang dapat saya pikirkan adalah menggunakan kondisi yang berlawanan dan meniadakannya untuk menghemat satu char .Am:

!f<T5Q
Maltysen
sumber
3

Lihatlah semua opsi aliran kontrol

Loop:

F: Untuk loop. Sama seperti Python.

V: Untuk loop di atas rentang. Baik variabel maupun rentang harus diberikan, jadi 2 karakter lebih pendek.

W: Sementara loop. Sama seperti Python.

#: Infinite while. Melarikan diri dengan kesalahan atau jeda eksplisit. Hanya try ... exceptfitur sekarang di Pyth.

Fungsi:

D: Definisi umum. Sama seperti Python.

L: 1 argumen, tidak ada fungsi penugasan, seperti lambda Python, tetapi dinamai. Nama fungsi, nama variabel dan return ( R) tidak perlu diberikan, jadi 3 karakter lebih pendek.

Pemrograman fungsional:

f: Filter - pilih elemen dari urutan input yang mengembalikan kebenaran pada input lambda.

f: Bilangan bulat pertama lebih besar dari atau sama dengan input yang memberikan hasil filter yang benar.

m: Peta - mengubah elemen urutan input menggunakan input lambda.

u: Kurangi - lipat urutan input pada input lambda, inisialisasi akumulator ke argumen ketiga.

o: Urutan - elemen yang lebih tua dari urutan input menggunakan input lambda sebagai kuncinya.

Biasanya, akan ada beberapa kemungkinan untuk setiap masalah yang diberikan, dan hanya dengan menulis solusi tes dengan masing-masing dari mereka yang dapat Anda mencari tahu mana yang terpendek.

isaacg
sumber
.xbaru-baru ini dapat digunakan untuk blok coba-kecuali.
mbomb007
@ mbomb007 apakah ada cara untuk mengabaikan kecuali blok, maksud saya bisakah itu dibiarkan kosong? Untuk ex: .x{some_statments}{except_block - can this be empty}.
Gurupad Mamadapur
@GurupadMamadapur # ... Bdapat digunakan dengan cara ini jika Anda tidak berada di dalam ekspresi
isaacg
3

Berpindah dua elemen dalam daftar

Mengganti dua elemen bisa menjadi tugas yang cukup mahal. Jadi, inilah dua pendekatan yang ingin Anda gunakan.

Pendekatan variabel tmp

Dalam persiapan kami mendefinisikan daftar Ydan mengisinya dengan beberapa angka. Tujuannya adalah untuk mengganti elemen kedua dan ketiga.

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

Kami cukup menetapkan variabel tmp J = Q[G], melakukan tugas daftar pertama Y[G] = Y[H]dan kemudian tugas terakhir kedua Y[H] = J. Kuncinya di sini adalah untuk menumpuk dua tugas daftar, sehingga Anda tidak perlu menekan pencetakan dan tidak harus menggunakan rujukan dua kali Y.

J@YGXXYG@YHHJ

dari pada

J@YG XYG@YHXYHJ

Pendekatan penerjemahan

Jika elemen, yang ingin Anda alihkan, unik dalam daftar, gunakan pendekatan ini. Ini sangat singkat. Jadi kali ini kita beralih elemen pertama dan ketiga (nilai 1dan 5unik).

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

Ini menggunakan fungsi terjemahan dari daftar:

XYm@YdK)

Penerjemahan ini menggantikan setiap elemen Y[0]dengan Y[1]dan setiap Y[1]dengan Y[0]. Jadi jika nilainya tidak unik, hal-hal buruk akan terjadi. Misalnya K,1 2menghasilkan [1, 5, 3, 5, 6, 7].

Perhatikan bahwa tanda kurung penutup adalah opsional, jika pernyataan itu adalah yang terakhir dalam kode Anda.

Jakube
sumber
3

Debugging dengan <newline>

Jika kode Anda ditulis dengan gaya pemrograman imperatif, cukup mudah untuk di-debug, karena Anda dapat dengan mudah mencetak hasil-hasil antara. ( permalink )

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

Tetapi sejumlah besar program Pyth menggunakan elemen pemrograman fungsional, seperti peta, filter dan kurangi, yang tidak memungkinkan pencetakan sesederhana itu. Tapi itu masih mungkin, menggunakan \nperintah.

Kode yang sama menggunakan u(mengurangi) adalah: ( permalink )

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

Jika Anda ingin mencetak nilai menengah, cukup masukkan \n: ( permalink )

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

\namencetak apada baris baru dan kembali a. Jadi Anda bisa memasukkannya di mana saja tanpa perlu khawatir mengubah fungsionalitas program.

Jakube
sumber
Anda sekarang dapat menggunakan baris baru untuk ini, yang juga mencetak baris baru.
PurkkaKoodari
@ Pietu1998 Ya, saya menggunakannya sepanjang waktu. Saatnya memperbarui posting.
Jakube
3

Menemukan maksimum dua bilangan bulat

g#

Misalnya, anggap Anda punya J=5dan K=12. Kemudian g#JK= 12, dan g#KJ= 12 juga.

Ini ditemukan oleh @ Pietu1998, yang mengatakannya seperti ini:

Tidak yakin apakah seseorang telah menemukannya, tetapi ada cara keren untuk melakukan maks (A, B) dalam 2 byte, tidak perlu menggunakan 3 untuk eS,AB. g#ABmelakukan hal yang sama. (Meskipun demikian, ini sangat tidak efisien, karena loopnya max (1, A-B + 1) kali. Optimalisasi adalah menempatkan angka yang kemungkinan lebih besar dari B.)

isaacg
sumber
@ Jakube Ini benar. Saya keliru mengira sesuatu saat mengetik ini dalam obrolan.
PurkkaKoodari
2

joinMetode Pyth

The joinmetode dalam Python dapat sering sedikit mengganggu, karena hanya bergabung string. Pyth joinlebih murah hati. Ini mengubah semua objek dalam string secara default.

Misalnya jkUTmemberi 0123456789atau jb["abc"4,5\f]7memberi

abc
4
(5, 'f')
[7]
Jakube
sumber
Baru-baru ini, fungsionalitas transformasi-ke-string yang lebih banyak telah ditambahkan - argumen pertama dipaksa ke string juga, misalnya j2\a\b->"a2b"
isaacg
1

Memberitahu jika suatu Angka adalah Angka Utuh

Trik yang rapi adalah menggunakan Invariant untuk mengetahui apakah suatu bilangan adalah bilangan bulat:

sI

Ini memeriksa apakah nomor tidak berubah ketika Anda memotongnya, dan itu tidak akan terjadi jika itu adalah angka bulat.

Misalnya, Anda bisa menggunakan ini sebagai tanda kuadrat sempurna:

sI@Q2
Maltysen
sumber
1

Gunakan Packed Pyth

Packed Pyth adalah "bahasa pemrograman" baru yang persis sama dengan Pyth, kecuali bahwa ia menggunakan 7 bit per karakter, bukan 8 bit per karakter.

Untuk menggunakannya, klon repositori pyth . File tersebut packed-pyth.pyadalah juru bahasa.

Katakan kode Anda "Hello, world!.

Pertama, letakkan di file: echo -n '"Hello, world!' > code.pyth

Selanjutnya, kemas kode Pyth ke dalam file Pyth Packed: python3 packed-pyth.py -p code.pyth code.ppyth

Terakhir, jalankan kode Packed Pyth: python3 packed-pyth.py code.ppyth

Saat menjalankan kode, Anda dapat memberikan -dtanda untuk melihat apa kode Pyth yang sebenarnya sedang dijalankan, dan Anda dapat memberikan input sebagai argumen baris perintah kedua setelah file yang berisi kode.

Terbalik:

  • Kode lebih pendek pada 1/8.

Kelemahan:

  • Hanya ASCII.

  • Tidak ada input interaktif.

  • Opsi debug penuh tidak tersedia.

  • Pelaporan kesalahan yang lebih buruk.

isaacg
sumber
1
seperti yang kita lakukan untuk hal safe mode, bisakah kita memindahkannya ke flag?
Maltysen
Ini luar biasa btw: D
Maltysen
@Maltysen Saya pikir itu akan meningkatkan skor byte per satu.
isaacg
Tidak bisakah Pyth dikemas lebih lanjut karena hanya menggunakan ASCII yang dapat dicetak?
lirtosiast
1

Pengujian terbagi menggunakan Idan GCD

Penafian: Ini hanya berfungsi untuk bilangan bulat non-negatif.

Untuk memeriksa apakah dua bilangan bulat non-negatif dapat dibagi, Anda dapat melakukan hal berikut:

iI<divisor><dividend>

Jika a dapat dibagi dengan b dan ≥ b ≥ 0 , maka gcd (a, b) = b .

Ini tidak selalu menghemat byte !%<dividend><divisor>, tetapi mungkin membawa Anda penghematan, karena:

  • Anda mungkin dapat mengubah hal-hal tersirat pada akhir program Pyth (seperti menjatuhkan Q), ketika bekerja dengan dividen.
  • Anda dapat menggunakannya sebagai <pfn>, karena ini adalah fungsinya sendiri.
  • Ini menangani modulo oleh 0.

Cobalah!

Tuan Xcoder
sumber
Satu lagi kelebihan: iIadalah fungsi tersendiri, sedangkan !%tidak, jadi Anda bisa menggunakannya sebagai fungsi awalan.
Erik the Outgolfer
@EriktheOutgolfer Terima kasih, ditambahkan ke daftar keunggulan :)
Tn. Xcoder
0

Menetapkan variabel ke fungsi yang diterapkan pada dirinya sendiri

Jika Anda memiliki fungsi arity 1, dan ingin menerapkannya ke variabel dan menerapkannya sendiri, Anda dapat menggunakan sintaks berikut:

=<function><variable>

Dari pada:

=<variable><function><variable>

Misalnya, jika Anda ingin menambah variabel Z, Anda dapat melakukan:

=hZ

Yang menghemat satu byte lebih =ZhZ.

Tuan Xcoder
sumber