スチームパンク:Clackerアニメーション


11

過小評価されているスチームパンク小説The Difference Engineでは、映画館に相当するものが、機械的に反転できるタイルで表示されるピクセル化された動画を配信しました。これらのタイルの動きを調整するための制御エンジンは、パンチされたカードのデッキによって制御される大きなノイズの多いマシンでした。

あなたの仕事は、そのようなエンジンをエミュレートし、入力ファイルで指定されたピクセル化されたアニメーションを表示することです。入力は固定幅形式の行で構成されますが、行末を示すのに便利なものは何でも想定できます。形式は次のとおりです。

SSSSYYxxXXOA
SSSS: 4 digit sequence no. may be padded by blanks or all blank
    YY: the y coordinate affected by this line (descending, top is 0, bottom is m-1)
      xx: the starting x coordinate
        XX: the ending x coordinate
          O: hexadecimal opcode
           A: argument (0 or 1)

入力は明示的に順序付けされます(カードデッキを床に落とした場合は、この部分に感謝します)。つまり、プログラムは、ソートフィールドとしてシーケンスフィールドを使用して、入力行の安定したソートを実行する必要があります。同じシーケンス番号を持つ行は、元の相対的な順序を維持する必要があります。(実際の行番号をキーに追加すると、不安定なソートで動作するはずです。)空白のシーケンスフィールドは、任意の数値よりも低いと解釈される必要があります(ascii照合シーケンス)。

単一のステートメント行は単一のy座標にのみ影響を与えますが、x値の連続した範囲を指定できます。単一のピクセルに影響を与えるために、終了x値は空白のままにするか、初期値と同じにすることができます。

オペコードは、ラスタロップとして使用されるユニバーサルバイナリ関数コードを指定する16進数です。引数は0または1です。実行されるラスター操作は

pixel = pixel OP argument          infix expression
         --or-- 
        OP(pixel, argument)        function call expression

したがって、ピクセルの元の値はUBFテーブルにXとして入り、ステートメントからの引数値はYとして入ります。この関数の結果はピクセルの新しい値です。そして、この操作は、ステートメントで指定されたxx、YYからXX、YYまでの各x、yのペアに対して実行されます。xxおよびXXで指定された範囲には、両方のエンドポイントが含まれます。そう

0000 0 010F1

行0にピクセル0,1,2,3,4,5,6,7,8,9,10を設定する必要があります。

出力寸法(m x n)は少なくとも20 x 20である必要がありますが、必要に応じて大きくすることができます。しかし、穀物は表示されるはずです。ピクセル化されることになっています。グラフィカル出力とASCIIアート出力の両方が許容されます。

たとえば、ピクセル化された図の画像を作成したい場合:

  #   #
   ###
   ##
   ####
    #
#### ####
   # #

   ###
   # #
   # #

XORのようなビット反転操作で描画すると、画面が黒か白かに関係なく描画および消去できます。

    00020261
     0 6 661
     1 3 561
     2 3 461
     3 3 661
     4 4 461
     5 0 361
     5 5 861
     6 3 361
     6 5 561
     8 3 561
     9 3 361
     9 5 561
    10 3 361
    10 5 561

このシーケンスを複製すると、図が表示されたり消えたりします。

NMMはミッキーマウスではありません

シーケンスフィールドに異なる「ショット」を指定することで、より大きなアニメーションを順不同で構成できます。

   100 016F0
   101 016F0
   102 016F0
   103 016F0
   104 016F0
   105 016F0
   106 016F0
   107 016F0
   108 016F0
   109 016F0
   110 016F0
   111 016F0
   112 016F0
   113 016F0
   114 016F0
   115 016F0
   200020261
   2 0 6 661
   2 1 3 561
   2 2 3 461
   2 3 3 661
   2 4 4 461
   2 5 0 361
   2 5 5 861
   2 6 3 361
   2 6 5 561
   2 8 3 561
   2 9 3 361
   2 9 5 561
   210 3 361
   210 5 561
    00020261
     0 6 661
     1 3 561
     2 3 461
     3 3 661
     4 4 461
     5 0 361
     5 5 861
     6 3 361
     6 5 561
     8 3 561
     9 3 361
     9 5 561
    10 3 361
    10 5 561
   300020261
   3 0 6 661
   3 1 3 561
   3 2 3 461
   3 3 3 661
   3 4 4 461
   3 5 0 361
   3 5 5 861
   3 6 3 361
   3 6 5 561
   3 8 3 561
   3 9 3 361
   3 9 5 561
   310 3 361
   310 5 561
    00020261
     0 6 661
     1 3 561
     2 3 461
     3 3 661
     4 4 461
     5 0 361
     5 5 861
     6 3 361
     6 5 561
     8 3 561
     9 3 361
     9 5 561
    10 3 361
    10 5 561

生産:

黒/白vs白/黒

これはので、最短のプログラム(バイト数)が勝ちます。エンジンがクリック音を鳴らす場合、ボーナス(-50)。


3
通常、サンドボックスに投稿することにより、説明を要求します。サンドボックスをシャットダウンしようとしていますか?
ジョン・ドヴォルザーク

5
個人的には、サンドボックスは行き止まりです。私はそれらを完了するために先延ばしが得意です。ここで、ライブ、お尻の下の火を無視することはできません。
luser droog

1
ブール型コネクタはどのように機能しますか?同じシーケンス番号の行のみを結合しますか?それらが混在している場合、演算子の優先順位の形式はありますか?ブール型コネクタに依存するテストケースはありますか?投稿したテストケースにシーケンス番号がないのはなぜですか?終了x座標は常に包括的ですか?
ピーターテイラー

5
ここにいくつかのかわいらしいひび割れ音があります。ボーナスはもらえますか?;-)
デジタル外傷

1
音については、駅のフリップボードのようなものを考えていますか?たとえば、パリのガールデュノール駅のソラリボードスプリットフラップディスプレイ-DIY ドライバー回路。または、より機械的なリレー音を考えていますか?
スコットリードリー

回答:


3

Mathematica、306 281バイト

これは、入力文字列が変数に格納されることを想定しています i

ListAnimate[ArrayPlot/@FoldList[({n,y,x,X,o,a}=#2;MapAt[IntegerDigits[o,2,4][[-1-FromDigits[{#,a},2]]]&,#,{y+1,x+1;;X+1}])&,Array[0&,{20,20}],ToExpression/@MapAt["16^^"<>#&,StringTrim/@SortBy[i~StringSplit~"\n"~StringCases~RegularExpression@"^....|..(?!.?$)|.",{#[[1]]&}],{;;,5}]]]

そして、ここにいくつかの空白があります:

ListAnimate[ArrayPlot /@ FoldList[(
     {n, y, x, X, o, a} = #2;
     MapAt[
      IntegerDigits[o, 2, 4][[-1 - FromDigits[{#, a}, 2]]] &,
      #,
      {y + 1, x + 1 ;; X + 1}
      ]
     ) &,
   Array[0 &, {20, 20}],
   ToExpression /@ 
    MapAt["16^^" <> # &, 
     StringTrim /@ 
      SortBy[i~StringSplit~"\n"~StringCases~
        RegularExpression@"^....|..(?!.?$)|.", {#[[1]] &}], {;; , 5}]
   ]]

これはかなり長くなりました。この課題には多くの厄介な詳細が含まれており、特に入力解析はMathematicaで多くのコードを必要とします(そのほぼ半分、137バイトは入力を解析するだけです)。Mathematicaに落ち着く前に言語を2回切り替えることになりました(Rubyを使用して入力解析を節約できると思いましたが、結果をアニメーション化する必要があることに気づいたので、Mathematicaに戻りました)。


2

Ungolfed Postscriptの例

これは「プロトコル-プロローグ」スタイルのプログラムなので、データは同じソースファイル内ですぐに続きます。アニメーションgifファイルは、ImageMagickのconvertユーティリティ(ghostscriptを使用)で作成できますconvert clack.ps clack.gif

%%BoundingBox: 0 0 321 321

/t { token pop exch pop } def
/min { 2 copy gt { exch } if pop } def
/max { 2 copy lt { exch } if pop } def

/m [ 20 { 20 string }repeat ] def
/draw { change {
        m {} forall 20 20 8 [ .0625 0 0 .0625 0 0 ] {} image showpage
    } if } def

%insertion sort from https://groups.google.com/d/topic/comp.lang.postscript/5nDEslzC-vg/discussion
% array greater_function insertionsort array
/insertionsort
{ 1 1 3 index length 1 sub
    { 2 index 1 index get exch % v, j
        { dup 0 eq {exit} if
            3 index 1 index 1 sub get 2 index 4 index exec
            {3 index 1 index 2 copy 1 sub get put 1 sub}
            {exit} ifelse
        } loop
        exch 3 index 3 1 roll put
    } for
    pop
} def

/process {
    x X min 1 x X max { % change? x
        m y get exch  % row-str x_i
        2 copy get  % r x r_x 
        dup         % r x r_x r_x
        0 eq { 0 }{ 1 } ifelse  % r x r_x b(x)
        2 mul a add f exch neg bitshift 1 and   % r x r_x f(x,a)
        0 eq { 0 }{ 255 } ifelse  % r x r_x c(f)
        exch 1 index % r x c(f) r_x c(f)
        ne { /change true def } if
        put
    } for
    draw
} def

{ [ {
     currentfile 15 string
         dup 2 13 getinterval exch 3 1 roll
         readline not{pop pop exit}if
    pop
    [ exch
     /b exch dup 0 1 getinterval exch
     /n exch dup 1 1 getinterval exch
     /seq exch dup 2 4 getinterval exch
     /y exch dup 6 2 getinterval t exch
     /x exch dup 8 2 getinterval t exch
     /X exch dup 10 2 getinterval dup (  ) ne { t exch }{pop 2 index exch} ifelse
     /f exch dup 12 get (16#?) dup 3 4 3 roll put t exch
     /a exch 13 get 48 sub
     /change false def
    >>
}loop ]
dup { /seq get exch /seq get exch gt } insertionsort
true exch
{ begin
    b(A)eq{
        { process } if
    }{
        b(O)eq{
            not { process } if
        }{
            pop
            process
        }ifelse
    }ifelse
    change
    end
} forall
    draw
} exec
   100 016F0
   101 016F0
   102 016F0
   103 016F0
   104 016F0
   105 016F0
   106 016F0
   107 016F0
   108 016F0
   109 016F0
   110 016F0
   111 016F0
   112 016F0
   113 016F0
   114 016F0
   115 016F0
   200020261
   2 0 6 661
   2 1 3 561
   2 2 3 461
   2 3 3 661
   2 4 4 461
   2 5 0 361
   2 5 5 861
   2 6 3 361
   2 6 5 561
   2 8 3 561
   2 9 3 361
   2 9 5 561
   210 3 361
   210 5 561
    00020261
     0 6 661
     1 3 561
     2 3 461
     3 3 661
     4 4 461
     5 0 361
     5 5 861
     6 3 361
     6 5 561
     8 3 561
     9 3 361
     9 5 561
    10 3 361
    10 5 561
   300020261
   3 0 6 661
   3 1 3 561
   3 2 3 461
   3 3 3 661
   3 4 4 461
   3 5 0 361
   3 5 5 861
   3 6 3 361
   3 6 5 561
   3 8 3 561
   3 9 3 361
   3 9 5 561
   310 3 361
   310 5 561
    00020261
     0 6 661
     1 3 561
     2 3 461
     3 3 661
     4 4 461
     5 0 361
     5 5 861
     6 3 361
     6 5 561
     8 3 561
     9 3 361
     9 5 561
    10 3 361
    10 5 561
0000 0 515F1
0000 1 11501
0000 1 115F1

境界ボックス情報はを実行して発見されましたgs -sDEVICE=bbox clack.ps
luser droog
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.