ブロックの再配置


14

したがって、あなたの仕事は3x3ブロックを取得することです。ここで、-の意味は空白スペースであり、*の意味は塗りつぶされたスペースです、例えば:

-**
-*-
*-*

*のように、がXを形成するようにブロックを再配置します。

*-*
-*-
*-*

入力: 上記のような3x3の正方形、3行、配列、または必要に応じて。

出力: Xに再配置するための最短の移動量。各移動は、互いに水平であるか、互いに垂直であるか、または互いに斜めである、接触している2つのキャラクターを反転させます。不可能な場合は、不可能な出力を返します(例:999または)-42425最小のそのような数です。

テストケース:

1)出力:1

-**
-*-
*-*

2)出力:-1

-*-
-*-
*-*

3)出力:3

---
-**
***

4)出力:0

*-*
-*-
*-*

空白文字と非空白文字を置き換えることができますが、投稿にどちらが含まれるかを必ず確認してください

コードゴルフ

これは、最短のコードが勝つコードゴルフです。


1
2つのキャラクターを反転するということは、スペースからスペースへ*、またはその逆へのフリップを意味しましたか、それとも交換しますか?
user202729

5つ以上ある場合はどうなり*ますか?さらにテストケースを追加できますか?
スチューウィーグリフィン

たとえば、最後の2文字を反転させた場合、@ user202729はabcになります。
ノアクリスティーノ

@StewieGriffinは、「-1を返す*ことが不可能な場合」5 以上または5 未満では不可能になります。
ノアクリスティーノ

6
以外のものを使用でき-1ますか?たとえば5(そうでなければ不可能)、またはエラーを投げますか?
ジョナサンアラン

回答:


12

Pythonの3104の 78バイト

lambda n:-(sum(n)!=5)or sum(n[1::2])+n[4]*(max(n,n[6:],n[::3],n[2::3])>=[1]*3)

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

編集:@Jonathan Allanと@xnorの両方の提案を適用して、バイト数を大幅に削減しました。

入力は、ゼロと1を含む長さ9の文字列リストです。1は*sです。

いくつかの所見を次に示します。

  • 星を正しいセル上に移動する必要はありません。配置を間違えた星には、一度にブロックできない5つの周囲のセルがあります(そうでない場合、答えはすでに-1です)。
  • 置き忘れられた各星のコストは1または2であり、正しく配置された3つの星に囲まれている場合にのみ2です。
  • 置き忘れられた各スターのコストは、互いに独立しています。

したがって、最初に文字列に5つの文字列があるかどうかをテストし、次にこれらをカウントします。

  • 置き忘れた星の数(=インデックスが奇数の場合)
  • コスト2の見当違いの星の数(=細胞では0124034624584678全てのものです)
    • n[4]1であることを考慮して、各範囲の抽出をテストします'111'
    • そのような星は多くても1つなので、のmax代わりに安全に使用できsumます。

文字列の代わりにリストを受け入れることで17バイトを節約します(置き換えます count sをsumsおよび'111'[1]*3TIO(私はn[i::j]>=[1]*3ループで賢くしようとしましたが、もっと短くは見つかりませんでした)。
ジョナサンアラン

コスト2のスターは1つしか存在できないため、できるように見えますmax(n,n[6:],n[::3],n[2::3])>='1'*3
-xnor

コスト2の星を持つ他のアレンジメントがあります。[0,1,1,1,1,0,1,0,0]は2ではなく3を返すべきだと思います。
RootTwo18年

また、[1,1,1,1,0,0,1,0,0]は2ではなく3でなければなりません
。– RootTwo

また、[1,1,1,1,0,0,1,0,0]は2ではなく3でなければなりません
。– RootTwo

4

ゼリー、26バイト

5ḶḤd3ạŒ!Ṁ€€ḅ1Ṃ
T’d3Ç-L=5Ɗ?

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


入力としてフラットリストを取得します。

Jellyが「多次元の真実のインデックス」を持っていないのは残念です... T€ṭ€"JẎでも動作しますが、もう1バイト必要です。


アルゴリズム:5つの現在のブロック位置と5つのターゲット(宛先)があり、アルゴリズムは5つそれぞれを試行します![ソース、デスティネーション]チェビシェフ距離の最小合計をマッチングして出力します。


あなたはフラットリスト(「あなたが望むもの」)を取るかもしれません...たぶん、あなたは0ベースのインデックスを取り、24を持つことができますか?
ジョナサンアラン

4

ハスケル176 132 126 104バイト

w=0:1:w
m a|sum a/=5=5|1>0=sum$[a!!4|3<-sum.map(a!!)<$>[[0,1,2],[0,3,6],[2,5,8],[6,7,8]]]++zipWith(*)a w

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


1を非空白文字として持つ整数のリストを取ります。ゼロ以外の偶数インデックスの正方形の数を合計し、二重移動パターンのいずれかが見つかった場合は1を追加します(中央の正方形と端の列/行が完全に塗りつぶされます)。最後の部分は少し無駄だと思いますが、おそらくこのブルートフォース方式よりもはるかに改善されるでしょう。不可能な入力に対して5(不可能な出力)を返します。


2
いくつかのヒント:lengthテストはに短縮できますsum[1|1<-a]。関数s(1-e,n+sum[1|b>e])別のバイトを保存するためにインライン化できます。あなたは使用することができotherwise、ガードをしてmのペア保存するように()。最後&&に、ガードの最上位のをに置き換えることができます,。...
nimi

2
sumリスト内包表記を使用してブール値をintにキャストすることにより、別のバイトを保存できます。オンラインでお試しください!
ポストロックガーフハンター

2
実際には、パターンガードがなくなると、全体をに移動できるため、かなりの数バイトを節約できますmオンラインでお試しください!
ポストロックガーフハンター

2
また、のすべての非1の要素からaでなければなりませんが、0あなたが使用できないsum aのではなくsum[1|1<-a]オンラインでお試しください!
ポストロックガーフハンター

1
私はすべてを持つ以上1つの側面があることはできませんので、実現1の中心がある場合を除き、S 0、あなたが行うことができます3<-の代わりにelem 3$。また、のsum.map(a!!)代わりに使用することもできますsum<$>map(a!!)
ポストロックガーフハンター


3

JavaScript(ES6)、123バイト

入力を9ビット整数として受け取ります。ルールを単純に適用することでパズルを解きます。これは最短のアプローチではないことが証明されています。

f=(n,k=b=-1)=>n^341?k>2?b:[3,6,9,10,17,18,20,34,36].map(m=>[1,8,8].map(M=>(x=n&(m*=M))&-x^x||f(n^m,k+1)))|b:!~b|k<b?b=k+1:b

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

コメント済み

f = (                           // f = recursive function taking:
  n,                            //   n = input
  k =                           //   k = number of moves, initialized to -1
  b = -1                        //   b = best result so far, initialized to -1
) =>                            //
  n ^ 341 ?                     // if n does not match the target pattern:
    k > 2 ?                     //   if we've already done more than 3 moves:
      b                         //     we're not going to find a solution -> abort
    :                           //   else:
      [3,6,9,10,17,18,20,34,36] //     for each swap bitmask m
      .map(m =>                 //     and
      [1,8,8]                   //     for each multiplier M:
      .map(M =>                 //       apply the multiplier to m and
        (x = n & (m *= M))      //       apply the final bitmask to n -> this gives x
        & -x                    //       isolate the least significant bit of x
        ^ x ||                  //       if it's the only bit set,
        f(n ^ m, k + 1)         //       then swap the bits and make a recursive call
      )) | b                    //     end of both map() loops; return b
  :                             // else:
    !~b | k < b ? b = k + 1 : b //   this is a solution in k+1 moves: update b

NB:このコードは、mに 64を掛けると、ボードの最上部を超える違法な動きを実行します。ただし、それらは、最良の法的解決策よりも短い解決策につながる可能性がないため、単に無視されます。

以下は、9つのベーススワップビットマスクとターゲットパターンです。左上隅が最上位ビットです。

000  000  001  001  010  010  010  100  100     101
011  110  001  010  001  010  100  010  100     010 (341)
(3)  (6)  (9)  (10) (17) (18) (20) (34) (36)    101

テスト用に16進ダンプをリンクできますか?また、私は9ビットの整数はJSで可能であった知らなかった
スタン・ストラム

@StanStrumより簡単なエンコードでより短いバージョンに更新されました。(そして、はい:JSは最大32ビットのビット演算をサポートします。)
アーナルド

2

ゼリー、26 バイト

“ċȤ‘ḤB;U$=a¥;Ḋm2ƊẠ€SɓSn5Nȯ

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

モナドリンク。

どうやって?

バブラーのPythonの答えに触発されました。ゼリーに合わせてゴルフ...

“ċȤ‘ḤB;U$=a¥;Ḋm2ƊẠ€SɓSn5Nȯ - Link: length 9 list of ones & zeros, X
“ċȤ‘                       - list of code-page indices     = [232,154]
    Ḥ                      - double                        = [464,308]
     B                     - to binary     = [[1,1,1,0,1,0,0,0,0],[1,0,0,1,1,0,1,0,0]]
        $                  - last two links as a monad:
       U                   -   upend       = [[0,0,0,0,1,0,1,1,1],[0,0,1,0,1,1,0,0,1]]
      ;                    -   concatenate = [[1,1,1,0,1,0,0,0,0],[1,0,0,1,1,0,1,0,0],[0,0,0,0,1,0,1,1,1],[0,0,1,0,1,1,0,0,1]]
           ¥               - last two links as a dyad:
          a                -   logical AND (vectorises)
         =                 -   equal? (vectorises)
                Ɗ          - last three links as a monad:
             Ḋ             -   dequeue X (remove leftmost element)
               2           -   literal two
              m            -   modulo slice (keeps the "edge-elements") 
            ;              - concatenate
                 Ạ€        - all? for €ach (edge-elements: no-op
                           -                else: 1 for any cost-2 element 0 otherwise)
                   S       - sum
                    ɓ      - new dyadic chain ^that on the right; X on the left
                     S     - sum X
                       5   - literal five
                      n    - not equal?
                        N  - negate (-1 if not exactly 5 1s, 0 otherwise)
                         ȯ - logical OR with right

2

JavaScript、85バイト

s=>/^0*(10*){5}$/.test(s)*s.match(/(?=1.(..)*$|^1(..)?11.1|1.11(..)?1$)|$/g).length-1

これは、Bubblerの答えの正規表現です。

0/1の文字列として入力します。


2

スタックス23 22 バイト

Ç╙╤Ü┤└åVτ┐├Y-²▼░█∩¡3ëâ

実行してデバッグする

このプログラムは、[0, 1]入力として配列を受け取り、整数の動きを返すか、解決できない場合は空の文字列を返します。

グリッドのこのインデックスを検討してください

0 1 2
3 4 5
6 7 8
  • 1入力に正確に5 秒がない場合、解は存在しないため、出力は生成されません。
  • 各辺の中心は不正確な位置です。これらは、インデックス1、3、5、および7です。それぞれの距離を合計します1これらの位置すると、最終結果が生成されます。
  • それぞれの1位置が正しくない場合、その距離は1または2 1です。他のに囲まれている場合は2になります。たとえば1、インデックス[0、1、2、4]にs がある場合、不正な距離1は2です。
  • これを念頭に置いて、インデックス1によって結果に寄与する距離を取得するためのこの擬似コードを検討してください。

    1. インデックス[1、0、2、4]から4ビットを読み取ります。これにより、誤った位置が最も重要な位置に配置されます。
    2. これらのビットをb0〜15の数値に変換します。
    3. 場合0 <= b <= 7ときの距離は0である8 <= b <= 14距離が1であるb == 15距離がこれにより整数除算を使用して2を算出することができるされていますb * 2 / 15

そのため、このプロセスを4回繰り返し、その間にグリッドを回転させることで、合計距離を計算できます。

1#5=4*  if the number of 1s is 5, then 4, else 0
D       repeat the rest of the program that many times
  x     push the value in the x register, which is initially the input
  3/    split into 3 rows
  rM    rotate 90 degrees
  $X    flatten back into single array, and save the "rotated" array in the X register
  A|2E  get the digits of 2^10 i.e. [1,0,2,4]
  @     read the bits from the current rotation at indices [1,0,2,4]
  :b    convert bits to integer
  H15/  double, then divide by 2
  +     add to running total

これを実行する


だけでなく、あらゆる不可能な値が受け入れられ、編集をチェック-1それはあなたを助けている場合
ノアCristino

はい。これで2バイト節約できました。
再帰的

1

Excel、86 81バイト

=SUM(B1,A2,B3,C2)+B2*(AND(A1:A3)+AND(A1:C1)+AND(C1:C3)+AND(A3:C3))/(SUM(A1:C3)=5)

古い: 「不可能」出力が-1

=IF(SUM(A1:C3)=5,SUM(B1,A2,B3,C2)+B2*(AND(A1:A3)+AND(A1:C1)+AND(C1:C3)+AND(A3:C3)),-1)

用途1埋め用および0範囲内の空、入力のためにA1:C3「不可能」以外の値を返すことができれば、さらにゴルフをすることができます-1 を返します#DIV/0!不可能なグリッドでエラーを

BubblerのPython answerと同じロジックで動作します


編集をチェックし、どの不可能値は、だけでなく、-1受け入れられている
ノアCristino
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.