曲線上の点の対極を計算する


14

曲線は、正方形のグリッド上の点のセットであり、各点は4近傍の正確に2つの近傍を持ち、点は単一の連結成分を形成します。つまり、グリッドグラフ上のポイントによって誘導されるグラフは、単一のサイクルと同型です。「誘導」とは、2つのポイントがサイクル内で隣接していなければ入力をタッチできないことを意味します。

グラフ内の頂点Vの対極は、Vから最も遠い頂点です。対極は、偶数長のサイクルでは常に一意です(グリッドグラフの各サイクルは偶数長です)。距離は、基礎となる正方形グリッドを考慮せずに、サイクル自体によって誘導されるように測定するものとします。

入力は曲線の画像でなければなりません。曲線は#、スペース文字()から背景に番号記号文字()のシーケンスでマークアウトされます。曲線上の点の1つにP文字(「ポッド」)が付けられます。出力は入力と同じになりますが、1つのカーブポイントがA(「対極」)に置き換えられます。

文字が長方形にパディングされると仮定することができます。入力の最初と最後の行と列は完全にスペースで構成されていると想定できます(入力には背景が埋め込まれます)。または、最初と最後の行と列にそれぞれ曲線ポイントが含まれると想定することもできます(入力には最小のパディングがあります)。

このグリッドは、改行で区切られた単一の文字列、行の配列、または個々の文字の2D配列として入出力できます。この選択は、入力と出力で同じです。言語でこれが許可されている場合、変更された文字列または配列を返す代わりに、入力をその場で変更して出力できます。

可能な入力:

P#    P##   #P#   #####      #####P# #######   #####P#########   #####P#########
##    # #   # #   #   #      #     # #     #   #             #   #             #
      ###   ###   ## ##      # ### # # ### #   # ### ### ### #   #             #
###                # # ###   # # # # # # # #   # # # # # # # #   #             #
# P#    ### ###    # ### #   # # ### ### # #   # # ### ### # #   #             #
## #    # ### #    #     #   # #         # #   # #         # #   #             #
 # #    P     #    ##### P   # ########### #   # ##### ##### #   #             #
 ###    #######        ###   #             #   #     # #     #   #             #
                             ###############   ####### #######   ###############

対応する出力:

P#    P##   #P#   #A###      #####P# #A#####   #####P#########   #####P#########
#A    # #   # #   #   #      #     # #     #   #             #   #             #
      ##A   #A#   ## ##      # ### # # ### #   # ### ### ### #   #             #
###                # # ###   # # # # # # # #   # # # # A # # #   #             #
# P#    ### ##A    # ### #   # # ### ### # #   # # ### ### # #   #             #
## #    # ### #    #     #   # #         # #   # #         # #   #             #
 A #    P     #    ##### P   # ########### #   # ##### ##### #   #             #
 ###    #######        ###   #             #   #     # #     #   #             #
                             ###############   ####### #######   #########A#####

ポッドからの頂点距離(モジュロ10)(これらを出力しないでください):

P1    P12   1P1   5A543      54321P1 9A98765   54321P123456789   54321P123456789
1A    1 3   2 2   4   2      6     2 8     4   6             0   6             0
      23A   3A3   32 01      7 109 3 7 109 3   7 901 789 543 1   7             1
321                1 9 543   8 2 8 4 6 2 8 2   8 8 2 6 A 6 2 2   8             2
4 P1    234 89A    0 876 2   9 3 765 543 7 1   9 7 345 987 1 3   9             3
56 2    1 567 9    9     1   0 4         6 0   0 6         0 4   0             4
 A 3    P     8    87654 P   1 56789012345 9   1 54321 56789 5   1             5
 654    1234567        321   2             8   2     0 4     6   2             6
                             345678901234567   3456789 3210987   345678901A10987

回答:


4

JavaScript(ES6)、193 181バイト

f=s=>s==(`P#1P#21#12#221A`[r=`replace`](/.../g,([n,f,t])=>s=s[r](eval(`/([${n+=f}])([^]{${s.search`\n`}})?(?!\\1)[${n}]/`),m=>m[r](eval(`/^${f}|${f}$/`),t))),s)?s[r](/\d/g,`#`):f(s)

ループアニメーションを提供するバージョン:

f=s=>s==(`#A#1#12#221AP#1P#2`[r=`replace`](/.../g,([n,f,t])=>s=s[r](eval(`/([${n+=f}])([^]{${s.search`\n`}})?(?!\\1)[${n}]/`),m=>m[r](eval(`/^${f}|${f}$/`),t))),s)?s[r](/\d/g,`#`):s
;setInterval(_=>i.value=f(i.value),1e3)
<textarea rows=10 cols=20 id=i style="font-family:monospace"></textarea>


4

パイソン2333の 221 215バイト

@JanDvorakのおかげで-17バイト

g=input()
y=map(max,g).index('P')
x=g[y].index('P')
m=[k[:]for k in g]
v=x;w=y
while'#'in sum(m,[]):x,y,(v,w)=v,w,[(x+a,y+b)for a,b in((1,0),(-1,0),(0,1),(0,-1))if'#'==m[y+b][x+a]][0];m[w][v]='_'
g[w][v]='A'
print g

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


Pythonの3402 288 282バイト、文字列IO

g=[[*k]for k in open(0).read().split('\n')]
y=[max(k)for k in g].index('P')
x=g[y].index('P')
m=[k[:]for k in g]
v=x;w=y
while'#'in sum(m,[]):x,y,(v,w)=v,w,[(x+a,y+b)for a,b in((1,0),(-1,0),(0,1),(0,-1))if'#'==m[y+b][x+a]][0];m[w][v]='_'
g[w][v]='A'
print('\n'.join(map(''.join,g)))

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


実行中のコードのアニメーション:

実行中のコードのアニメーション


4

MATL43 42バイト

32-I#fbbJ*+!w3>y"&)yy-|&X<]vJQ2/)G65b&Zj&(

このコードは、最初と最後の行と列に任意の量のスペースパディングを受け入れます。入力は、;行セパレータとして使用する文字の長方形配列です。たとえば、入力

#####   
#   #   
## ##   
 # # ###
 # ### #
 #     #
 ##### P
     ###

として表されます

['#####   ';
 '#   #   ';
 '## ##   ';
 ' # # ###';
 ' # ### #';
 ' #     #';
 ' ##### P';
 '     ###']

または、1行で(したがって、STDINを介して入力できます)、

['#####   '; '#   #   '; '## ##   '; ' # # ###'; ' # ### #'; ' #     #'; ' ##### P'; '     ###']

オンラインでお試しください!または、最後の4例を確認します。 1 2 3 4(彼らは最も複雑な曲線を持っているので、これらが選択されています。最後の一つは、いくつかのスペースパディングを持っています)。

説明

TL; WR:複素数、大量のインデックス付け、畳み込みなし。

32-     % Implicitly input char matrix. Subtract 32. Space becomes zero
I#f     % 3-output find: pushes nonzero values, their row indices,
        % and their column indices, as column vectors
bb      % Bubble up twice, so row and column indices are on top
J*+     % Times 1j, add. This transforms row and column indices into
        % complex numbers, where real is row and imaginary is column
!       % Transpose into a row vector
w       % Swap, so vector of nonzero values is on top
3>      % Logical index of elements exceeding 3. ASCII codes of space,
        % '#' and 'P0 are 32, 35 and 80 respectively. Since 32 was
        % subtracted these became 0, 3 and 48. So the only entry with
        % value exceeding 3 is that corresponding to the original 'P'.
y"      % Do this as many times as the number of complex positions
        %   The stack now contains the vector of complex positions and an
        %   index into that vector. The index points to the complex position 
        %   to be processed next.
  &)    %   Two-output reference indexing: pushes the indexed entry and
        %   a vector with the remaining entries. This pulls off the
        %   current complex position, which is initially that of 'P'
  yy    %   Duplicate top two elements, i.e. current position and vector
        %   of remaining positions
  -|    %   Absolute differences
  &X<   %   Index of minimum. Gives the index of the complex position
        %   that is closest to the current one. In case of tie (which
        %   only happens in the first iteration) it picks the first. The 
        %   result is the index of the complex position to be processed in 
        %   the next iteration. This index will be empty if this is the last
        %   iteration.
]       % End
        % The stack now contains the complex positions as individual
        % values, starting from 'P' and sorted as per the curve; plus two 
        % empty arrays. These empty arrays have been produced by the last
        % iteration as the index for the "next" iteration and the array of
        % "remaining" complex positions
v       % Concatenate into a column vector. The empty arrays have no effect.
        % The resulting vector contains the sorted complex positions
JQ      % Push 1j and add 1
2/      % Divide by 2. This gives (1+1j)/2. When used as an index this is
        % interpreted as (1+end)/2. Since the length of the curve is even
        % this gives a non-integer number, which will be implicitly
        % rounded up (because of .5 fracctional part). As an example, for
        % length 32 this gives 16.5, which rounded becomes 17. Position 17
        % along the curve is the antipode of position 1
)       % Reference indexing. Gives the complex position of the antipode
G       % Push input char matrix again
65      % Push 65 (ASCII for 'A')
b       % Bubble up, so complex position is on top
&Zj     % Separate into real and imagimary parts, corresponding to row and
        % column indices
&(      % 4-input assignment indexing. This writes 'A' at the specified row
        % and column of the char matrix. Implicitly display

0

Python 3 3、421バイト

l,e=len,enumerate
r=open(0).read()
n=lambda x:[(x[0]-1,x[1]),(x[0]+1,x[1]),(x[0],x[1]-1),(x[0],x[1]+1)]
p=a={(i,j):y for i,x in e(r.split('\n'))for j,y in e(x)}
t=l(r.split('\n'));s=l(r.split('\n')[0])
for i in a:p=[p,i][a[i]=='P']
w=[p]
while l(w)!=r.count('#')+1:
 for x in a:
  if x in n(w[-1])and a[x]!=' 'and x not in w:w+=[x]
a[w[(l(w)+1)//2]]='A';print('\n'.join(''.join(a[j,i]for i in range(s))for j in range(t)))

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


0

Mathematica、234 223バイト

(p=Position;v=p[#,"#"|"P"];n=Length@v;q=v[[#]]&;h=FindCycle[Graph[v,Join@@Table[If[Norm[q@i-q@j]==1,q@i<->q@j,Nothing],{i,n},{j,i-1}]]][[1,#,1]]&;ReplacePart[#,h@Mod[p[Table[h@x,{x,n}],p[#,"P"][[1]]][[1,1]]+n/2,n,1]->"A"])&

このコードはv、グラフの頂点リストになります:"#"および"P"sのインデックス。それからn、長さ(必然的に偶数)でq、入力の頂点を抽出します(そのため、ループの形状は無視されます)。

次に、インデックスペアの差の長さが正確に1であるため(頂点の差がまたはのようなものである場合)、h頂点内vおよび頂点間の無向エッジでグラフを構築し、すべてのサイクルのリストを見つけて最初の関数を提供する関数です(のみ)サイクル(エッジのリストとして)してから、入力番目のエッジを取得し、そのエッジを構成する最初の頂点を取得します。{-1,0}{0,1}

を使用して、サイクル内hののインデックスを検索し、"P"中間点に移動して(サイクルリストの境界を超える場合はModを使用してラップアラウンドします)対anti点を検索し、元の対応するエントリを置換できます入力m付き"A"

Wolfram Cloud Sandboxに以下を貼り付けて「セルを評価」をクリックするか、Shift + EnterまたはNumpad Enterを押すと、オンライン試すことができます。

(p=Position;v=p[#,"#"|"P"];n=Length@v;q=v[[#]]&;h=FindCycle[Graph[v,Join@@Table[If[Norm[q@i-q@j]==1,q@i<->q@j,Nothing],{i,n},{j,i-1}]]][[1,#,1]]&;ReplacePart[#,h@Mod[p[Table[h@x,{x,n}],p[#,"P"][[1]]][[1,1]]+n/2,n,1]->"A"])&@{{"#","#","#","#","#"," "," "," "},{"#"," "," "," ","#"," "," "," "},{"#","#"," ","#","#"," "," "," "},{" ","#"," ","#"," ","#","#","#"},{" ","#"," ","#","#","#"," ","#"},{" ","#"," "," "," "," "," ","#"},{" ","#","#","#","#","#"," ","P"},{" "," "," "," "," ","#","#","#"}}//MatrixForm

代替案、258バイト

ovsのPythonソリューションに少し触発されて、Mathematicaのグラフ理論機能を使用せず、盲目的に距離を計算するコードを記述しようとしました。私はそれを短くすることはできませんでしたが、誰かがそれを改善できると疑っています:

f[m_]:=(x="#";t=ReplacePart;p=Position;l=t[m,p[m,"P"][[1]]->0];v=p[l,x|0];n=Length[v];q=v[[#]]&;r=l[[q[#][[1]],q[#][[2]]]]&;y=t[l,q@#->(r@#2+1)]&;Do[If[Norm[q@i-q@j]==1&&Xor[r@i==x,r@j==x],If[r@i==x,l=y[i,j],l=y[j,i]]],n,{i,n},{j,n}];t[m,p[l,n/2][[1]]->"A"])`

このコードは非常に非効率的です。基本的に、それは置き換え"P"0、その後を探し"#"ていない何かの隣に"#"二回全体のことをループでからの距離を表す数字に置き換える"P"と、必ずそれを終了させるために、そのプロセスのないn時間を。実際には、1つのブランチが対antiを通過する可能性があるため、距離を正確に計算することすらできませんが、1つだけの場所に番号が付けられn/2ます。

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