Pentomino 6x10ソリューションノーマライザー


19

おそらく今おわかりのように、6x10グリッドのペントミノパズルには2339のソリューションがあります。12個のペントミノにはさまざまなラベル付けスキームがあり、そのうちの2つが下の画像に示されています。

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

画像クレジット:ウィキペディア

現在のタスクの目的上、正規化されたペントミノソリューションは、2番目のラベル付けスキーム(Conwayの)を使用するソリューションであると言います。

例:

O O O O O S S S Z Z
P P R R S S W W Z V
P P P R R W W Z Z V
U U X R T W Y V V V
U X X X T Y Y Y Y Q
U U X T T T Q Q Q Q

5つの正方形が一列に並んだ作品Oには、スキームに従って文字が表示されます。同じことがすべてのピースに当てはまります。

仕事:

ピースにランダムシェムのラベルが付けられている6x10ペントミノの解決策を考えて、すべてのピースがConwayのラベル付けスキームでラベル付けされるように正規化します。ピースを認識し、特定のピースの各正方形にピースのシンボルをマークする必要があります。

入力:

正規化するソリューション。たとえば、次のようなユーザーにとって便利な任意の形式です。

  • 複数行の文字列

  • 文字列のリスト

  • 文字のリストのリスト

等々

出力:

同じソリューション(すべてのピースの位置と方向が保持されます)が、各ピースはConwayのラベル付けスキームに従ってラベル付けされます。注:出力は、文字の6x10グリッドとして印刷する必要があります。先頭と末尾の改行とスペースは許可されます。上記の例のように、文字間にスペースを印刷することもできます(空行ではありません)。

テストケース:

1.入力:

6623338888
6222344478
66A234BB70
1AAA94B770
11A99BB700
1199555550

出力:

UURTTTQQQQ
URRRTVVVSQ
UUXRTVZZSY
PXXXWVZSSY
PPXWWZZSYY
PPWWOOOOOY

2.入力:

45ookkkk00
455ooogk00
4a55gggdd0
4aaa3gnnd.
4am333ndd.
mmmm3nn...

出力:

OWSSQQQQPP
OWWSSSRQPP
OTWWRRRUUP
OTTTXRZZUV
OTYXXXZUUV
YYYYXZZVVV

受賞基準:

各言語のバイト単位の最短ソリューションが勝ちです。ゴルフ言語に落胆しないでください。アルゴリズムと実装の説明を歓迎します。



@KevinCruijssenありがとうございます!(テトロモノに関連する質問を確認しませんでした)
ガレンイワノフ

回答:


12

APL(Dyalog Classic)54 53 50バイト

⍴⍴{'OXRYTPZQUWSV'[⌊5÷⍨⍋⍋,{×/+⌿↑|(⊢-+/÷≢)⍸⍵}¨⍵=⊂⍵]}

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

入力内の各ペントミノの不変量を計算します。各正方形からその重心までの(Δx、Δy)を測定し、abs(Δx)とabs(Δy)を取り、x成分を合計し、yを個別にコンポーネント、および2つの合計を乗算します。これにより、12の異なる結果が得られます。次に、すべての不変条件のソートされたコレクションで各ペントミノの不変条件のインデックスを見つけます。0を'O'1に'X'、2を'R'などに置き換えます。


素早い回答と説明をありがとう、私からの+1!ソリューションを6x10グリッドとして明示的に印刷することを意味しました。説明を変更しました。ソリューションを更新してください。ご不便をおかけして申し訳ありません。
ガレンイワノフ

@GalenIvanovしかし... それはグリッドです。私のテストは結果を出力する代わりに「OK」を出力します-多分それはわかりにくいでしょうか?
ngn

はい、テストに混乱しました。
ガレンイワノフ

3
今、彼らはそれを検証する前に結果を印刷します
-ngn

4

ゼリー、37 バイト

ŒĠZÆmạƊ€ḅı§AỤỤị“æṂ⁾+’Œ?¤+78Ọ,@FQṢƊyⱮY

文字列のリストを取得する完全なプログラム(印刷する必要がある-そうでなければ末尾Yを削除し、文字のリストを返す数字または文字のリストの一覧を取得するモナドがある)

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

どうやって?

これは、わずかに異なる方法ではありますがngnのAPLソリューションと同じペントミノの分類を使用して機能すると信じています(APLも知らないので、方法が分類を超えているかどうかはわかりません)。

(これ“æṂ⁾+’Œ?¤+78Ọは1バイトの保存のみ“XRPTZWUYSVQO”です!)

ŒĠZÆmạƊ€ḅı§AỤỤị“æṂ⁾+’Œ?¤+78Ọ,@FQṢƊyⱮY - Main Link: list of lists of characters L
ŒĠ                                    - group multidimensional indices by value
      Ɗ€                              - last three links as a monad for €ach i.e. f(x):
  Z                                   -   transpose x
   Æm                                 -   mean (vectorises) (i.e. the average of the coordinates)
     ạ                                -   absolute difference with x (vectorises) (i.e. [dx, dy])
         ı                            - square root of -1 (i)
        ḅ                             - convert from base (vectorises) (i.e a list of (i*dx+dy)s)
          §                           - sum each
           A                          - absolute value (i.e. norm of the complex number)
            Ụ                         - grade up (sort indices by value)
             Ụ                        - grade up (...getting the order from the result of A back,
                                      -              but now with one through to 12)
                       ¤              - nilad followed by links as a nilad:
               “æṂ⁾+’                 -   base 250 literal = 370660794
                     Œ?               -   permutation@lex-index = [10,4,2,6,12,9,7,11,5,8,3,1]
              ị                       - index into
                        +78           - add seventy-eight
                           Ọ          - cast to characters (character(1+78)='O', etc...)
                                 Ɗ    - last three links as a monad (i.e. f(L)):
                              F       -   flatten
                               Q      -   de-duplicate
                                Ṣ     -    sort
                            ,@        - pair (with sw@pped @rguments) (giving a list of 2 lists)
                                   Ɱ  - Ɱap across L with:
                                  y   -   translate i.e. swap the letters as per the the pair)
                                    Y - join with new lines
                                      - implicit print

2

Wolfram言語(Mathematica)、103バイト

""<>Riffle[(t=#)/.Thread[SortBy[Union@@t,Tr@Kurtosis@Position[t,#]&]->Characters@"UPSWZVRTQXYO"],"\n"]&

入力を文字のリストのリストとして受け取ります。

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

ここでの主なアイデアは、入力内の各文字について、それが発生する座標を見つけ、尖度を取り、その座標を合計することです。これにより、各ピースに不変量が与えられます。

(尖度は統計上、ほとんど無関係な演算子です。キーは、変換中は不変であり、反射と回転はせいぜい座標の順序を切り替えることです。座標を合計するので、不変式は変化しません。)

とにかく、奇妙な不変条件を除けば、この解決策は他のものに似ています:各不変条件で文字とピースをソートし、次に、各文字"UPSWZVRTQXYO"を尖度の合計でソートされたピースの対応する文字で置き換えます。

最後に、""<>Riffle[...,"\n"]グリッドとして印刷するコードがあります。


聞いたこともない操作を知り、それを有効に活用したことに対して+1
Black Owl Kai

解決策への私の最初の試みSort@Varianceはの代わりにありTr@Kurtosis、おそらくより多くの人が分散について聞いたでしょう。しかしTr@Variance、いくつかのペントミノ(PやXなど)のx分散とy分散の合計が同じであるため、機能しません。それで、私はMathematicaのドキュメンテーションを調べて、もっと面白いものを探しました。
ミシャラヴロフ

2

Python 2、191バイト

def y(o):print"".join(['XPRTWZUYSVQO\n'[[w for v,w in sorted([sum(abs(u-sum(t)/5)for t in[[complex(r%11,r/11)for r,q in enumerate(o)if q==p]]for u in t),p]for p in o)].index(x)/5]for x in o])

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

末尾の改行を含む複数行の文字列を受け取り、6つのネストされたリストの内包表記を行います。

非ゴルフバージョン

def pentomino_normalizer(input_string):
    # input_string is a multi-line string with a trailing newline

    results = []  # For saving the results of the for loop
    for current_char in input_string:
        # current_char = p in the golfed version

        # The python data type complex stores a real and a imaginary value and
        # is used for storing the x and y coordinates.
        # In the end, the positions list contains a complex number for every
        # occurence of current_char in the string
        # positions_list = t in the golfed version
        positions_list = [complex(i % 11, i / 11) for i, c
                          in enumerate(input_string) if c == current_char]
        # average_pos is the midpoint of all occurences of current_char, 
        # to get rid of translations
        average_pos = sum(positions_list)/5
        # Calculates a value for each tile that is invariant under 
        # translations and rotations,
        # simply the sum of all the distances between the midpoint
        # and the positions
        invariant = sum(abs(pos - average_pos) for pos in positions_list)

        # Saves the invariant value to a list
        results.append(invariant, current_char)

    # This new list contains the characters occuring in the string, sorted
    # by the invariant value. Because this was done with each char in the 
    # input string, this lists contains every value five times and also 
    # contains six newlines
    # at the end of the list
    sorted_results = [w for v, w in sorted(results)]

    # This code snippet maps each char from the input string to its according
    # output and prints to stdout
    chars = ['XPRTWZUYSVQO\n'[sorted_results.index(c)/5] for c in input_string]
    print "".join(chars)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.