磁気彫刻…宇宙で!


8

バックグラウンド

これは、私の以前の課題の続きです。その課題は、磁石を巨大な山に落として得られた彫刻の形状を計算することでした。

朗報です。エキセントリックなアーティストはあなたの作品が好きで、あなたのために別のプロジェクトを持っています。彼はまだ磁気彫刻を使用していますが、アートスタジオを宇宙に拡張することにしました。彼の現在の方法は、単一の立方体の磁石を軌道に爆破し、他の磁石を発射して巨大な磁気衛星を作成することです。

入力

入力は、0sと1sの有限リストであり、言語のネイティブリスト形式または文字列のいずれかで指定されます。作品の「青写真」として解釈され、左から右へと次のように処理されます。

2D平面の整数座標に浮かぶ単一の磁石から始め、指示に従って磁石を追加し続けます。ディレクティブ0は、彫刻全体を反時計回りに90度回転させます。ディレクティブの場合1、アーティストは彫刻の左端の列を見つけ、新しい磁石を下から発します。新しい磁石は、柱の一番下にある既存の磁石にくっついて、彫刻の一部になります。以前の課題とは異なり、磁石は隣接する列の他の磁石にくっつかないことに注意してください。その速度は今や天文学的です!

出力

アーティストは、完全な彫刻がガレージに収まるかどうかを知りたがっています(軌道から降ろす方法は不明のままです)。したがって、出力は彫刻の幅と高さであり、低いものから高いものへと並べられます。それらは、2要素のリスト、ペア、またはコンマで区切られた文字列として指定できます。

入力シーケンスを検討する

[1,0,1,1,0,1,0,0,1,1]

それを処理するには、空間に浮かぶ1つの磁石から始めます。

#

最初のディレクティブは1なので、下から新しい磁石を撃ちます:

#
#

次のディレクティブは0なので、彫刻を回転させます。

##

次の2つのディレクティブは1,1です。つまり、2つの磁石を左端の列に向けて発射します。

##
#
#

次に、再び回転させて、次のように1回撮影し0,1ます。

#
###
#

最後に、2回回転して2回撃ちます。

  #
###
# #
#

結果の彫刻には幅3と高さ4があるため、出力します[3,4]

ルール

関数または完全なプログラムを与えることができます。最も低いバイト数が優先され、標準の抜け穴は許可されません。

テストケース

[1,0,1] -> [2,2]
[1,0,1,1,0,1,0,0,1,1] -> [3,4]
[1,1,0,1,1,0,1,0,1,1] -> [4,5]
[1,1,0,1,1,0,1,0,1,1,0] -> [4,5]
[1,0,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1,1] -> [3,3]
[0,1,0,1,1,1,1,0,0,1,0,1,0,0,1,1,0,1,0,1,0,0,1,1,0,1,0,0,0,0,1,0,1,0,1,1,0,0,1,1] -> [5,7]
[1,0,1,1,1,1,0,1,0,0,0,0,1,1,1,0,1,1,0,1,0,1,0,0,0,0,0,0,1,1,0,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,0,0,0,0,1,1,0,0,1,1,0,1,0,0,1,1,0,1,1,0,0,1,0,1,0,0,1,0,1,1,1,0,1,1,0,0,1,0,1,1,0,0,0,1,0,1,1,0,0,1,0,1,1,0] -> [11,12]

べきではない[1,1,0,1,1,0,1,0,1,1,0]戻る[5,4]といませんか[4,5]?最後に彫刻を回転させます。
algorithmhark

@algorithmshark私も同じ間違いをしました。出力セクションでは、結果を順序付けする必要があることを指定しています。
マーティンエンダー2015年

1
@MartinBüttnerは正しいです。正当化は、あなたが宇宙にいるとき、向きは重要ではないということです。:P
Zgarb 2015年

回答:


8

Pyth34 33バイト

Sml{dCuS?+G,hhGtehGHm,_ekhkGQ],ZZ

入力は、質問のように、1と0のリストです。オンラインで試す:Pyth Compiler / Executor

説明:

これは、次のPython 2コード(126バイト)を1対1で変換したものです

print sorted(map(len,map(set,zip(*reduce(lambda s,i:([[-b,a]for a,b in s],s+[[min(s)[0],min(s)[1]-1]])[i],input(),[[0,0]])))))

単一の磁石の座標のリストを作成します。これは磁石で初期化され[0,0]ます。次に、ブループリントの整数ごとに、次のようにリストを操作します。次の整数が0である場合、各磁石の座標[a,b][-b,a](基本的に回転行列で乗算して)変更することにより、彫刻を回転させます。次の整数がである場合、1最小のピース[a,b](これは自動的に左端の列の一番下の磁石です)を検索し、磁石[a,b-1]をリストに追加します。

すべての入力が処理されたら、2つのセット(重複を削除するため)を作成します。1つはx値用で、もう1つはy値用で、それらのサイズを並べ替えて出力します。

Sml{dCuS?+G,hhGtehGHm,_ekhkGQ],ZZ
                             ],ZZ  starting list G=[(0,0)]
      u                     Q],ZZ  for H in input(): manipulate G
       S                              Sort G after each manipulation
        ?          H                  G = ... if H==1 else ...
                    m,_ekhkG            [(-b,a) for a,b in G)] (rotate)
         +G,hhGtehG                     G+[(G[0][0],G[0][1]-1)]
                                        (G[0] is the lowest magnet in the leftmost column)
     C                             Zip the coords together
                                    (creates 2 lists, x- and y-coords)
 ml{d                              for each of those list compute number of unique values
S                                  sort and print

改善アイデア:磁石の座標として複素数を使用する。回転は、左端の列の最も低い磁石による乗算jと減算jです。悲しいことに、この最も左下の磁石を見つけると、Pythonで非常に多くの文字が必要になり、長方形を見つけることさえ話しません。


7

CJam、48バイト

S]l~{{)S/);Sa+S*a+_z,f{_N*@\+<}}{zW%}?}/_,\z,]$p

ここでテストしてください。

入力はCJamスタイルの配列(つまり、コンマではなくスペース)であると想定し、同様に出力を表示します。質問から直接テストケースを使用する場合は、それらを入力フィールドに直接コピーし(->結果と結果を含む)、このテストハーネスを使用して、行を正しい入力形式に変換します(結果を破棄します)。

qN/{S/0=","Ser}%{[

S]\~{{)S/);Sa+S*a+_z,f{_N*@\+<}}{zW%}?}/_,\z,]$p

}/

説明

私はルールを文字通り非常に実装しています。現在の彫刻(文字列の配列)でグリッドを保持し、各命令でグリッドを回転するか、新しいブロックを追加します。バイトを節約するための主なトリックは次のとおりです。

  • から下の行に追加します。これは完全に同等です。私は1回転先ですが、グリッドは回転不変で始まるため、問題ではありません。
  • 使用中のブロックを表すにはスペースを使用し、空のブロックを表すには改行文字を使用します。したがって、実際にグリッドを印刷した場合、全体が見えず、長方形に見えません。私がこれを行っているのは、ほとんどの配列ベースの演算子は、問題のグリッド要素が配列にラップされている場合にのみ必要なことを行うためです。そしてとSし、N私がアクセスしていた文字列のスペースと改行文字(列に包まれた、すなわち文字)を含むが、代わりに使用することの、と言う、1a0a番号を含む配列を取得します。

コードを見てみましょう:

"Overall program structure:";
S]l~{{...}{...}?}/_,\z,]$p
S]                         "Push a string with a space and wrap it in an array.
                            This is the initial grid containing a single block.";
  l~                       "Read the input and evaluate it.";
    {           }/         "For each instruction in the input...";
     {...}{...}?           "Execute the first block if it's 1, the second if it's 0.";
                  _,       "Duplicate the resulting grid and get its length. This
                            is one of the dimensions.";
                    \      "Swap with the other copy of the grid.";
                     z,    "Zip/transpose it and get its length. This is the other
                            dimension of the grid.";
                       ]$p "Wrap both in an array, sort them, and print the result.";

"The rotation block is simple. A rotation is equivalent to two reflection operations
 along different axes. The simplest ones available are to transpose the grid (which
 is a reflection about the diagonal) and reversing the rows (which is a reflection
 about the horizontal). In CJam these are z for zip/tranpose and W% for reversing
 an array. So I simply put these together in the right order to get a counter-
 clockwise rotation:";
zW%

"Now the interesting part, adding new blocks and growing the grid. This part consists
 of two steps: appending a block to the rightmost block in the bottom row (allowing
 for empty blocks after it). And then potentially padding the rest of the grid with
 new empty cells if the bottom row got longer.";
)S/);Sa+S*a+_z,f{_N*@\+<}
)                         "Split off the bottom row.";
 S/                       "Split the row on occupied blocks.";
   );                     "Split off the final substring - this discards trailing
                           empty cells.";
     Sa+                  "Add a new substring containing an occupied block to the row.";
        S*                "Join all substrings together with spaces, putting back in
                           all the occupied blocks.";
          a+              "Wrap it in an array to add the row back onto the grid.";

 "At this point we need to make sure the grid is still rectangular. The easiest way
  (I found) is to find the maximum row length, add that many empty blocks to each 
  line and then truncate the lines to that length.";

            _             "Duplicate the grid.";
             z,           "Zip/transpose it and get the length. This is the length
                           of the longest row in a ragged array.";
               f{       } "Map this block onto each row, passing in the target length.";
                 _N*      "Duplicate the target length and get a string of that many
                           empty cells.";
                    @\    "Pull up the row and then swap it with those empty cells.";
                      +   "Add the empty cells to the end of the row.";
                       <  "Truncate to the target length.";

これがどのように機能するかはわかりませんが、機能します!
Luis Mendo 2015年

@LuisMendo説明を追加しました。不明な点があり、興味がある場合は、遠慮なく別のコメントを送ってください。;)
マーティンエンダー

私はCJamについて何も知りません、そしてそれは正確に簡単な言語ではないようです。あなたはすでに私の+1を持っていました:-)
Luis Mendo 2015年

4

Matlab(92)

S=1;for d=input(''),if d,S(find(S(:,1),1,'last')+1,1)=1;else,S=rot90(S);end;end,sort(size(S))

標準入力が使用されます。データはの形式で導入する必要があります[1,0,1,1,0,1,0,0,1,1]

未ゴルフ:

S = 1; %// initial magnet
for d = input('') %// get directives, and pick them sequentially
    if d %// if directive is 1
        S(find(S(:,1),1,'last')+1,1) = 1; %// add 1 after lowest 1 in column 1. Grow if needed
    else %// if directive is 0
        S = rot90(S); %// rotate counterclockwise. Handy Matlab built-in function
    end
end
sort(size(S)) %// display size sorted

実行例:

>> clear all
>> S=1;for d=input(''),if d,S(find(S(:,1),1,'last')+1,1)=1;else,S=rot90(S);end;end,sort(size(S))
[1,0,1,1,0,1,0,0,1,1]
ans =
     3     4

1

パイソン-211

import numpy as n
p=input()
q=len(p)
a=n.zeros([2*q+1]*2)
a[q,q]=1
for i in p:
 if i:x=a[:,n.where(a.any(0))[0][0]];x[len(x)-n.where(x[::-1])[0][0]+1]=1
 else:a=n.rot90(a)
z=a[:,a.any(1)]
print z[a.any(0)].shape

出力は低い方から高い方にソートする必要があります!また、プログラムは入力に対して中断します[1]
ジャクベ2015年

0

CJam、47バイト

1]]q~{{0f+(W%_1#(1tW%a\+z{1b},}{W%}?z}/),\,)]$p

これは、STDINからCJamスタイルの(コンマではなくスペースで区切られた)配列入力を受け取り、結果をSTDOUTに出力します。

例:

[1 0 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1]

与える

[3 3]

出力。

これ以上ゴルフをすることはできないと私が確信した後に続く説明。

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

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