阿弥陀如来


10

日本や東アジアの文化に触れたことがあるなら、あみだくじゲームにきっと出会うことでしょう。

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

以下のようウィキペディアは説明して、それが紙の上に描かれた宝くじの一種であり、ランダムにN項目の順列を選択するために使用しました。

たとえば、N人に開始シーケンスをランダムに割り当てたり、N人にN賞をランダムに割り当てたりするために使用できます。

ゲームが順列を表す理由を理解するコツは、すべての水平ストローク(「レッグ」と呼ばれる)が2つのアイテムを所定の位置で交換することを認識することです。

同じWikipediaのページでも、N個の項目の順列Pはそれぞれ無数のアミダクジ図に対応していると説明されています。水平ストローク(脚)の数が最も少ないものは、その特定の順列Pの「素数」と呼ばれます。

あなたの仕事は、2つ以上の縦線(この例では6)のアミダクジ図を次の形式(文字を除く)で受け取ることです。

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

そして、その素数の1つを生成します(これも、文字を差し引いたものです)。

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

文字を含む最初と最後の行は、フォーマットの一部ではありません。順列を示すためにここに追加しました。また、されていない最初または最後の行は全く足を含まないことが必要で|-|でも出力はできるだけコンパクトであること。

この特定の入力例は、Wikipediaページの上部にあるアミダクジ図の(無限)ASCII表現の1つです。

これらのASCIIダイアグラムには明白でないルールが1つあります。隣接するレッグは禁止されています。

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

ウィキペディアは、「バブライゼーション」と呼ばれる図から素数を取得するための標準的な手順を説明しています。

1)右フォークから左フォーク:

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

2)ダブルスの除去:

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

その説明が明確かどうかはわかりません。コードは、必要な素数を生成するその手法またはその他のアルゴリズムを使用する場合があります。

最短のコードが勝ちます。

標準規則と標準手当が適用されます。(入力が有効でない場合、プログラムが発火する可能性があります。入出力形式は、stdin / stdout、文字列引数、行のリスト、charの行列、最適なものなどです。)

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


3
これは非常に興味深い課題です。思いもよらない解決策を生み出すには、しばらく時間がかかるかもしれませんね。
JosiahRyanW 2018年

出力は可能な限りコンパクトである必要がありますか、それとも脚の数が最小限である限り、縦方向のスペースは許容されますか?
Laikoni 2018年

@Laikoni縦のスペースはいくつでも許可されます。
トビア2018年

気泡化と逆気泡化は同じ結果あみだくじに到達しますか?
l4m2

@ l4m2逆バブライゼーションとは何ですか?
トビア2018年

回答:


4

Pythonの2322の 240バイト

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

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

文字列を指定された形で受け取り、その形で還元されたあみだくじも出力する関数。

ここでの基本的な考え方は、最初に入力を(for x in Xループ内の)順列に変換することです。次に、whileループでその並べ替えのバブルソートを実行します。ウィキペディアの記事にあるように、これは「素数」のアミダクジになるためです。


ワオ。私はPython 3バージョンを作成するのに長い時間を費やしたばかりですが、それは526バイトです。
JosiahRyanW 2018年

数百のランダムな図をコードに入力したところ、正しい素数が出力されることが確認できました。
トビア2018年

3

Haskell、288バイト

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

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

説明

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

よくやった!私はあなたのコードに数千のランダムな図を与えました、そしてそれはそれらすべてを解決しました。
トビア

(_:[])ちょうどすることができ[_]かつp?q=(p:fst q,snd q)可能p?(f,s)=(p:f,s)。代わりに定義するc 0='-';c _=' ';と、その後使用してc m" -"!!(0^abs m)動作するはずです。
ライコニ

(g 0)ブラケットは不要letで、ガード内のaはより短いですwhere。全部で274バイト:オンラインでお試しください!
ライコニ

固定小数点関数%はでインライン化できますuntil(\x->g 0 x==x)(g 0)
ライコニ

2

Retina 0.8.2、105バイト

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

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

$
¶$%`

最後の行を複製します。

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

最終行の列に番号を付けます。

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

最初の行に到達するまで数値を上に移動します。各反復で、右端の番号のみ-1=が移動されます。|前に置かれて-いる場合を除いて、一番右に移動され|ます。その場合、前に移動されます。(rは、正規表現が後読みであるかのように処理されることを示します。これにより、このケースをわずかに簡単に一致させることができます。)これにより、アミダクジがソートされた順序に変換される順列が計算されます。

-
 
1G`

番号のリストだけを保持し-、最初の行以降のsと何かを削除します。

;{`

次に、プログラムの残りの部分が繰り返され、リストが順番に並べ替えられますが、最終的なリストは出力されませんが、Retina 0.8.2がリストが正しいことを確認するために反復を行うため、脚のない行は最後に生成された、これは許容できると思います。

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

隣接するソートされていない数値の利用可能なすべてのペアに-、脚のsを付けます。

*`1+
|

脚を印刷しますが、番号を|sに置き換えます。

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

実際にスワップを実行します。


Retina.exeでコードを実行する方法について何かアドバイスはありますか?私は正しいソース(105バイト)を持っていると思いますが、何も出力しません。Retinaの例からHello Worldを試してみましたが、うまくいきました。どこかでソースをアップロードしたり、エンコーディングを間違ってしまった場合に備えて、Base64でエンコードしてペーストビンに入れたりできますか?
トビア2018年

@トビア申し訳ありませんが、Retina.exeの使い方を思い出せません。私はそれを1〜2回使用した可能性があると思いますが、最近はオンラインで試すだけを使用しています。
Neil

大爆笑だ!0.8.2ではなく、いくつかの最新バージョンを使用していました。これで、ハーネスに何百ものランダムな図をコードに送りました。常に正しい素数を出力することを確認できました。よくやった!
トビア2018年

@Tobiaテストをありがとう!Retina 1に必要な微調整:$**; -1=0; 1_; ;.(大まかに); **\
Neil

1

Pythonの3524の 488 486バイト

-ovsのおかげで-38バイト!

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

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

これは、アミダクジを2Dバイナリ配列に変換し、ルールを使用して直接削減します。


私はあなたのアプローチに興味があります。見てみます!一方で、あなたは交換することにより、いくつかのバイトを保存することができ" "+i.replace("|","")+" "i.split("|")インチ p関数の最初の行...
Chas Brown

さらにいくつかの標準的なPythonゴルファーを調整して、それを479バイトにします
Chas Brown、


ええ、なぜそれが起こっているのかわかりません...
Chas Brown

常にではありません...右フォークから左フォークにできない場合もありますが、左フォークから右フォークにはできます。その特定のケースでは、それはそこで逆のことをするだけの問題です。おそらく私は両方をする必要がありますか?
JosiahRyanW 2018年

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.