커브상의 점의 안티 포드 계산


14

곡선은 각 점이 4 개 이웃에 정확히 2 개의 이웃을 가지고 있고 점들이 단일 연결된 구성 요소를 형성하도록 정사각형 그리드상의 점 세트입니다. 즉, 그리드 그래프의 점에 의해 유도 된 그래프는 단일 사이클에 대해 동형입니다. "유도"는 싸이클에서 인접하지 않고 두 점이 입력을 건드릴 수 없음을 의미합니다.

그래프에서 꼭짓점 V의 antipode는 V에서 가장 멀리 떨어져있는 꼭짓점입니다. antipode는 항상 짝수 길이주기에서 고유합니다 (그리드 그래프의 모든주기는 짝수 길이). 거리는 기본 정사각형 그리드에 관계없이 사이클 자체에 의해 유도 된대로 측정되어야합니다.

입력은 곡선의 이미지 여야합니다. 곡선은 #배경에 공백이없는 문자 ( )에 일련의 숫자 기호 문자 ( ) 로 표시됩니다 . 곡선의 점 중 하나에 P문자 ( "포드")가 표시됩니다. 하나의 곡선 점이 A( "antipode") 로 대체된다는 점을 제외하고는 출력은 입력과 동일해야합니다 .

문자가 직사각형 모양으로 채워질 것이라고 가정 할 수 있습니다. 입력의 첫 번째와 마지막 행과 열이 완전히 공백으로 구성되어 있다고 가정 할 수 있습니다 (입력은 배경으로 채워집니다). 또는 첫 번째 행과 마지막 행과 열에 각각 곡선 점이 포함되어 있다고 가정 할 수 있습니다 (입력에는 최소 패딩이 있음).

이 그리드를 줄 바꿈으로 구분 된 단일 문자열, 행 배열 또는 개별 문자의 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#####

Pode로부터의 정점 거리 (모듈로 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

자바 스크립트 (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

파이썬 2 , 333 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

온라인으로 사용해보십시오!


파이썬 3 , 402 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

MATL , 43 42 바이트

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

이 코드는 첫 번째 행과 마지막 행과 열에 임의의 양의 공간 패딩을 허용합니다. 입력은 ;행 분리 자로 사용되는 직사각형 문자 배열입니다 . 예를 들어, 입력

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

로 표현된다

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

또는 한 줄로 (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

파이썬 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

매쓰, 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입력 정점을 추출합니다 (루프 모양을 무시 함).

이어서 h정점과 그래프 빌드 함수 v들은 인덱스 쌍 차이의 길이가 정확히 1 인 경우의 정점 사이의 방향성 에지 (그 차분과 같이 무언가 {-1,0}또는 {0,1}) 후 모든 사이클의 목록을 찾아 제를 제공한다 (단지) 순환 (가장자리 목록으로) 한 다음 입력 가장자리를 가져 와서 해당 가장자리를 구성하는 첫 번째 정점을 가져옵니다.

를 사용 하여 사이클 h의 인덱스를 찾은 다음 "P"반쯤 진행하여 (사이클 목록의 경계를 지나갈 경우 Mod를 사용하여 줄 바꿈) 안티 포드를 찾은 다음 원본의 해당 항목을 바꿀 수 있습니다 입력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"0A의 보이는 다음과 "#"아닌입니다 뭔가 옆 "#"에서 거리를 나타내는 숫자로 두번을 대체 그들 전체 것을 통해 반복에 의해 "P"그것은 그 과정의 수행, 그리고 완료 확인하기 위해 n시간을. 이것은 실제로 하나의 브랜치가 안티 포드를 지나갈 수 있기 때문에 거리를 정확하게 계산하지는 못하지만, 한 위치에만 번호가 매겨집니다 n/2.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.