Amidakuji (阿 弥陀 籤) sadeleştirme


10

Eğer Japon ya da Doğu Asya kültürüne hiç maruz kaldıysanız, kesinlikle Amidakuji oyunuyla karşılaşmış olacaksınız:

resim açıklamasını buraya girin

As Vikipedi açıklıyor , bu piyango bir tür kağıt üzerinde çizilmiş ve rastgele N öğelerin bir permütasyon seçmek için kullanılır.

Örneğin, N kişiye rastgele bir başlangıç ​​dizisi veya N kişiye N ödül, vb. Atamak için kullanılabilir.

Oyun bir permütasyon temsil neden anlamak için hile (bir "bacak" olarak adlandırılır) her yatay inme fark etmektir swapları yerde onun iki öğeyi.

Aynı Wikipedia sayfası ayrıca N öğenin her permütasyon P'sinin sonsuz sayıda Amidakuji diyagramına karşılık geldiğini açıklar. En az sayıda yatay darbeye (ayağa) sahip olan (lar) bu belirli permütasyon P'nin "primerleri" olarak adlandırılır.

Göreviniz 2 veya daha fazla dikey çizgiyle (bu örnekte 6'dır) bir Amidakuji diyagramı almaktır (eksi harfler):

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

Ve asallarından birini üretin (yine, harfler eksi):

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

Harfleri olan ilk ve son satırlar formatın bir parçası değildir . Buraya permütasyonu göstermek için ekledim. Ayrıca, bir değil, ilk veya son hatlarının bacakları içeren gerekli |-|, ne de çıkış olabildiğince kompakt olması.

Bu özel giriş örneği, Wikipedia sayfasının üstündeki Amidakuji diyagramının (sonsuz) ASCII gösterimlerinden biridir.

Bu ASCII diyagramları hakkında açık olmayan bir kural vardır: bitişik bacaklar yasaktır.

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

Wikipedia, aşağıdaki basitleştirmeleri defalarca uygulamaktan oluşan "kabarcıklanma" adı verilen bir diyagramdan bir asal elde etmek için standart bir prosedürü açıklar:

1) Sağ çatal sol çatala:

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

2) Çiftleri ortadan kaldırmak:

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

Bu açıklamanın açık olup olmadığından emin değilim. Kodunuz bu tekniği veya gerekli primerleri üreten herhangi bir algoritmayı kullanabilir.

En kısa kod kazanır.

Standart kurallar ve standart ödenekler geçerlidir. (Giriş geçerli değilse, programınız alev alabilir. Giriş / çıkış biçimleri stdin / stdout, dize bağımsız değişkeni, satır listesi, karakter matrisi, sizin için en uygun olan vb. Olabilir.)

resim açıklamasını buraya girin


3
Bu çok ilginç bir mücadele. Bir süre çözülmemiş bir çözüm üretebilirim, heh.
JosiahRyanW

Çıktının mümkün olduğunca kompakt olması gerekiyor mu veya bacak sayısı minimum olduğu sürece herhangi bir miktarda dikey alana izin veriliyor mu?
Laikoni

@Laikoni herhangi bir miktarda dikey alana izin verilir.
Tobia

Bubblization ve ters bubblization Amidakuji'nin her sonucuna ulaşıyor mu?
l4m2

@ l4m2 ters kabarcıklanma nedir?
Tobia

Yanıtlar:


4

Python 2 , 322 240 bayt

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

Çevrimiçi deneyin!

Dizeyi belirtilen biçimde alan ve azaltılmış Amidakuji'yi bu biçimde de basan bir işlev.

Buradaki temel fikir, önce girdiyi bir permütasyona ( for x in Xdöngüde) dönüştürmektir; ve sonra whiledöngüde, bu permütasyonun bir kabarcık türünü gerçekleştirin, çünkü wikipedia makalesi notları, bu bir 'asal' Amidakuji ile sonuçlanır.


Vay. Sadece bir Python 3 sürümü yapmak için uzun zaman geçirdim, ama 526 bayt, heh.
JosiahRyanW

Kodunuza yüzlerce rastgele şema besledim ve doğru primler çıkardığını doğrulayabilirim!
Tobia

3

Haskell , 288 bayt

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

Çevrimiçi deneyin!

açıklama

-- 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

Aferin! Kodunuza 1000'lerce rastgele diyagram besledim ve hepsini çözdü.
Tobia

(_:[])adil olabilir [_]ve p?q=(p:fst q,snd q)olabilir p?(f,s)=(p:f,s). Bunun yerine tanımlama c 0='-';c _=' ';kullanarak sonra ve c m, " -"!!(0^abs m)çalışması gerekir.
Laikoni

(g 0)parantez gerektirmez ve letbir muhafızdaki a daha kısadır where. Hep birlikte 274 bayt: Çevrimiçi deneyin!
Laikoni

Düzeltme noktası işleviniz %ile işaretlenebilir until(\x->g 0 x==x)(g 0).
Laikoni

2

Retina 0.8.2 , 105 bayt

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

Çevrimiçi deneyin! Açıklama:

$
¶$%`

Son satırı çoğalt.

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

Son satırdaki sütunları numaralandırın.

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

İlk satıra gelene kadar sayıları yukarı taşıyın. Her yinelemede yalnızca en sağdaki sayı -1=taşınır. Önünde |bir -öncekine geçilmediği sürece en sağa taşınır |. ( rNormal ifadenin, bir göz bağı gibi işlendiğini gösterir, bu da bu durumla eşleşmeyi marjinal olarak kolaylaştırır.) Bu, Amidakuji'nin sıralı sıraya dönüştürdüğü permütasyonu hesaplar.

-
 
1G`

-İlk satırdan sonra s ve her şeyi silerek yalnızca sayı listesini tutun .

;{`

Daha sonra programın geri kalanı tekrarlanır, listeyi tekrar sıraya sıralar, ancak son liste yazdırılmaz, ancak listenin sıralı olduğunu fark etmek için Retina 0.8.2 için bir iterasyon gerektirdiğinden, bacaksız bir çizgi sonunda kabul edilebilir olduğuna inanıyorum.

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

Bitişik sıralanmamış sayıların mevcut tüm çiftlerini -bacaklar için s ile işaretleyin .

*`1+
|

Bacakları yazdırın, ancak sayılar |s ile değiştirin .

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

Aslında takasları gerçekleştirin.


Kodunuzu Retina.exe ile çalıştırma hakkında tavsiyeleriniz var mı? Sanırım doğru kaynağım var (105 bayt) ama hiçbir şey çıktılamıyor. Merhaba Dünya'yı Retina örneklerinden denedim ve işe yarıyor. Bir yere kaynak yükleyebilir misiniz, yoksa Base64 kodlayabilir ve kodlamayı yanlış anlamam durumunda bir çöp kutusuna koyabilir misiniz?
Tobia

@Tobia Üzgünüm, ama Retina.exe kullanmayı hatırlayamıyorum; Sanırım bir ya da iki kez kullanmış olabilirim ama bugünlerde sadece Try It Online kullanıyorum.
Neil

LOL Ben aptalım! 0.8.2 yerine son teknoloji bir versiyon kullanıyordum. Şimdi kablo demetimi kodunuza yüzlerce rastgele diyagram besledim ve her zaman doğru primer çıkardığını doğrulayabilirim. Aferin!
Tobia

@Tobia Test ettiğiniz için teşekkürler! Retina 1 için gerekli ince ayarlar: $**; -1=0; 1_; ;.(kabaca); **\.
Neil

1

Piton 3 , 524 488 486 bayt

-Ovs sayesinde bayt!

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="|")

Çevrimiçi deneyin!

Bu, Amidakuji'yi bir 2D ikili diziye dönüştürür ve kuralları kullanarak doğrudan azaltır.


Yaklaşımını merak ediyorum; Bir bakacağım! Bu arada, yerine " "+i.replace("|","")+" "ile bazı baytlar kaydedebilirsiniz i.split("|"). p
Chas Brown

479 bayt almak için birkaç standart python golf tweaks .
Chas Brown


Yah, bunun neden gerçekleştiğinden emin değil ...
Chas Brown

Her zaman değil ... bazen sağ çataldan sol çatala yapılamaz, ancak sol çataldan sağ çatala. Bu özel durumda, bu sadece tam tersini yapma meselesidir. Belki ikisini de yapmam gerekiyor?
JosiahRyanW

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.