Tips untuk bermain golf di Racket / Skema

15

Apa tip umum yang Anda miliki untuk bermain golf di Racket / Skema ? Saya mencari ide yang dapat diterapkan pada masalah kode golf secara umum yang setidaknya agak spesifik untuk Racket / Skema (mis. "Hapus komentar" bukan jawaban).


Saya tahu Skema dan Racket (sebelumnya Skema PLT) adalah bahasa yang berbeda secara teknis tetapi sangat mirip dalam banyak hal dan banyak kode (saya curiga) sebagian besar akan berjalan sebagaimana dimaksud dalam keduanya. Jika tip Anda hanya berlaku untuk salah satu bahasa yang disebutkan di atas, perhatikan demikian.

kucing
sumber

Jawaban:

3

Ekspresi 'x, `x, ,x, sebuah ,@xotomatis memperluas untuk (quote x), (quasiquote x), (unquote x), dan (unquote-splicing x)masing-masing. Ini murni transformasi sintaksis, dan dapat diterapkan di mana saja. Ini memberikan notasi yang nyaman untuk fungsi satu variabel:

; Defining a function:
(define ,x (+ x x))
; Calling a function:
(display ,2)

yang diperluas ke

; Defining a function:
(define (unquote x) (+ x x))
; Calling a function:
(display (unquote 2))

Saya tidak yakin apa arti semantik untuk membayangi kata kunci sintaksis seperti quoteatau quasiquotedengan variabel terikat, meskipun kode seperti di atas berfungsi pada penerjemah yang saya uji, dan unquote-splicingkurang ideal karena memiliki singkatan dua karakter, tetapi unquoteadalah sintaksis bantu dengan singkatan satu karakter dan sangat ideal untuk peretasan ini.

Itai Bar-Natan
sumber
8

Di Racket , λdan lambdamerupakan kata kunci sinonim untuk membangun fungsi anonim, tetapi λ2 byte di mana lambda6.

Dalam Skema , tidak ada kata kunci seperti itu λdan Anda tidak dapat menggunakannya lambda.

kucing
sumber
6

Gunakan ~auntuk mengonversi angka dan simbol menjadi string.

soegaard
sumber
5

Saat menggunakan Racket , ikat variabel yang digunakan λuntuk memangkas beberapa byte. Dalam Skema , lambdabuat trik ini tidak berlaku, kecuali ada yang mengikat empat atau lebih variabel.

Contoh: Satu variabel menyimpan 2 byte lebih dari let/define

(define n 55)(* n n) ; 20 bytes

(let([n 55])(* n n)) ; 20 bytes

((λ(n)(* n n))55) ; 18 bytes
Winny
sumber
Saya tidak akan menyebut itu mengikat. Anda menggunakan berbagai fungsi. Dalam beberapa kasus, menggunakan fungsi anonim lebih pendek daripada mengikat variabel.
Michael Vehrs
Saya tidak yakin apa pendapat Anda tentang terminologi tipikal yang digunakan dalam lingkaran skema. Saya dapat meyakinkan Anda bahwa kedua cara mengikat variabel ke lingkup leksikal, dan sering diimplementasikan dalam hal . letlambda
Winny
5

Di Racket , requireformulir dapat memiliki beberapa argumen.

(require net/url net/uri-codec)

Jauh lebih pendek dari

(require net/url)(require net/uri-codec)

Saya tidak tahu banyak tentang Skema , tetapi tampaknya tidak memiliki requirebuiltin.

kucing
sumber
5

Gunakan sinonim yang lebih pendek

Ada sejumlah prosedur di Racket yang memiliki versi pendek yang sebagian besar setara. (Mereka biasanya tidak setara: misalnya, (car (cons 1 2))berfungsi di mana (first (cons 1 2))gagal. Tapi Anda dapat membuat substitusi jika Anda tahu mereka adalah sinonim dalam kasus Anda.)

Daftar ini mungkin tidak lengkap: Saya mungkin belum tahu tentang sebagian besar hal yang bisa masuk dalam daftar ini.

  • (= a b)bukannya (equal? a b)saat membandingkan angka.
  • '(1 2)bukannya (list 1 2).
  • car, cadr, cdrUntuk first, second, dan rest.
  • null? dari pada empty?
  • moduloalih-alih remainderketika modulus positif.
  • floorbukannya truncateketika argumennya positif.
Misha Lavrov
sumber
4

Menghilangkan ruang yang tidak perlu

Ini bisa dianggap tip "sepele", tetapi harus ditunjukkan di suatu tempat.

Setiap kali Anda membaca kode Racket yang ditulis oleh orang normal (misalnya dalam dokumentasi Racket ) akan ada semua ruang yang dimasukkan: misalnya,

(append (list 1 2) (list 3 4) (list 5 6) (list 7 8))

Bahkan, karena (dan )tidak dapat menjadi bagian dari nama variabel, kami dapat menghapus semua ruang di sekitarnya dan tidak kehilangan ambiguitas (dan, yang lebih penting, masih mendapatkan kode yang valid). Jadi, ungkapan di atas dapat berupa:

(append(list 1 2)(list 3 4)(list 5 6)(list 7 8))
Misha Lavrov
sumber
2

Kiat-kiat berikut adalah untuk Racket :

Argumen default

Terutama berguna untuk membuat alias untuk nama fungsi panjang yang sering digunakan.

Asumsikan golf memungkinkan Anda untuk menulis fungsi yang menghabiskan argumen, dan menganggap Anda perlu reversebanyak menggunakan . Anda akan mulai dengan sesuatu seperti:

(λ(x) ... reverse ... reverse ... reverse ...

Sebagai gantinya Anda dapat menerima argumen tambahan, dengan nama yang lebih pendek daripada reverse, dan menetapkan nilai defaultnya ke reverse:

(λ(x[r reverse]) ... r ... r ... r ...

Lebih lanjut, ini berguna jika Anda memiliki fungsi pembantu yang Anda gunakan di banyak tempat dengan beberapa argumen yang sama. Ingatlah untuk menyusun ulang argumen ke fungsi sesuai kebutuhan, sehingga Anda dapat menggunakan argumen default sebanyak mungkin, dan menghapus argumen dari beberapa panggilan.

match

Yang ini sedikit lebih sulit untuk diringkas dalam posting kecil, jadi baca di Racket Docs untuk yang ini. Singkatnya, matchmemungkinkan Anda mengekstrak elemen dan urutan elemen dalam urutan tertentu dari daftar, dan sintaks kuasiquote memungkinkan Anda menjahit daftar yang dimutilasi kembali bersama-sama:

(match (range 10)
 [`(,xs ... 3 ,ys ... 6 ,zs ...)
  `(,@(map f xs) 3 ,@(map f ys) 6 ,@(map f sz))]
 ...

Ini juga memberi Anda cara mudah untuk bekerja dengan ekspresi reguler dan melakukan perhitungan tambahan pada grup yang dihasilkan setelahnya,

Bernama let

Lihat sintaks yang dinamai di sini .let proc-id ...

Ini memungkinkan Anda untuk menulis fungsi rekursif yang dipanggil segera tanpa defineatau benar-benar memanggil fungsi setelah Anda mendefinisikannya.

Sesuatu seperti:

(define (fib i)
  (if (< i 2) i
      (+ (fib (- i 1)) (fib (- i 2)))))
(fib 10)

dapat disingkat menjadi:

(let fib {[i 10]}
  (if (< i 2) i
      (+ (fib (- i 1)) (fib (- i 2)))))


Yang terakhir ini konyol, tapi saya belum bisa menggunakan trik kecil ini di mana pun sejauh ini:
(apply map list matrix)mengambil transpos matrix, di mana matrixada beberapa daftar daftar persegi panjang, seperti '((1 2 3) (a b c)).
Beri tahu saya jika ini terbukti bermanfaat.

waf9000
sumber
1

Seperti yang ditunjukkan Winny , #!biasanya dapat digunakan alih-alih #lang, menghemat empat byte.

#lang racket ;12 bytes
#!racket ;8 bytes
dfeuer
sumber