Tips bermain golf di Pip

Aug 31 2020

Pip adalah bahasa golf penting dengan operator infix. Ia juga meminjam beberapa fitur dari pemrograman fungsional dan array.

Tip umum apa yang Anda miliki untuk bermain golf di Pip? Saya mencari pendekatan dan trik yang umumnya berguna untuk golf kode dan khusus untuk Pip (misalnya "hapus komentar" bukanlah jawaban).

Harap posting satu tip untuk setiap jawaban.

Jawaban

7 user Aug 31 2020 at 10:10

Gunakan variabel yang sudah diinisialisasi

Pip memiliki banyak variabel global yang telah diinisialisasi sebelumnya sehingga Anda dapat menghindari penulisan nomor / string / sesuatu yang lain secara manual.

Berikut beberapa di antaranya ( daftar lengkap ):

  • _Fungsi identitas (== {a})

  • h 100

  • i 0

  • k ", "

  • l Daftar kosong

  • m 1000 (mnemonik: angka romawi M)

  • n Karakter baris baru

  • o 1

  • s Karakter luar angkasa

  • t 10

  • v -1

  • w Cocok dengan spasi \s+

  • x String kosong

  • z Huruf kecil alfabet a sampai z

  • BBlok yang mengembalikan argumen keduanya ( {b})

  • GBlok yang mengembalikan daftar argumennya ( {g})

  • AZ Huruf besar alfabet A sampai Z

  • CZ Konsonan huruf kecil b sampai z

  • PASemua karakter A SCII P rintable , 32 hingga 126

  • PI \$\pi\$ (3.141592653589793)

  • VW Huruf vokal huruf kecil a sampai u

  • VY Huruf vokal huruf kecil a sampai y

  • XACocok dengan satu huruf Latin [A-Za-z](ada lebih banyak X*perintah)

Tautan ke dokumentasi

5 DLosc Aug 31 2020 at 12:42

Gunakan Yoperator

Dari survei singkat, sepertinya saya menggunakan Y(atau salah satu variannya, YPdan YO) dalam satu dari setiap tiga jawaban Pip - apalagi jawabannya semakin kompleks.

Menyimpan nilai

Ysingkatan dari "yank", yang biasa bagi pengguna Vim sebagai perintah yang menyalin baris atau pilihan saat ini ke dalam buffer. YOperator unary di Pip melakukan hal serupa: ia menyimpan salinan operannya di yvariabel global dan mengembalikan operan tidak berubah. Pada dasarnya, Y<expr>setara dengan y:<expr>, tetapi lebih pendek.

Ini saja membuat Y(dan yvariabel) berguna dalam banyak kasus. Perlu menyimpan sesuatu dalam variabel dan tidak peduli yang mana yang Anda gunakan? Ymenghemat satu byte dari tugas. Perlu menggunakan ekspresi dua kali? Tarik dan gunakan ydua kali sebagai gantinya. Jika ekspresi lebih panjang dari dua byte, Anda akan menghemat.

Tetapi Yjuga berguna dengan cara lain:

Memanipulasi prioritas operator

Misalkan kita ingin menghitung jumlah 0 di input dan kemudian memasukkan hitungan ke akhir input itu. (Misalnya, input dari 1001101harus menghasilkan 1001101 3.) Menghitung 0s adalah 0Na, dan jadi kami ingin melakukannya a.s.0Na. Tapi itu tidak akan berhasil karena Nlebih rendah daripada ., dan ekspresi akan mengurai sebagai ((a.s).0)Na. Untuk menegakkan didahulukan, kita dapat menggunakan tanda kurung: a.s.(0Na). Ini selalu berhasil, dan terkadang itu satu-satunya pilihan.

Namun seringkali, kita bisa menggunakan Ysebagai gantinya. Triknya adalah itu Ymemiliki prioritas yang sangat rendah - yang terendah, pada kenyataannya, bersama dengan Pdan O. Jadi ekspresi apa pun di sebelah kanan Yakan diurai sebagai Yoperan, sedangkan seluruh Yekspresi pada gilirannya akan menjadi operan kanan apa pun yang muncul di sebelah kirinya. Dan Yakan melewatkan operannya melalui tidak berubah (ditambah menetapkannya ke y, tetapi kami tidak peduli tentang itu selama kami tidak menggunakannya yuntuk hal lain). Jika kita menulis a.s.Y0Na, itu akan mem-parsing (a.s).(Y(0Na)), seperti jika kita telah mengurung 0Na. Tetapi harganya hanya satu byte, sedangkan tanda kurung harganya dua.

Peringatan

Sebuah Yekspresi hanya dapat digunakan pada sisi kanan operator biner, bukan kiri, karena Yakan mengambil segala sesuatu di sebelah kanan sebagai operan nya. Misalnya, jika kita ingin menambahkan jumlah 0 daripada menambahkannya, kita tidak dapat melakukan Y0Na.s.a--itu akan mengurai sebagai Y(0N(a.s.a)). Sebaliknya, kami harus kembali ke tanda kurung atau strategi lain.

Hanya ada satu yvariabel, jadi Anda tidak dapat menarik dua nilai yang berbeda dalam program yang sama (kecuali Anda dapat menyusun kode Anda sehingga Anda tidak memerlukan keduanya pada saat yang sama). Anda harus memilih satu untuk ditetapkan ke variabel lain. Cobalah kedua cara tersebut dan lihat mana yang menghemat lebih banyak byte.

Operator biner di Pip selalu mengevaluasi sisi kiri mereka terlebih dahulu, yang berarti Anda secara umum tidak dapat menggunakan nilai baru dari ydalam ekspresi yang sama di mana Anda menariknya: Jika Anda ingin menghitung kuadrat a+1, Anda tidak dapat melakukan y*Ya+1( ytidak akan a+1ketika dievaluasi, karena a+1belum ditarik); dan Anda tidak dapat melakukan Ya+1*a(yang akan mengurai sebagai Y(a+(1*a))). Dalam situasi seperti ini, Anda mungkin ingin mencabut nilai pertama, dalam ekspresi yang terpisah: Ya+1y*y. Jika Anda benar-benar perlu untuk melakukannya dalam satu ekspresi, Anda dapat mengurungkan yang Ybagian: (Ya+1)*y. Ini berfungsi karena sisi kiri dari *dievaluasi terlebih dahulu, sehingga ymemiliki nilai yang benar saat sisi kanan dievaluasi.

2 Razetime Sep 07 2020 at 23:02

Ganti fungsi sederhana dengan lambda

Lambda umumnya merupakan cara yang baik untuk menghemat 2 byte (paling tidak), dibandingkan dengan fungsi biasa yang memerlukan tanda kurung.

Lambda Pip, bagaimanapun, tidak meniru atribut umum lambda, katakanlah, Python. Anda tidak dapat mempersingkat semua fungsi mandiri menjadi lambda.

Mereka adalah perpanjangan dari fungsi identitas _, di mana _ = {a}. Ini berarti Anda dapat membuat lambda dari suatu fungsi hanya jika Anda menulis fungsi dengan satu ekspresi.

Lambdas di Pip memiliki beberapa kegunaan menarik selain ekspresi tunggal. Misalnya, Anda dapat mereferensikan argumen fungsi utama tanpa menarik / menyalinnya.

Dari tutorial Dlosc tentang fungsi :

Fungsi _+amenambahkan argumennya ke argumen baris perintah pertama program. amasih memiliki nilai tingkat atas karena tidak ada di dalam kurung kurawal.

Tangkapannya adalah Anda tidak dapat menggunakan perintah (If, Else if, Loops) dan semuanya harus turun ke satu pernyataan, karena umumnya dengan menerapkan operator pada fungsi.

Karena pembatasan tersebut, Pip lambda umumnya lebih cocok untuk fungsi pemetaan atau pemfilteran kecil. Selamat bermain golf!

Jika Anda menemukan kasus penggunaan yang menarik, beri tahu saya.

1 DLosc Sep 04 2020 at 10:47

M dapat memetakan nilai alih-alih fungsi

Biasanya, Anda akan menggunakan Mseperti ini:

UC_M"abc"

dengan sisi kiri menjadi fungsi dan sisi kanan menjadi beberapa iterable yang ingin Anda petakan. Jika Anda perlu menukar argumen, "abc"MUC_berfungsi juga.

Tetapi dalam kasus di mana Anda hanya ingin mengganti setiap item dalam iterable dengan nilai konstan, Mdapat melakukannya juga - berikan non-fungsi sebagai sisi kirinya:

42M"abc"

Ini akan mengembalikan [42;42;42]: satu 42untuk setiap karakter di "abc". Jika Anda tidak keberatan mendapatkan list dan bukan string, ini satu byte lebih pendek dari 42X#"abc", dan dua byte lebih pendek dari padanan daftar 42RL#"abc".

Nilainya dapat berupa apa saja * yang bukan merupakan fungsi: Skalar, Pola, Daftar, Rentang, atau bahkan Nihil.

Trik ini juga berfungsi dengan beberapa operator peta lainnya:

  • aMJbmenggabungkan hasil menjadi string setelah pemetaan (mungkin sangat berguna ketika abukan Skalar untuk memulai)
  • aMMbakan memberi Anda daftar dari a, panjang sublists yang cocok dengan panjang item dalamb
  • aMCbakan memberi Anda bx bgrid (daftar bersarang) daria

Yang terakhir itu adalah alternatif yang berguna ZGketika Anda menginginkan nilai selain 0 ( misalnya ).


* Secara teknis, ini akan berperilaku berbeda jika diberi daftar yang berisi fungsi.

1 DLosc Oct 04 2020 at 00:26

Pintasan untuk daftar tertentu

Biasanya, jika Anda memerlukan daftar konstanta, Anda cukup mengapit item dalam tanda kurung siku, dengan pemisah seperlunya ( [4 8 15 16 23 42]). Tetapi ada cara yang lebih pendek untuk membuat beberapa daftar yang umum digunakan:

  • Pertama, jangan lupa Anda dapat menggunakan variabel preset jika Anda belum menetapkannya kembali. Daftar kosong bisa jadi lsebagai pengganti []. Menggunakan iuntuk 0dan ountuk 1dalam daftar dapat menghemat satu byte (atau bahkan dua) jika mereka berada di sebelah angka lain, karena variabel huruf kecil tidak memerlukan pemisah: [0 5]→ [i5]. Menggunakan vfor -1, tfor 10, hfor 100, atau mfor 1000juga menyimpan byte secara langsung, karena nama variabel lebih pendek dari angka yang diwakilinya.
  • Gunakan rentang jika memungkinkan: [0 1]→ [io]→ ,2. Ini masih menghemat satu byte jika berbasis-1 ( [o2]→ \,2) atau dimulai di beberapa nomor lain ( [v0]→ v,1).
  • Untuk daftar digit, pisahkan angka: [1]→ ^1; [3o4o5 9]→ ^314159; [oi]→ ^t. Ini juga berfungsi untuk karakter: ['#]→ ^'#; ['h'i]→ ^"hi".

Perhatikan bahwa dua metode terakhir melibatkan operator dengan prioritas berbeda, yang perlu Anda perhitungkan. Jika mengerjakan prioritas terlalu merepotkan, Anda selalu dapat kembali ke sintaks daftar standar.