ラケット/スキームでのゴルフのヒント


15

ラケット / スキームでゴルフをするための一般的なヒントは何ですか?私は、少なくともラケット/スキームに特有のゴルフ問題全般のコーディングに適用できるアイデアを探しています(例えば、「コメントを削除する」は答えではありません)。


SchemeRacket(以前のPLT Scheme)は技術的に異なる言語ですが、多くの点で非常に似ており、多くのコード(どちらかといえば)が意図したとおりに実行されることは承知しています。ヒントが前述の言語のいずれかにのみ適用される場合は、そのように注意してください。

回答:


3

式は'x`x,x,@x自動的に拡大(quote x)(quasiquote x)(unquote x)、と(unquote-splicing x)、それぞれ。これは純粋に構文変換であり、どこにでも適用できます。これは、1変数関数に便利な表記法を提供します。

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

に展開します

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

私は確かにどのような構文上のキーワードをシャドウイングのための意味論じゃないquoteか、quasiquote上記の私が上でそれをテストした通訳で働いていた、とのようなコードが、バインドされた変数とunquote-splicing、それは2文字の略語を持っているので、理想よりも少ないですが、unquoteは、1文字の略語を持つ補助構文であるため、このハックに最適です。


8

ラケットλおよびlambda匿名関数を構築するための同義語のキーワードですが、λ2つのバイト場所ですlambda 6です。

ではスキーム、そのようなキーワードはありませんλし、あなたがで立ち往生していますlambda



5

ラケットを使用する場合する場合は、を使用λして変数をバインドし、数バイト削ります。ではスキームlambda1が4つの以上の変数をバインドされていない限り、このトリックは適用されませんなります。

例:1つの変数でlet/ を2バイト節約define

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

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

((λ(n)(* n n))55) ; 18 bytes

私はそのバインディングを呼び出しません。さまざまな機能を使用しています。場合によっては、匿名関数を使用する方が変数をバインドするよりも短い場合があります。
マイケルVehrs

スキームサークルで使用される一般的な 用語について、あなたの意見がどういう関係にあるのかわかりません。どちらの方法でも変数を字句スコープにバインドし、let多くの場合で実装されることを保証できますlambda
ウィニー

5

ラケットrequireフォームが複数の引数を持つことができます。

(require net/url net/uri-codec)

よりもずっと短い

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

私はSchemeについてあまり知りませんが、require組み込みのものはないようです。


5

短い同義語を使用する

ラケットには、ほぼ同等の短いバージョンを持つ多くの手順があります。(彼らは通常、等価ではありません。たとえば、(car (cons 1 2))どこ作品(first (cons 1 2))ません。失敗した場合ます。ただし、それらが同義語であることがわかっている場合は、置換を行うことができます。)

このリストはおそらく不完全です。おそらく、このリストに含まれる可能性のあるもののほとんどについてはまだ知りません。

  • (= a b) の代わりに (equal? a b)数値を比較する。
  • '(1 2) の代わりに (list 1 2)
  • carcadrcdrのためにfirstsecondと、rest
  • null? の代わりに empty?
  • modulo の代わりに remainderモジュラスが正の場合の。
  • floortruncate引数が正の場合の代わりに。

4

無駄なスペースを省く

これは「些細な」ヒントと見なすことができますが、どこかに指摘する必要があります。

普通の人が書いたラケットコード(ラケットのドキュメントなど)を読むと、すべてのスペースが入れられます。たとえば、

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

実際、()は変数名の一部にできないため、変数の周囲のすべてのスペースを削除し、あいまいさを失わないようにすることができます(さらに重要なことは、有効なコードを取得することです)。したがって、代わりに上記の式は次のようになります。

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

2

次のヒントはラケット用です

デフォルト引数

頻繁に使用される長い関数名のエイリアスを作成するのに特に便利です。

ゴルフでは、引数を消費する関数を記述することができreverse、多くを使用する必要があると仮定します。次のようなものから始めます。

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

代わりに、より短い名前で追加の引数を取り、reverseそのデフォルト値をreverse次のように設定できます。

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

さらに、同じ引数のいくつかを使用して多くの場所で使用するヘルパー関数がある場合に役立ちます。必要に応じて関数の引数を並べ替えることを忘れないでください。これにより、できるだけ多くのデフォルト引数を使用し、複数の呼び出しサイトから引数を削除できます。

match

これは小さな投稿で要約するのが少し難しいので、このためのRacket Docsを読んでください。簡単に言えば、matchリストから特定の順序で要素と要素のシーケンスを抽出できます。また、準引用構文を使用すると、切断されたリストをつなぎ合わせることができます。

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

また、正規表現を使用して、結果のグループに対して追加の計算を行う簡単な方法も提供します。

名前付き let

ここで名前付き構文を参照してくださいlet proc-id ...

これにより、すぐに呼び出される再帰関数を書くことができます define、関数を定義に呼び出すか、実際に呼び出す。

何かのようなもの:

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

以下に短縮できます。

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


この最後のものは愚かですが、私はどこにもこれまでのところ、この小さなトリックを使用することができていない:
(apply map list matrix)の転置取りmatrixmatrixリストのいくつかの長方形のリストは以下のように、です'((1 2 3) (a b c))
これが役立つかどうかを教えてください。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.