Befungeプログラムを圧縮する


17

Befungeは2次元の難解なプログラミング言語です。基本的な考え方は、(1文字の)コマンドが2次元グリッドに配置されるということです。制御フローはグリッド上を移動し、通過するコマンドを実行し、矢印にヒットすると方向を変更します(>^<v)。コマンドはスタックベースです。このリストを参照してください。http://esolangs.org/wiki/Befungeも参照してください

Befunge-98の仕様が利用可能です。

問題

Befungeプログラムをよりコンパクトな表現に変換するプログラムを作成します。たとえば、次のプログラムは印刷します0

>   0   v

>   @   .

^       <

この場合、スペースの行を削除することにより、プログラムの動作を変更せずに圧縮できます。

>0v
>@.
^ <

より洗練された変換は、コマンドのシーケンスを回転またはミラー化し、プログラムを圧縮するために不要な制御フローコマンドを排除できます。たとえば、このプログラムでは:

>12345v
      6
v....7<
.
.
.
@

プログラムの終わりを穴に押し込むかもしれません。

>12345v
>...@ 6
^....7<

最初の例では、可能な限り最もコンパクトなプログラムは

>0.@

出力プログラムで同じ結果が得られる限り、任意の変換を使用できます。

入力プログラム

入力プログラムは有効なBefunge-98プログラムです。

入力プログラムが決定論的であると仮定することができます。つまり、外部状態を読み取るコマンドは使用しません。ユーザー入力コマンド&~、ランダマイザー?、および自己修正コードコマンドpgです。

入力プログラムが終了することを想定できます。

得点

これはコードゴルフではありませんが、コードゴルフを実行するプログラムを作成する問題です。

入力はテストケースのセットです(上記の入力制限を満たすBefungeプログラム)。合計スコアは、テストケースのスコアの合計です。

各テストケースのスコア

スコアは、出力プログラムの空でないセルの凸包の面積です。各セルは、4つの角がデカルト平面の格子点である正方形として扱われます。たとえば、

>   v
 @  <

9.5のスコアを取得します。

プログラムが特定の入力で妥当な時間とメモリで終了しない場合、スコアは入力プログラムのスコアです。(これは、プログラムが時間内に終了しない場合、入力プログラムを変更せずに出力する時間制限ラッパーを簡単に追加できるためです。)

プログラムで処理した後、テストケースプログラムの結果が異なる(または終了しない)場合、スコアは入力プログラムのスコアに100ポイントのペナルティを加えたものです。


8
プログラムを最後まで実行して、同じ出力を出力するBefungeプログラムを作成しないようにするにはどうすればよいですか?
キースランドール

5
「get」と「put」は許可されていますか?「put」(自己修正コード)を許可すると、何もするのが難しくなります。
キースランドール

2
実行はどこから始まりますか?左上隅?その場合、2番目の例の出力を説明できますか?.出力整数を意味しますが、左上から開始する場合、スタックに出力する整数はありません。
elssar

1
@elssarはい、.整数を出力します。しかし、スタックに十分なパラメーターがない場合、befungeは代わりに十分な量のゼロがあるふりをします。したがって、2番目の例は出力されます000
ダニエロ

@KeithRandall:同じ出力で新しいプログラムを作成すると、短い出力のプログラムでのみ機能します。gそしてp許可されていません(申し訳ありませんが、それらを忘れて、編集しました)。
機械式カタツムリ

回答:


12

これをコーディングするのに長い飛行機に乗った。私は、befungeプログラムを実行し、基本的なブロックを抽出し、それらをコンパクトな表現でレイアウトする疑似befungeコンパイラーを作成しました。

プログラムへのリンク

この99本のボトルプログラムで実行すると:

92+9*                           :. v  <
>v"bottles of beer on the wall"+910<
,:
^_ $                             :.v
            >v"bottles of beer"+910<
            ,:
            ^_ $                     v
>v"Take one down, pass it around"+910<
,:
^_ $                           1-v
                                 :
        >v"bottles of beer"+910.:_          v
        ,:
        ^_ $                          ^
                    >v" no more beer..."+910<
                    ,:
                    ^_ $$ @

次の出力が生成されます。

92+9*:.019+"llaw eht no "v
v  _v# :"bottles of beer"<
>    ,:    v
^  _v#     <
    >$:.019+"reeb f"v
 v _  v#:"bottles o"<
 >     ,:  v
 ^ _  v#   <
      >$019+"dnuo"v
     v"pass it ar"<
     >" ,nwod eno"v
 v _    v#:"Take "<
 >       ,:v
 ^ _    v# <
        >$1-:v
 v _      v# <
 >         :.019+"reeb "v
  v_  v#   :"bottles of"<
  >        ,v
  ^_  v#   :<
      >    $019+"llaw"v
           v" on the "<
           >"reeb fo "v
^  _^#      :"bottles"<
          >019+"...r"v
v  _v#:" no more bee"<
>    ,:    v
^  _v#     <
    >$$@    

実際にはソースよりもはるかにコンパクトではありませんが、おそらくより大きく/よりまばらなプログラムでより良くなります。

プログラムは、左側にルーティングエリア、右側に基本ブロックコンテンツでレイアウトされます。基本ブロックは通常、偶数列に配置されているため、入口と出口はルーティングエリアに隣接しています。各基本ブロックの最後に、#^_v右から左にレイアウトされたガジェットとバリアントが条件分岐を行い、フローを列にルーティングします。各基本ブロックの開始時に、これらの列は宛先基本ブロックの行にルーティングされます。

さらに、出力が短い場合は、次のように出力を明示的に生成するだけです。

"output">:#,_@

基本的なブロック自体を最適化するために何もしていません。レイアウトだけです。藤堂。

では、テストはどこにありますか?


1
ソースコードのリンクは現在500になっているようです。サーバーの設定ミス?
ジョンドボラック

1
@JanDvorak:確かに。修繕。
キースランドール

1

Sed、5文字

そのため、これがcodegolfでなくても、スコアの比率に対するスコアの長さは比較的良好ですが、必ずしも良いスコアではないソリューションがあります。

/^$/d

単に空白行を削除するだけです。


10
コードが正しくありません!単に空白行を削除することはできません。コメントに2Dコードを書くことはできません。ただし、方向が下向きで、一定の文字列が開始される(")場合を考えます。途中のすべての空白行はスペース文字として扱う必要があります。その文字列を出力する場合、生成したコードの出力にはそのスペースがありません!
saeedn

3
ideone.com/BdcRcfのコードをてくださいb a。ただし、短縮後は印刷されますba
サイード
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.