Brainflak Multiplication Metagolf


17

この質問は、Brain-Flakの最初の誕生日を祝うために設計されたいくつかのBrain-flak Birthdayチャレンジの最初のものです!Brain-Flakの誕生日の詳細については、こちらをご覧ください。

昨年の夏、私たちはBrain-flak Integer Metagolfを作成し、それが生成した回答はBrain-Flakコミュニティにとって非常に役立ちました。整数メタゴルフを非常に効率的にする主なものは、乗算ハードコーディングと呼ばれる技術です。

Brain-Flakでは、実行時の乗算は非常に高価です。既知の最短の乗算スニペットは次のとおりです。

({}<>)({<({}[()])><>({})<>}{}<><{}>)

メガトムが発見

ただし、コンパイル時間の乗算を作成する非常に簡単な方法があります。たとえば、次のコードは5倍になります。

 (({})({})({})({}){})

オンラインでお試しください!

これは、連続した式が一緒に追加されるため機能します。それぞれ({})がスタックに対して何もせず({}ポップし(..)てすぐに押し戻します)、スタックの一番上にあるものを評価します。これらのすべての式は、スタックの一番上にあるものを合計すると最大5倍になります。

いずれかのためにn、以下の文字列式は、スタックの最上部を掛けますスニペットを行いますn

"("+"({})"*(n-1)+"{})"

これはn、すべてスタックの最上位に評価される式を作成することで機能します。最初のものn-1は実際には何も変更せず、最後のものはプッシュの前にスタックのトップを削除します。

複合数値の場合、複数の小さな式を連結してバイトを節約できます。たとえば、5を2回掛けることで25を掛けることができます。

(({})({})({})({}){})(({})({})({})({}){})

これは非常に単純であり、いくつかの数値ではかなりうまく機能しますが、これを行うより良い方法があります。たとえば、私が思いついた方法の1つは、数値のバイナリ表現を使用しています。(ここにpythonの実装があります)この新しいメソッドは、前に示した単純な文字列式よりもはるかに効果的ですが、終わりではありません。

だから、私たちがどれほど良いものを得ることができるかを見る時だと思います。

Brain-Flakの簡単な概要

このチャレンジでBrain-Flakについて知っておく必要があるすべての説明を以下に示します。

Brain-Flakには「nilads」と「monads」があります。ニラッドは、中に何もないカッコです。各niladは処理を行い、値を返します。この挑戦のために私達がかかわっている2人のniladsは{}あり<>ます。 {}アクティブなスタックの一番上をポップし、その値を返します。<>アクティブスタックとアクティブスタックを切り替え、アクティブスタックが非アクティブになり、非アクティブスタックがアクティブになるように、ゼロを返します。

モナドは、中に何かがある括弧です。それらは、単一の引数、内部のすべての合計を取り、アクションを実行してから値を返します。懸念しているこれらの3つは(...)<...>および[...]です。このチャレンジで最も重要なモナド(...)は、内部の値を取得してアクティブスタックにプッシュします。次に、引数を返します。 <...>そして[...]、彼らは任意のアクションを実行するのではなく、彼らが渡された値を変更しないでという、両方の「不活性」モナドです。 <...>渡された引数に関係なく、常にゼロを返します。一方、[...]常に引数timesを返します-1


説明付きのサンプルプログラム

Brain-Flakでプログラミングしたことがない場合は、説明されている操作を使用していくつかのサンプルプログラムを確認することをお勧めします。

({}{})

これにより、スタックの上位2つの数字が追加されます。それぞれ{}がスタックから値をポップし、(...)合計を押し戻します。

({}[{}])

同様に、これはスタックの2番目の項目を最初の項目から減算します。それぞれ{}が値をポップする前と同様ですが[..]、2番目の値の前後で値が追加されます。もう一度(...)合計をプッシュします。

({}<{}>)

これにより、スタックの2番目の値が削除され、トップの値がそのまま維持されます。最後の2つと同じように機能しますが、2つ目の値はによって無音化される<...>ため、プッシュは最初の値のみを押し戻します。

(({}))

これにより、スタックの一番上に値の2番目のコピーが作成されます。これは{}、値を取得してスタックの最上部をポップすることでこれを行い、最初に(..)値を評価してその値に戻します。2番目(...)は1番目から返された値を受け取り、それをスタックにプッシュします。2番目のコピーを作成します。

仕事

整数を指定nすると、現在のスタックの最上部にを掛けるスタッククリーンなBrain-Flakスニペットを作成しますn

次のBrain-Flak操作を使用することが許可されています

(...) -> Push Monad, Pushes the result of its contents
<...> -> Zero Monad, Returns zero
[...] -> Negative Monad, Returns the opposite of its contents result
{}    -> Pop nilad, Pops the TOS and returns its value
<>    -> Switch nilad, Switches the active and inactive stack

他の操作は、チャレンジの目的で禁止されています。

得点

スコアはからn=2までのすべてのプログラムの累積長になりn=10000ます。確認のため、プログラムの出力へのリンクを必ず含めてください。


1
興味深いことに、なぜ1およびループ操作が禁止されていますか?
ニール

@Neilスタックの高さ演算子も禁止されています。
エリックアウトゴルファー

1
@EriktheOutgolferとにかく、私は既に整数メタゴルフの1つを禁止していました。
ニール

7
コンピューター科学者は奇妙です。彼らは、使用することは不可能で、本質的にアンチゴルフであるプログラミング言語を発明し、この言語の簡単な問題を解決するためにゴルフされたコードを書くように互いに挑戦します。これ以上に難解なものはありません。+1良い先生。
Draco18sは、

1
@ Qwerp-DerpリンクされたPythonプログラム(現在のスコア681950)の出力の最適化を検討し、を使用して4492の些細な節約を見つけた[...]ので、それが始まりです。
ニール

回答:


2

ルビー、669856

$answers = Hash.new{|hash,n|
  valid = []
  2.upto(n**0.5){|i|
    valid.push("("+hash[n/i]+")"+"({})"*(i-2)+"{}") if n%i == 0
  }
  valid.push("({})"+hash[n-1])
  (hash[n] = valid.min_by{|s| s.length})
}
$answers[1] = "{}"

def full_answer n
  "("+$answers[n]+")"
end

これは簡単なベースラインの回答です。最初の1000分-のプログラムが見つかりました。ここに。(私はそれらのすべてを投稿しようとしましたが、それは最大ペーストビンサイズをオーバーロードしました。)後でコードの説明を追加するかもしれません。

例:

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