ファットアロー関数を短縮する方法はありますか?


15

ここPPCGで私が見てきたことから、太い矢印関数を含むほとんどのJavaScriptエントリは、2つの陣営のうちの1つである傾向があります。

  1. 単一のステートメントとして実行し、すぐに答えを返すことができるシンプルなもの x=(a,b)=>a*a+b

  2. ループを使用しているために通常中括弧があり、結果としてreturnステートメントを使用する必要がある、より複雑なもの。p=b=>{m=b;for(a=1;~-m;)--m,a*=m*m;return a%b}

概念実証として中括弧の概念を持つカテゴリ2から上記の例を取り上げreturnます。これは、JSゴルファーのコードから8バイトを削除できる可能性があるため(これが常に発生するというわけではない)、これを求めているだけです。このインスタンスで使用できるテクニックはありますか?私は再帰を試みましたが、このm=b声明は揺るがすことができないように思われるので、ちょっとしたバグであることが証明されました。

上記のコードの場合、returnゴルフが短くなるかどうかに関係なく、どのようにしてさらにゴルフがステートメントを削除するでしょうか?

回答:


18

再帰を使用する

再帰は(ほとんど)常にeval+ より短いことがわかりましたfor。forからevalに変換する一般的な方法は次のとおりです。

for(a=n;b;c);d
(f=a=>b?f(c):d)(n)

あなたの例を見てみましょう:

b=>{m=b;for(a=1;~-m;)--m,a*=m*m;return a%b}

まず、次のように単純化できます。

for(m=b,a=1;~-m;--m,a*=m*m)a%b;

ここで何をしましたか?さて、forステートメント内のすべてを単純に移動しました。これはセミコロンの量を減らすのに役立ちます。セミコロンの量は直接良くはありませんが、ほとんどの場合ゴルフにつながります。


これをevalに入れて、再帰バージョンと比較してみましょう。

b=>{m=b;for(a=1;~-m;)--m,a*=m*m;return a%b}
b=>eval('for(m=b,a=1;~-m;--m,a*=m*m)a%b')
b=>(f=a=>~-m?(--m,f(a*=m*m)):a%b)(1,m=b)

forループの最初の部分(a=n)、これらの変数を引数として渡すことで開始できます。条件は単純です:b?(c,f(a)):dどこdが戻り値です。通常c、変更するだけaでマージできます。だから、私が言ったことを使ってさらにゴルフをすることができます:

b=>(f=a=>~-m?(--m,f(a*=m*m)):a%b)(1,m=b)
b=>(f=a=>~-m?f(a*=--m*m):a%b)(1,m=b) // --m moved into a*=
b=>(f=a=>--m?f(a*=m*m):a%b)(1,m=b) // --m moved to condition

とはいえ、@ Nielが指摘しているように、アルゴリズムは単純化されています。ある言語でゴルファーのアルゴリズムは別の言語ではゴルファーではない場合がありますので、異なるアルゴリズムを試し、それらを比較してください。


1
元のコードを単純化することで大きな節約を逃しました。~-mis m-1であるため、ループが可能にfor(m=b,a=1;--m;a*=m*m)a%b;なり、再帰バージョンが可能になります(未テスト)b=>(f=a=>--m?f(a*=m*m):a%b)(1,m=b)
Peter Taylor

1
時には、あなただけの別のアルゴリズムを使用する必要がありますが、この場合には、私が行うことができる最高はPeterTaylorの答え@と同じ長さだった:b=>b>1&(f=a=>--a<2||b%a&&f(a))(b)
ニール

11

虐待評価。

簡単です。の代わりに:

f=n=>{for(i=c=0;i<n;i++)c+=n;return c}

使用する

f=n=>eval("for(i=c=0;i<n;i++)c+=n;c")

Evalは、最後に評価されたステートメントを返します。この場合、最後に評価されたステートメントはであるためc+=nc2バイトを節約することになります。

f=n=>eval("for(i=c=0;i<n;i++)c+=n")

一般に:

f=n=>eval("code;x")

これよりも1バイト短い:

f=n=>{code;return x}

注:墓を使用してevalを呼び出してバイトを節約することはできません。

eval`string`

に等しい

["string"]

難読化に役立ちます!コードゴルフではそれほどではありません。


2
foo`string`は常にに相当しfoo(["string"])、多くの関数が配列を目的の文字列にキャストするだけです。
ニール

@ニールああ、なんて面白い!
コナーオブライエン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.