この正方形は対称ですか?


22

ちょうど4からなる4×4テキスト・グリッドにかかるプログラムや関数を書くAの、4 B、の4 Cの、及び4 Dの、例えば:

ACDC
BBCA
BADD
ABCD

ABCD配置は任意ですが、常に4つあります。入力が有効であると想定できます。必要に応じて、末尾に改行があるか、読み取り順序で1行になっていると仮定することもできますACDCBBCABADDABCD。また、必要に応じて、文字ABCD0123またはで置き換えることも1234できます(ただし、それだけです)。

テキストグリッドに反射対称または回転対称の形式がある場合、真理値を出力します。具体的には:

  • 対称の中央の水平線がある場合。例えば

    BACD
    BACD 
    BACD \___ bottom mirrors top
    BACD /
    
  • 対称の中心垂直線がある場合。例えば

    BCCB
    DAAD
    CAAC
    BDDB
      \/___ right mirrors left
    
  • 対称の対角線がある場合(どちらの方向にも)。例えば

         ___ diagonally mirrored
        /
    ABDC
    BACD
    DCAB
    CDBA
        \___ diagonally mirrored
    
  • 90°回転対称がある場合。例えば

    BDAB
    ACCD    same if rotated 90 degrees (or 180 or 270)
    DCCA
    BADB
    
  • 180°回転対称がある場合。例えば

    DBCA
    BDCA    same if rotated 180 degrees
    ACDB
    ACBD
    

(ここでは並進対称性が作用しないことに注意してください。)

グリッドに上記の対称性がない場合、偽の値を出力します。たとえば、最初の例のグリッド。

バイト単位の最短コードが優先されます。


入力として4つの文字列のリストを使用できますか?
マーティンエンダー

@MartinEnderはい、大丈夫です。
カルビンの趣味

4
私はそれを読んで、「いいえ」と思ったlol
Shaun Wild

正方形をタイル状に並べようと思っていたら、平行移動の対称性も考慮することができました。
ニール

1
@Adámいいえ。これ以上入力フォーマットはありません。私は本当にマーティンを許可すべきではないと感じています。
カルビンの趣味

回答:


16

CJam、16バイト

{{z_W%_}4*;])e=}

スタックの最上部にある4つの文字列のリストとして入力を予期し、0非対称入力に対して(偽)を、対称入力に対して正の整数(真)を残す名前のないブロック。

ここでテストしてください。 または、完全なテストスイートを実行します。

説明

正方形の対称性は、次数8の二面体グループの要素です(これは、正方形の4回転と、正方形の反射バージョンの同じ4回転です)。単一の順列を繰り返し適用してこのグループを生成することはできません。しかし、2つの反射は常にある程度の回転を与えます。したがって、2回の反射を4回交互に繰り返すことで、グループ全体を生成できます。(2つの反射が0または180ではなく、90度または270度の回転を与えることを確認する必要があります。)

チャレンジは、入力正方形が他の7つの対称性のいずれかに等しいかどうかを尋ねます。したがって、この答えはそれらのすべてを生成し、入力が他のものの中にあるかどうかをチェックします。

{      e# Run this block 4 times.
  z_   e# Transpose the grid and duplicate it. (This is one type of reflection.)
  W%_  e# Reverse the lines and duplicate it. (This is another type of
       e# reflection. Together they rotate the grid by 90 degrees.)
}4*    e# The last element will be the original grid again.
;      e# Discard one copy of that original grid.
]      e# Wrap all symmetries in a list.
)      e# Pull off the original grid.
e=     e# Count how many times it appears among the other symmetries.

すべての対称性を繰り返し適用しzW%生成する方法を確認するには、次の「図」を参照してください。

     0123
     4567
     89ab
     cdef

     original

 z   048c       W%       37bf
-->  159d  ----------->  26ae
     26ae                159d
     37bf                048c

     diag. refl.         rot. 90 degrees ccw

 z   3210       W%       fedc
-->  7654  ----------->  ba98
     ba98                7654
     fedc                3210

     vert. refl.        rot. 180 degrees

 z   fb73       W%       c840
-->  ea62  ----------->  d951
     d951                ea62
     c840                fb73

     antidiag. refl.     rot. 270 degrees ccw

 z   cdef       W%       0123
-->  89ab  ----------->  4567
     4567                89ab
     0123                cdef

     horiz. refl.        original

うわー、これを説明できますか?すべての回転/反転用のビルトインがありますか?
アダム

@Adám完全な説明を少し追加しますが、行をz転置してW%逆にします。そのため、それらを繰り返し適用することですべての対称性を生成しています。
マーティンエンダー

4
もちろん、最初の値について特別なものはありませんが、悲しいことに、8つの異なる値を取得するかどうかをカウントするより純粋なアプローチでは、1文字余分にコストがかかります。
ピーターテイラー

8

Pyth、11バイト

<7.u?%Y2CN_

テストスイート

これはMartinの転置および逆手法を使用しますが、ひねりがあります。他のソリューションは8つの対称性をすべて明示的に生成し、元の出現回数をカウントしましたが、このプログラムはPythの.u関数を使用します。

.uこの関数は、「繰り返しが発見されるまで適用」です。この場合、繰り返しが発生するまで交互に転置および反転し、結果をリストに蓄積します。次に、最後の7つの値を削除するので、対称性がない場合にのみ値が残り、8つの反射と繰り返しがすべて生成された後に最初の繰り返しが発生します。

説明:

<7.u?%Y2CN_
<7.u?%Y2CN_NQ    Implicit variables
                 Q = eval(input())
  .u        Q    Starting with Q, apply the following until a repeat occurs, 
                 then accumulate all values into a list.
    ?%Y2         If the iteration number is odd
        CN       Transpose
          _N     Else reverse
<7               Remove the last 7 results


4

Perl、61 60バイト

+3を含む -p0a

STDINに入力正方形を与え、対称性がない場合は0を出力し、そうでない場合は正の数を出力します

./symmetry.pl
DBCA
BDCA
ACDB
ACBD
^D

symmetry.pl

#!/usr/bin/perl -p0a
s,.,chop$F[$i++/($j-4?1:4)%4],eg;$\+=$$_++;++$j<8&&redo}{


3

Brachylog38 36バイト

@eL:1fbeL
(L;?:raL)(.;L$\.;L$/.;Lr.)

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

これには、入力として文字列のリストが必要です。これにより、true.またはが出力されますfalse.

説明

  • 主な述語:

    @eL    Split each line into a list of chars ; call that list of lists L
    :1f    Find all symmetries
    b      Remove the first one (the identity)
    eL     L is an element of that list of symmetries
    
  • 述語1:出力は、入力の8つの対称性の1つです。

    (
        L             L = Input
    ;             Or
        ?:raL         L = reverse all lines of the input
    )
    (
        .             Output = L
    ;             Or
        L$\.          Output = transpose of L    
    ;             Or
        L$/.          Output = antitranspose of L
    ;             Or
        Lr.           Output = reverse of L
    )
    

3

TSQL、229バイト

TSQLには回転用のビルトインがないため、これはコードに含まれています。

ゴルフ:

DECLARE @1 char(16)=
'BCCBDAADCAACBDDB'

,@i INT=0,@ varchar(16)=''WHILE @i<16SELECT @+=substring(@1,@i*4%16+@i/4+1,1),@i+=1SELECT sign(count(*))FROM(SELECT LEFT(x,8)a,RIGHT(x,4)b,substring(x,9,4)c FROM(values(@1),(@))x(x))x WHERE c+b=reverse(a)or a=reverse(b+c)or a=b+c

ゴルフをしていない:

DECLARE @1 char(16)=
'BCCBDAADCAACBDDB'

,@i INT=0,@ varchar(16)=''
WHILE @i<16
  SELECT @+=substring(@1,@i*4%16+@i/4+1,1),@i+=1

SELECT sign(count(*))
FROM
  (SELECT LEFT(x,8)a,RIGHT(x,4)b,substring(x,9,4)c
   FROM(values(@1),(@))x(x))x
WHERE c+b=reverse(a)or a=reverse(b+c)or a=b+c

フィドル


2

Python 2、154 146バイト

numpy配列を使用して、必要な変換のいずれかが元の変換と同等であるかどうかを確認します。入力は4つの文字列のリストとして取得されます。

from numpy import*
A=array(map(list,input()))
R=rot90
T=transpose(A)
print any([all(A==Z)for Z in(A[:,::-1],A[::-1],R(A),R(A,2),R(A,3),T,R(T,2))])

オンラインで試す

入力を単一の文字列として取得すると、1文字長くなりA=array(list(input())).reshape(4,4)ます。A[:,::-1]はと同じfliplr(A)です。A[::-1]はと同じflipud(A)です。


map(list,input())代わりに使用する可能性があります[list(r)for r in input()]
チョイス

@Cyoceありがとう。Idkがどうしてそれを見逃したか。
mbomb007

anyジェネレータ式を使用するため、角括弧の外側のペアを削除することで数バイトを節約できます。
-TheBikingViking

@TheBikingViking私はすでにそれを試していました。ジェネレーターを渡すと、ジェネレーターが返され、printステートメントが機能しなくなります。オンラインコードをフォークして、そのように実行してみてください。
mbomb007

ああ、わかった。それが壊れることに気づかなかったprint
TheBikingViking

2

Python 3、99バイト

def f(x):
 t=x;c=[]
 for i in range(7):*t,=[map(''.join,zip(*t)),t[::-1]][i%2];c+=t,
 return x in c

引数を介して、文字列のリストの入力を受け取り、関連する、TrueまたはFalseを返す関数。

これは@MartinEnderのanswerと同じアプローチを使用します

使い方

def f(x)                Function with input list of strings x
 t=x;c=[]               Initilaise temporary square t and combination list c
 for i in range(7):...  For i in range [0,6]:
 [...][i%2]              If i is even:
 zip(*t)                  transpose(t)
 *t,=map(''.join,...)     t = t with each line concatenated (such that t is in the same
                          format as x)
                         Else:
 *t,=t[::-1]              t = reverse(t)
 c+=t,                   Append t to c
 return x in c           Return True if x is in c else return False

Ideoneでお試しください


2

JavaScript(ES6)、131バイト

s=>[...`0101010`].map(c=>+c?``+b.reverse():`${b=b.map((s,i)=>s.replace(/./g,(_,j)=>b[j][i]))}`,b=a=s.match(/..../g)).includes(``+a)

4つの文字列の配列を直接渡す場合、17バイトを削除できます。ビットトゥイッドリング("0123301223011230"形式での入力)を試みましたが、199バイトかかりました。

s=>[...'0101010'].map(c=>r=+c?r<<24&255<<24|r<<8&255<<16|r>>8&255<<8|r>>>24:r&0xc0300c03|r<<6&806093568|r<<12&3075<<16|r<<18&3<<24|r>>6&0xc0300c|r>>12&49200|r>>18&192,r=n=parseInt(s,4)|0).includes(n)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.