グリッドタングラムを解く


22

タングラムは五異なるサイズの三角形、平行四辺形や広場:7つの形状から作られた解剖パズルです。形状が与えられた場合、目標は、すべてのピースを使用して、重複することなく形状を再作成することです。このピースのセットを平面に配置するには、明らかに無限に多くの方法があります。興味深いサブセットは

グリッドタングラム

「標準の」タングラム正方形を、グリッドで 16個の小さな正方形に分割された大きな正方形に描画できます。グリッドタングラムは、タングラムのすべての頂点がグリッドポイント上にあるように、タングラムのピースで構成される形状です。

これらは、おそらくより一般的なものよりも扱いやすいため、この課題で検討したいタングラムパズルの種類です。

補足:中国の数学者であるChuan-Chin HsiungとFu Traing Wangは、1942年に凸タングラムが13個しかないことを証明しました。彼らはまず問題をグリッドタングラムに縮小できることを示し、次にいくつかの組み合わせおよび幾何学的引数を使用しました。これらはすべて13です。

チャレンジ

解けるグリッドタングラムが与えられた場合、グリッドタングラムの解剖を7つのタングラムピースに出力します。

IO

タングラムは、両側が50pxの倍数である白黒画像(形状は黒、背景は白)として与えられます。グリッドの幅は正確に50pxです。グリッド線は画像の側面に平行です。

編集:画像は入力として受け入れられ、PNG、TIFF、PBMなどの便利なラスター画像形式で出力として返されますが、バイナリ2d配列または文字列または行列としての表現は受け入れられます。

出力も同じサイズで同じ形状である必要がありますが、各ピースの色が異なるか、すべてのピースを分離する白い線が必要です。四角形以外の四角形を反転できることに注意してください。

ピースの境界上のピクセルは、シェイプ上のピクセルと正確に一致する必要はありません。エイリアシング効果やその他のファズがある場合でも、これで問題ありません。

入力と出力の例:

例:

可能な解決策:


この課題において、画像処理はまったく不要なハードルです。入力を小さなバイナリ配列として指定した場合、より魅力的になります。
スパー

1
私が言ったように、それはサンドボックスにあったときに議論されました。しかし、タスク自体ははるかに難しいため、多くのバイトが追加されるとは思いません。
-flawr

3
私は、インプットとアウトプットを現状のままにすることを勧めた人の一人でした。私は、これがタングラムの課題を提示するのに最も自然でふさわしい方法だからです。どんな形式の入力/出力もかなりのバイト数を必要とするため、ここでは実際に問題になるとは思いません。
エレンディアスターマン

1
Elendiaに同意します。グラフィカルI / Oの唯一の問題は、グラフィック機能を持たない言語を制限する可能性があることです。とはいえ、PBMとPGMはASCIIアートに非常に近いので、人々がそのような形式を知っている場合、実際の問題はありません。en.wikipedia.org/wiki/Netpbm_format
Level River St

1
@LevelRiverStそれは良い点です。これらの形式を使用したり、たとえば0と1の2D配列/文字列を使用したりすることは完全に受け入れられると思います。
-flawr

回答:


31

BBC BASIC、570 514 490バイトASCII

http://www.bbcbasic.co.uk/bbcwin/download.htmlからインタープリターをダウンロードします

トークン化された435バイト

完全なプログラムは、L.bmp画面に入力を表示し、それを修正して解決策を見つけます。

*DISPLAY L
t=PI/8q=FNa(1)
DEFFNa(n)IFn=7END
LOCALz,j,p,i,c,s,x,y,m,u,v
F.z=0TO99u=z MOD10*100v=z DIV10*100ORIGINu,v
F.j=0TO12S.4p=0F.i=j+3TOj+9S.2c=9*COS(i*t)s=9*SIN(i*t)p=p*4-(POINT(c,s)<>0)*2-(POINT(9*c,9*s)<>0)N.
m=n:IFn=5A.(43A.p)=0p=0m=7
IF(ASCM."??O|(C",n)-64A.p)=0THEN
F.i=-1TO0GCOL0,-i*n:c=99*COS(j*t)s=99*SIN(j*t)y=402/3^m MOD3-1MOVE-c-s*y,c*y-s:x=n<3MOVEc*x-s*x,s*x+c*x:x=2778/3^m MOD3-1y=5775/3^m MOD3-1PLOT85-32*(n MOD6>3),c*x-s*y,s*x+c*y:IFi q=FNa(n+1)ORIGINu,v
N.
ENDIF
N.N.=0

説明

BBCベーシックでは、距離が1ピクセル= 2ユニットなので、50x50ピクセルグリッドは100x100グリッドになることに注意してください。

再帰関数を使用して、2つの大きな三角形、中程度の三角形、正方形、平行四辺形を形状に配置します。リスト内の以前の形状は、次の再帰呼び出しが行われる前に描画されます。解決策を見つけることなく再帰呼び出しが返される場合、以前の図形は黒でオーバードローされ、以前の図形の新しい位置が試行されます。

これらの5つの形状が描画されたら、2つの小さな三角形を配置するのは単なる形式です。ただし、共通のエッジを共有している場合はそれらを区別するために、そのうちの1つを描画する必要があります。2つの小さな三角形の1つだけに色を付けます。もう一方は自然な黒のままです。

各形状の配置は、異なるX、Y座標で、4つの異なる回転で試行されます。図形を描くための空きスペースがあるかどうかをテストするために、45度の角度で以下のテンプレートを使用します。回転が行われ、*テストされた8ピクセルは半径9および81単位の2つの半円で、xおよびy軸に対して22.5度の奇数倍の放射線に当たります。

大きな三角形の場合、8つのスペースすべてをクリアする必要があります。他の形状の場合、マスクが適用されるように、一部のセルのみが透明でなければなりません。

+----+----   Shape             Mask HGFEDCBA Mask decimal 
|\ E/|\G /  
| \/F|H\/    1,2. Large triangle    11111111    -1
|C/\ | /     3. Med triangle        00001111    15
|/ D\|/      4. Square              00111100    60
+----*       5. Parallelogram       11101000   -24
|\ B/        6. Small triangle      00000011     3
|A\/         7. Parallogr reversed  00101011    43
| /          Note: reversed parallelogram is checked/drawn at recursion depth n=5
|/           with a special check, but the coordinates are encoded as m=7.  

形状が適合することが確定したら、それを描画する必要があります。三角形の場合、でプロットされますPLOT 85。それが平行四辺形の場合、数値は32大きくなります(PLOT正方形を特別な平行四辺形と見なすことに注意してください)。いずれの場合も、3つの連続した頂点を指定する必要があります。2番目の頂点は、形状の原点(*上記の表でマーク)です。ただし、大きな三角形の場合は例外です(回転前)-1,-1.。他の2つの頂点は、xおよびy座標を-1,0 or 1ベース3から抽出できます。符号化された数値は、その後99によってスケーリングされ、形質転換によって、必要に応じて回転するcs

未ゴルフコード

  *DISPLAY L
  t=PI/8                                          :REM Constant 22.5 degrees.
  q=FNa(1)                                        :REM Call function, return dummy value to q
  END                                             :REM End the program gracefully if no solution. Absent in golfed version.

  DEFFNa(n)                                       :REM Recursive function to place shapes.
  IFn=7END                                        :REM If n=7 solution found, end program.
  LOCALk,z,j,p,i,c,s,x,y,m,u,v                    :REM declare local variables for function.
  k=ASCMID$("??O|(C",n)-64                        :REM Bitmasks for big tri, big tri, med tri, sq, normal paralellogram, small tri.
  FORz=0TO99                                      :REM For each point on the grid
    u=z MOD10*100:v=z DIV10*100                   :REM calculate its x and y coordinates relative to bottom left of screen
    ORIGINu,v                                     :REM and set the origin to this point.
    FORj=0TO12STEP4                               :REM For each rotation 0,90,180,270deg
      p=0                                         :REM assume no non-black pixels found
      FORi=j+3TOj+9STEP2                          :REM test angles of 3,5,7,9 times 22.5 deg anticlockwise from right x axis.
        c=9*COS(i*t)                             :REM Coords of test points at radius ll
        s=9*SIN(i*t)
        p*=4                                      :REM Leftshift any existing data in p
        p-=(POINT(c,s)<>0)*2+(POINT(9*c,9*s)<>0)  :REM and check pixels at radius 11 and 99.
      NEXT
      m=n                                         :REM The index of the shape to plot normally corresponds with recursion depth n.
      IF n=5 AND (43ANDp)=0 p=0:m=7               :REM If n=5 check if a reverse parallelogram is possible (mask 43). If so, clear p and change m to 7.
      REM                                         :REM Check p against mask k, if the shape fits then...
      IF (k ANDp)=0 THEN
        FOR i=-1 TO 0                               :REM draw the shape in colour, and if deeper recursions prove unsuccesful, redraw it in black.
          GCOL0,-i*n                                :REM Colour is equal to n.
          c=99*COS(j*t)                             :REM Set parameters c and s for scaling by 99
          s=99*SIN(j*t)                             :REM and rotation by 0,90,180 or 270 as appropriate.
          x=-1                                      :REM For vertex 1, x=-1 always.
          y=402/3^m MOD3-1                          :REM Lookup y value for vertex 1.
          MOVEc*x-s*y,s*x+c*y                       :REM Use c and s to transform the vertex and move to it.
          x=n<3                                     :REM For vertex 2, coords are 0,0 except for large triangle where they are -1,-1
          y=x                                       :REM in BBC BASIC, TRUE=-1
          MOVEc*x-s*y,s*x+c*y                       :REM Use c and s to transform the vertex and move to it.
          x=2778/3^m MOD3-1                         :REM Lookup x and y value for vertex 3.
          y=5775/3^m MOD3-1                         :REM PLOT85 uses last 2 points + specified point to make triangle, PLOT85+32 makes paralelogram (or square.)
          PLOT85-32*(n MOD6>3),c*x-s*y,s*x+c*y      :REM Use c and s to transform the vertex and draw shape.
          IFi q=FNa(n+1):ORIGINu,v                  :REM If i=-1 recurse to next level. If it fails, reset the origin before replotting this level's shape in black.
        NEXT
      ENDIF
    NEXT
  NEXT
  =0                                                :REM Dummy value to return from function

出力

これは、テストケース用のプログラムで見つかったソリューションのモンタージュです。ゴルフの理由で100ではなく99を使用すると、小さな黒い隙間が残ります。検索中に図形が再描画されるため、場合によっては実行に数秒かかることがあり、見るのは非常に魅力的です。

ここに画像の説明を入力してください


4
うわー、感動しました。今、私はそれの実際のビデオを見たいです!=)
flawr
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.