Amidakuji (阿 弥陀 籤) Vereinfachung


10

Wenn Sie jemals Kontakt mit der japanischen oder ostasiatischen Kultur hatten, werden Sie sicherlich auf das Amidakuji-Spiel gestoßen sein:

Geben Sie hier die Bildbeschreibung ein

Wie Wikipedia erklärt , handelt es sich um eine Art Lotterie, die auf Papier gezeichnet und zur zufälligen Auswahl einer Permutation von N Elementen verwendet wird.

Beispielsweise kann es verwendet werden, um N Personen zufällig eine Startsequenz zuzuweisen oder N Personen N Preise zuzuweisen und so weiter.

Der Trick , um zu verstehen , warum das Spiel eine Permutation darstellt , ist zu erkennen , dass jeder horizontaler Hub (ein „Bein“ genannt) tauscht seine beiden Elemente an ihrem Platz.

Dieselbe Wikipedia-Seite erklärt auch, dass jede Permutation P von N Elementen einer unendlichen Anzahl von Amidakuji-Diagrammen entspricht. Diejenigen mit der geringsten Anzahl horizontaler Striche (Beine) werden als "Primzahlen" dieser bestimmten Permutation P bezeichnet.

Ihre Aufgabe ist es, ein Amidakuji-Diagramm mit 2 oder mehr vertikalen Linien (in diesem Beispiel 6) in diesem Format (abzüglich der Buchstaben) zu erhalten:

A B C D E F
| | | | | |
|-| |-| |-|
| |-| |-| |
| | | | |-|
| |-| |-| |
| | |-| |-|
| | |-| | |
|-| | |-| |
|-| |-| | |
| |-| | |-|
| | | | | |
B C A D F E

Und produziere eine seiner Primzahlen (wieder abzüglich der Buchstaben):

A B C D E F
| | | | | |
|-| | | |-|
| |-| | | |
| | | | | |
B C A D F E

Die erste und letzte Zeile mit den Buchstaben sind nicht Teil des Formats. Ich habe sie hier hinzugefügt, um die Permutation zu zeigen. Es ist auch nicht erforderlich , dass die ersten oder letzten Zeilen keine Beine enthalten |-|, noch , dass die Ausgabe möglichst kompakt sein.

Dieses spezielle Eingabebeispiel ist eine der (unendlichen) ASCII-Darstellungen des Amidakuji-Diagramms oben auf der Wikipedia-Seite.

Bei diesen ASCII-Diagrammen gibt es eine nicht offensichtliche Regel: Benachbarte Beine sind verboten.

|-|-|  <-  NO, this does not represent a single swap!

Wikipedia erklärt ein Standardverfahren zum Erhalten einer Primzahl aus einem Diagramm namens "Bubblization", das darin besteht, die folgenden Vereinfachungen immer wieder anzuwenden:

1) Rechte Gabel zur linken Gabel:

| |-|      |-| |
|-| |  ->  | |-|
| |-|      |-| |

2) Eliminieren von Doppel:

|-|        | |
|-|   ->   | |

Ich bin mir nicht sicher, ob diese Erklärung eindeutig ist. Ihr Code verwendet möglicherweise diese Technik oder einen anderen Algorithmus, der die erforderlichen Primzahlen erzeugt.

Der kürzeste Code gewinnt.

Es gelten Standardregeln und Standardzulagen. (Wenn die Eingabe nicht gültig ist, kann Ihr Programm Feuer fangen. Eingabe- / Ausgabeformate können stdin / stdout, Zeichenfolgenargument, Zeilenliste, Zeichenmatrix, was auch immer für Sie am besten funktioniert, usw. sein.)

Geben Sie hier die Bildbeschreibung ein


3
Dies ist eine sehr interessante Herausforderung. Es könnte eine Weile dauern, bis ich eine Lösung ohne Wolf gefunden habe, heh.
JosiahRyanW

Muss die Ausgabe so kompakt wie möglich sein oder ist ein beliebiger vertikaler Raum zulässig, solange die Anzahl der Beine minimal ist?
Laikoni

@Laikoni beliebig viel vertikaler Raum ist erlaubt.
Tobia

Erreichen Bubblization und inverse Bubblization das gleiche Ergebnis wie Amidakuji?
14 m2

@ l4m2 was ist inverse Bubblization?
Tobia

Antworten:


4

Python 2 , 322 240 Bytes

def f(X):
 X=[[c>' 'for c in s.split('|')]for s in X.split('\n')];h=L=len(X[0])-1;p=range(L)
 for x in X:p=[a-x[a]+x[a+1]for a in p]
 while h:h=i=0;exec"if p[i]>p[i+1]:print'|'+i*' |'+'-|'+(L-i-2)*' |';h=p[i],p[i+1]=p[i+1],p[i]\ni+=1\n"*~-L

Probieren Sie es online aus!

Eine Funktion, die die Zeichenfolge in der angegebenen Form verwendet und auch das reduzierte Amidakuji in dieser Form ausgibt.

Die Grundidee hier ist, zuerst die Eingabe in eine Permutation (in der for x in XSchleife) umzuwandeln ; whileFühren Sie dann in der Schleife eine Blasensorte dieser Permutation durch, da dies, wie im Wikipedia-Artikel erwähnt, zu einem 'primären' Amidakuji führt.


Beeindruckend. Ich habe gerade lange Zeit damit verbracht, eine Python 3-Version zu erstellen, aber es sind 526 Bytes, heh.
JosiahRyanW

Ich habe Ihrem Code gerade Hunderte von zufälligen Diagrammen zugeführt und kann bestätigen, dass er die richtigen Primzahlen ausgibt!
Tobia

3

Haskell , 288 Bytes

p x(_:[])=x
p(x:y:z)(_:b:c)|b=='-'=y:p(x:z)c|0<1=x:p(y:z)c
c 0='-'
c _=' '
_#1="|"
m#n='|':c m:(m-1)#(n-1)
p?q=(p:fst q,snd q)
f%b|b==f b=b|0<1=f%f b
f l=reverse$snd$(g 0)%(foldl p[1..n]l,[])where n=1+div(length$l!!0)2;g b((x:y:z),a)|x>y=y?g(b+1)(x:z,a++[b#n])|0<1=x?g(b+1)(y:z,a);g _ x=x

Probieren Sie es online aus!

Erläuterung

-- the function p performs the permutation of a list
-- according to a single line from amidakuji board
p x (_:[]) = x
p (x:y:z) (_:b:c)
    | b == '-' = y : p (x : z) c
    | otherwise = x : p (y : z) c

-- helper to select either leg '-' or empty cell
c 0 = '-'
c _ = ' '

-- the # operator generates an amidakuji line containing one leg
-- which corresponds to one swap during bubble sort

-- terminal case, just one edge left
_ # 1 = "|"
-- each cell contains an edge '|' and either space or a '-' for the "active" cell
m # n = '|' : c m : (m - 1) # (n - 1)

-- helper to find the limit value of a function iteration
f % b
    | b == f b = b  -- return the value if it is unchanged by the function application 
    | otherwise = f % f b -- otherwise repeat

-- helper to appropriately combine q which is the result of invocation of 
-- the function g (see below), and a character p
p ? q = (p : fst q, snd q)

-- the function that does the work
f l = reverse $ snd $ (g 0) % (foldl p [1..n] l, []) where
    -- number of lines on the board
    n = 1 + div (length $ l !! 0) 2
    -- apply one iteration of bubble sort yielding (X, Y)
    -- where X is partially sorted list and Y is the output amidakuji
    g b ((x:y:z), a)
        -- if we need to swap two elements, do it and add a line to our board
        | x > y = y ? g (b + 1) (x:z, a ++ [b # n])
        -- if we don't need to, just proceed further
        | otherwise = x ? g (b + 1) (y:z, a)
    -- terminal case when there is only one element in the list
    g _ x = x

Gut gemacht! Ich habe Ihrem Code Tausende von zufälligen Diagrammen zugeführt und sie alle gelöst.
Tobia

(_:[])kann gerecht sein [_]und p?q=(p:fst q,snd q)kann sein p?(f,s)=(p:f,s). Anstatt zu definieren c 0='-';c _=' ';und dann zu verwenden c m, " -"!!(0^abs m)sollte funktionieren.
Laikoni

(g 0)benötigt keine Klammern und ein letin einer Wache ist kürzer als where. Alles in allem 274 Bytes: Probieren Sie es online aus!
Laikoni

Ihre Fixpunktfunktion %kann mit eingebunden werden until(\x->g 0 x==x)(g 0).
Laikoni

2

Retina 0,8,2 , 105 Bytes

$
¶$%`
r`.?.\G
 1$.'$*
+r-1=`\|(-?.?[- 1]*¶.*)(1+)
$2$1
-
 
1G`
;{`\b(1+) \1
$1-$1
*`1+
|
(1+)-(1+)
$2 $1

Probieren Sie es online aus! Erläuterung:

$
¶$%`

Dupliziere die letzte Zeile.

r`.?.\G
 1$.'$*

Nummerieren Sie die Spalten in der letzten Zeile.

+r-1=`\|(-?.?[- 1]*¶.*)(1+)
$2$1

Bewegen Sie die Zahlen nach oben, bis sie in die erste Zeile gelangen. Bei jeder Iteration wird nur die Nummer ganz rechts -1=verschoben. Es wird ganz nach rechts verschoben, |es sei denn, es wird ein vorangestellt. -In diesem Fall wird es zum vorherigen verschoben |. (Das rzeigt an, dass der reguläre Ausdruck so verarbeitet wird, als wäre er ein Lookbehind, was es geringfügig einfacher macht, diesen Fall abzugleichen.) Dies berechnet die Permutation, die der Amidakuji in eine sortierte Reihenfolge umwandelt.

-
 
1G`

Behalten Sie nur die Liste der Zahlen bei und löschen Sie das -s und alles nach der ersten Zeile.

;{`

Der Rest des Programms wird dann wiederholt, um die Liste wieder in die richtige Reihenfolge zu sortieren. Die endgültige Liste wird jedoch nicht gedruckt. Da jedoch eine Iteration für Retina 0.8.2 erforderlich ist, um festzustellen, dass die Liste in Ordnung ist, befindet sich eine Zeile ohne Beine am Ende generiert, was ich für akzeptabel halte.

\b(1+) \1
$1-$1

Markieren Sie alle verfügbaren Paare benachbarter unsortierter Zahlen mit -s für die Beine.

*`1+
|

Drucken Sie die Beine, wobei die Zahlen durch |s ersetzt werden.

(1+)-(1+)
$2 $1

Führen Sie die Swaps tatsächlich durch.


Haben Sie Ratschläge, wie Sie Ihren Code mit Retina.exe ausführen können ? Ich denke, ich habe die richtige Quelle (105 Bytes), aber es gibt nichts aus. Ich habe die Hello World aus den Retina-Beispielen ausprobiert und es funktioniert. Können Sie die Quelle irgendwo hochladen oder Base64 codieren und in einen Pastebin legen, falls ich die falsche Codierung habe?
Tobia

@Tobia Sorry, aber ich kann mich nicht erinnern, wie man Retina.exe benutzt; Ich glaube, ich habe es ein- oder zweimal benutzt, aber heutzutage benutze ich nur Try It Online.
Neil

LOL Ich bin dumm! Ich habe eine hochmoderne Version anstelle von 0.8.2 verwendet. Jetzt habe ich mein Geschirr dazu gebracht, Ihrem Code Hunderte von zufälligen Diagrammen zuzuführen, und ich kann bestätigen, dass immer die richtigen Primzahlen ausgegeben werden. Gut gemacht!
Tobia

@Tobia Danke fürs Testen! Für Retina 1 erforderliche Anpassungen: $**; -1=0; 1_; ;.(ungefähr); **\.
Neil

1

Python 3 , 524 488 486 Bytes

-38 Bytes dank OVS!

from numpy import*
A=array;E=array_equal
K=[0]
def r(a,m,n):
	X=len(m);Y=len(m[0]);W,H=a.shape
	for x in range(W-X+1):
		for y in range(H-Y+1):
			if E(a[x:x+X,y:y+Y],A(m)):a[x:x+X,y:y+Y]=A(n)
	return a
def p(a):
	b=A([[j>" "for j in i]for i in[i.split("|")for i in a.split("\n")]])
	while E(a,b)<1:a=b;Z=K*3;O=[0,1,0];T=[K+O,O+K]*2;D=[O,O],[Z,Z];P=[Z,O],[O,Z];*R,_=T;_,*L=T;b=r(r(r(r(r(r(a[any(a,1)],R,L),*D),*P),L,R),*D),*P)
	for i in a:print("",*[" -"[j]for j in i[1:-1]],"",sep="|")

Probieren Sie es online aus!

Dadurch wird das Amidakuji in ein 2D-Binärarray konvertiert und mithilfe der Regeln direkt reduziert.


Ich bin neugierig auf Ihren Ansatz. Ich werde einen Blick darauf werfen! In der Zwischenzeit können Sie einige Bytes speichern, indem Sie sie " "+i.replace("|","")+" "durch i.split("|")in ersetzen . die erste Zeile Ihrer pFunktion ...
Chas Brown

Ein paar weitere Standard-Python-Golf-Optimierungen, um 479 Bytes zu erreichen .
Chas Brown


Yah, nicht sicher, warum das passiert ...
Chas Brown

Nicht immer ... manchmal ist die Abzweigung von rechts nach links nicht machbar, aber von links nach rechts. In diesem speziellen Fall geht es nur darum, dort das Gegenteil zu tun. Vielleicht muss ich beides tun?
JosiahRyanW

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.