Blockumlagerung

14

Ihre Aufgabe ist es also, einen 3x3-Block zu erstellen, in dem -die mittleren Leerzeichen und *die mittleren ausgefüllten Leerzeichen enthalten sind, zum Beispiel:

-**
-*-
*-*

und ordne den Block so an, dass die *ein X bilden, wie folgt:

*-*
-*-
*-*

Eingabe: 3x3 Quadrate wie oben, es können 3 Zeilen sein, ein Array, oder wie Sie wollen.

Ausgabe: Die kürzeste Anzahl von Zügen, die in ein X umgeordnet werden müssen. Bei jedem Zug werden 2 Zeichen umgedreht, die sich berühren und horizontal, vertikal oder diagonal voneinander sind. Wenn dies nicht möglich ist, geben Sie eine unmögliche Ausgabe zurück, z. B. 999oder -4242. 5ist die kleinste solche Zahl.

Testfälle:

1) Ausgabe: 1

-**
-*-
*-*

2) Ausgabe: -1

-*-
-*-
*-*

3) Ausgabe: 3

---
-**
***

4) Ausgabe: 0

*-*
-*-
*-*

Sie können die leeren und nicht leeren Zeichen ersetzen, aber achten Sie darauf, welche in Ihrem Beitrag enthalten ist

Code Golf

Denken Sie daran, dies ist Code Golf, der kürzeste Code gewinnt!

Noah Cristino
quelle
1
Meinten Sie mit dem Umblättern von 2 Zeichen das Umblättern von Leerzeichen nach *und umgekehrt oder das Austauschen von Zeichen ?
User202729
Was ist, wenn es mehr als fünf gibt *? Können Sie weitere Testfälle hinzufügen?
Stewie Griffin
@ user202729 zum Beispiel abc wäre acb, wenn Sie die letzten 2 Zeichen spiegeln würden.
Noah Cristino
@StewieGriffin "Wenn es nicht möglich ist, einen -1" -Wert von mehr als 5 *oder weniger als 5 zurückzugeben, wird dies unmöglich.
Noah Cristino
6
Dürfen wir etwas anderes als verwenden -1? Zum Beispiel 5(sonst unmöglich) oder einen Fehler werfen?
Jonathan Allan

Antworten:

12

Python 3 , 104 78 Bytes

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

Probieren Sie es online!

Bearbeiten: Wendet sowohl @ Jonathan Allans als auch @ xnors Vorschläge an, um die Byteanzahl drastisch zu reduzieren.

Die Eingabe ist eine Stringliste der Länge 9 mit Nullen und Einsen, wobei Einsen das *s sind.

Hier sind einige Beobachtungen:

  • Wir müssen die Sterne nicht immer auf die richtigen Zellen bewegen. Jeder falsch platzierte Stern hat 5 umgebende Zellen, die nicht sofort geblockt werden können (andernfalls ist die Antwort bereits -1).
  • Die Kosten für jeden fehlplatzierten Stern betragen entweder 1 oder 2 und nur dann 2, wenn er von drei korrekt platzierten Sternen umgeben ist.
  • Die Kosten für jeden verlegten Stern sind unabhängig voneinander.

Daher testen wir zuerst, ob der String fünf Einsen enthält, und zählen dann die folgenden Dinge:

  • Die Anzahl der fehlplatzierten Sterne (= Einsen bei ungeraden Indizes)
  • Die Anzahl der fehl am Platze Sternen von Kosten 2 (= Zellen an 0124, 0346, 2458, 4678alle diejenigen zu sein)
    • Ziehen Sie es heraus n[4], eins zu sein, und testen Sie dann jedes Entfernungs-Extraktions-Wesen '111'.
    • Da ein solcher Stern höchstens ein, so können wir sicher verwenden maxstatt sum.
Bubbler
quelle
Sparen Sie 17 Bytes, indem Sie eine Liste anstelle einer Zeichenfolge akzeptieren (indem Sie counts durch sums und '111'durch ersetzen [1]*3). TIO (Ich habe versucht, mit einer n[i::j]>=[1]*3Schleife clever umzugehen, habe aber keine kürzere gefunden).
Jonathan Allan
Da es nur einen Preis-2-Stern geben kann, sieht es so aus, als ob Sie das können max(n,n[6:],n[::3],n[2::3])>='1'*3.
Xnor
Es gibt andere Arrangements, die einen 2-Sterne-Preis haben. Ich denke, [0,1,1,1,1,0,1,0,0] sollte 3 statt 2 zurückgeben.
RootTwo
Außerdem sollte [1,1,1,1,0,0,1,0,0] 3 statt 2 sein.
RootTwo
Außerdem sollte [1,1,1,1,0,0,1,0,0] 3 statt 2 sein.
RootTwo
4

Gelee , 26 Bytes

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

Probieren Sie es online!


Nehmen Sie eine flache Liste als Eingabe.

Schade, dass Jelly keine "multidimensionalen Wahrheitsindizes" hat ... T€ṭ€"JẎfunktioniert auch, benötigt aber 1 Byte mehr.


Algorithmus: Es gibt 5 aktuelle Blockpositionen und 5 Ziele (Destinationen), der Algorithmus versucht jedes der 5! Matching und Ausgabe der minimalen Summe von [Quelle, Ziel] Chebyshev Entfernung.

user202729
quelle
Sie können eine flache Liste nehmen ("wie Sie wollen") ... vielleicht können Sie sogar 0-basierte Indizes nehmen und 24 haben?
Jonathan Allan
4

Haskell , 176 132 126 104 Bytes

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

Probieren Sie es online!


Nimmt eine Liste von Ganzzahlen mit 1 als nicht leeres Zeichen. Summiert die Anzahl der Quadrate mit geradem Index ungleich Null und addiert dann 1, wenn eines der Doppelbewegungsmuster gefunden wird (mittleres Quadrat und Randspalte / -zeile vollständig ausgefüllt). Der letzte Teil ist meiner Meinung nach etwas verschwenderisch und könnte gegenüber dieser Brute-Force-Methode möglicherweise erheblich verbessert werden. Gibt 5 (eine unmögliche Ausgabe) für eine unmögliche Eingabe zurück.

Aoemica
quelle
2
Einige Tipps: Der lengthTest kann auf verkürzt werden sum[1|1<-a]. Funktion sauf: (1-e,n+sum[1|b>e])welche Sie inline können, um ein weiteres Byte zu speichern. Sie können die Verwendung otherwiseWache in mzu speichern Paar (). Schließlich kann &&auf oberster Ebene in einer Wache durch ersetzt werden ,. ...
nimi
2
Sie können ein weiteres Byte speichern, indem Sie ein sumin einer Liste angegebenes Verständnis verwenden, um einen Booleschen Wert in int umzuwandeln. Probieren Sie es online!
Post Rock Garf Hunter
2
Tatsächlich können Sie einige Bytes einsparen, denn sobald die Pattern-Guards verschwunden sind, können Sie das Ganze einfach nach oben verschieben m. Probieren Sie es online!
Post Rock Garf Hunter
2
Auch da nicht jedes Nicht-1-Element von sein amuss, 0können Sie sum astattdessen nicht verwenden sum[1|1<-a]? Probieren Sie es online!
Post Rock Garf Hunter
1
Ich habe gerade gemerkt, dass es nicht mehr als eine Seite mit allen 1s geben kann, es sei denn, die Mitte ist 0, können Sie 3<-stattdessen tun elem 3$. Auch können Sie sum.map(a!!)anstelle von verwenden sum<$>map(a!!).
Post Rock Garf Hunter
3

Python 2 , 194 192 Bytes

from itertools import*
f=lambda l,k=0:-(sum(l)!=5)or[1,0]*4!=l[:-1]and k<4and-~min(f(l[:a]+[l[b]]+l[a+1:b]+[l[a]]+l[b+1:],k+1)for a,b in combinations(range(9),2)if max(b/3-a/3,abs(a%3-b%3))<2)

Probieren Sie es online!

ovs
quelle
1
Funktioniert nicht mit [0,1,0,1,0,1,1,1,0](erwartet: 4, tatsächlich: 13).
Bubbler
@Bubbler reparierte es
ovs
3

JavaScript (ES6), 123 Byte

Übernimmt die Eingabe als 9-Bit-Ganzzahl. Löst das Rätsel durch naive Anwendung der Regeln, was sich als nicht der kürzeste Ansatz erwiesen hat.

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

Probieren Sie es online!

Kommentiert

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 : Dieser Code führt einige illegale Bewegungen über den oberen Rand des Spielfelds hinaus aus, wenn m mit 64 multipliziert wird. Sie werden jedoch einfach ignoriert, da sie möglicherweise nicht zu einer kürzeren Lösung führen können als die beste legale Lösung.

Unten sehen Sie die 9 Base-Swap-Bitmasken und das Zielmuster. Die obere linke Ecke ist das höchstwertige Bit.

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
Arnauld
quelle
Können Sie einen Hexdump zum Testen verknüpfen? Außerdem wusste ich nicht, dass in JS
Stan Strum am
@StanStrum Auf eine kürzere Version mit einer einfacheren Codierung aktualisiert. (Und ja: JS unterstützt bitweise Operationen für bis zu 32 Bits.)
Arnauld,
2

Gelee , 26 Bytes

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

Probieren Sie es online!

Eine monadische Verbindung.

Wie?

Inspiriert von Bubblers Python-Antwort ; Golf nach Jelly ...

“ċȤ‘Ḥ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
Jonathan Allan
quelle
2

JavaScript, 85 Bytes

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

Dies ist eine Regex-Portierung von Bubblers Antwort .

Eingabe als String von 0/1.

tsh
quelle
2

Stax , 23 22 Bytes

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

Führen Sie es aus und debuggen Sie es

Dieses Programm benötigt ein Array von [0, 1] als Eingabe und gibt eine ganze Zahl von Zügen oder eine leere Zeichenfolge zurück, wenn keine Lösung möglich ist.

Betrachten Sie diese Indizes für das Raster

0 1 2
3 4 5
6 7 8
  • Wenn es nicht genau 5 gibt 1 die Eingabe s enthält, gibt es keine Lösung, sodass keine Ausgabe erfolgt.
  • Die Mitten jeder Seite sind die falschen Positionen. Hierbei handelt es sich um die Indizes 1, 3, 5 und 7. Summieren Sie den Abstand für jeden1 an diesen Positionen ergibt das Endergebnis.
  • Für jede 1in einer falschen Position ist der Abstand entweder 1 oder 2. Es ist 2, wenn es von anderen 1s umgeben ist. Zum Beispiel, wenn es gibt1 s bei den Indizes [0, 1, 2, 4] befinden, ist der Abstand für das falsche 12.
  • Berücksichtigen Sie in diesem Zusammenhang diesen Pseudocode, um den Abstand zu ermitteln, der durch den Index 1 zum Ergebnis beigetragen hat.

    1. Liest 4 Bits aus den Indizes [1, 0, 2, 4]. Dadurch wird die falsche Position an die wichtigste Position gesetzt.
    2. Wandle diese Bits in eine Zahl um b von 0 bis 15 um.
    3. Wenn 0 <= b <= 7der Abstand 0 ist. Wenn 8 <= b <= 14der Abstand 1 ist. Wenn b == 15der Abstand 2 ist. Dies kann unter Verwendung der Ganzzahldivision durch berechnet werden b * 2 / 15.

Die Gesamtentfernung kann also berechnet werden, indem dieser Vorgang viermal wiederholt und das Gitter dazwischen gedreht wird.

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

Führen Sie dieses aus

rekursiv
quelle
Überprüfen Sie die Bearbeitung, jeder unmögliche Wert wird akzeptiert, nicht nur -1, wenn das hilft
Noah Cristino
Ja. Das sparte 2 Bytes.
rekursive
1

Excel, 86 81 Bytes

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

Alt: Als die "unmögliche" Ausgabe war-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)

Verwendet 1für gefüllt und 0für leer, Eingabe im Bereich A1:C3. Weiter Golf spielen möglich, wenn wir andere Werte als -1"unmöglich" zurückgeben können. Gibt a zurück#DIV/0! Fehler bei unmöglichen Gittern zurück

Arbeitet nach der gleichen Logik wie die Python-Antwort von Bubbler .

Chronozid
quelle
Überprüfen Sie die Bearbeitung, jeder unmögliche Wert wird akzeptiert, nicht nur -1
Noah Cristino