Calcule la antípoda de un punto en la curva

14

Una curva es un conjunto de puntos en una cuadrícula cuadrada de modo que cada punto tiene exactamente dos vecinos en el vecindario de cuatro vecinos y los puntos forman un solo componente conectado. Es decir, el gráfico inducido por los puntos en un gráfico de cuadrícula es isomorfo a un solo ciclo. "Inducido" significa que dos puntos no pueden tocarse en la entrada sin ser vecinos en el ciclo.

Una antípoda de un vértice V en un gráfico es un vértice más alejado de V. La antípoda siempre es única en un ciclo de longitud par (y cada ciclo en un gráfico de cuadrícula es de longitud par). La distancia se medirá como inducida por el propio ciclo sin respetar la cuadrícula cuadrada subyacente.

Su entrada será una imagen de una curva. La curva se marcará con una secuencia de caracteres de signo de número ( #) en un fondo sin caracteres de espacio ( ). Uno de los puntos en la curva estará marcado con el Pcarácter ("pode"). Su salida será la misma que la entrada, excepto que un punto de curva se reemplazará con A("antípoda").

Puede suponer que los caracteres se rellenarán con una forma rectangular. Puede suponer que la primera y la última fila y columna de entrada estarán compuestas completamente por espacios (la entrada se rellena con fondo). Alternativamente, puede suponer que la primera y la última fila y columna contendrán un punto de curva (la entrada tiene un relleno mínimo).

Puede ingresar y generar esta cuadrícula como una sola cadena separada por una nueva línea, como una matriz de filas o como una matriz 2D de caracteres individuales. Esta elección será la misma para la entrada y la salida. Si su idioma lo permite, puede modificar la entrada en su lugar en lugar de devolver la cadena o matriz modificada.

Posibles entradas:

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

Salidas correspondientes:

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

Distancias de vértice desde los podes (módulo 10) (no envíe estos):

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
John Dvorak
fuente

Respuestas:

4

JavaScript (ES6), 193181 bytes

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)

Versión que proporciona una animación en bucle:

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>

Neil
fuente
4

Python 2 , 333 221 215 bytes

-17 bytes gracias a @JanDvorak

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

Pruébalo en línea!


Python 3 , 402 288 282 bytes, String 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)))

Pruébalo en línea!


Animación del código en ejecución:

Animación del código en ejecución.

ovs
fuente
4

MATL , 43 42 bytes

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

El código acepta una cantidad arbitraria de espacio en las primeras y últimas filas y columnas. La entrada es una matriz rectangular de caracteres, que se usa ;como separador de filas. Por ejemplo, la entrada

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

se representa como

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

o, en una línea (para que pueda ingresarse a través de STDIN),

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

Pruébalo en línea! O verifique los últimos cuatro casos: 1 , 2 , 3 , 4 (estos han sido elegidos porque tienen las curvas más complicadas; el último tiene algo de espacio).

Explicación

TL; WR: números complejos, mucha indexación, sin convolución.

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
Luis Mendo
fuente
0

Python 3 , 421 bytes

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

Pruébalo en línea!

officialaimm
fuente
0

Mathematica, 234 223 bytes

(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"])&

Este código hace que vsea ​​la lista de vértices para el gráfico: los índices de la "#"y "P"s. Luego nes la longitud (necesariamente uniforme) y qextrae el vértice de entrada (ignorando la forma del bucle).

Luego hes una función que construye el gráfico con vértices vy bordes no dirigidos entre vértices cuando la longitud de la diferencia de sus pares de índices es exactamente 1 (por lo que su diferencia es algo así como {-1,0}o {0,1}) y luego encuentra una lista de todos los ciclos y proporciona el primer (solo) ciclo (como una lista de bordes) y luego toma el borde de entrada y toma el primer vértice que forma ese borde.

Usando h, podemos encontrar el índice de "P"en el ciclo, y recorrer la mitad (usando Mod para ajustar si pasamos los límites de la lista de ciclos) para encontrar la antípoda, y luego podemos reemplazar la entrada correspondiente del original entrada mcon"A"

Puede probarlo en línea pegando lo siguiente en Wolfram Cloud Sandbox y haciendo clic en "evaluar celda" o presionando Shift + Enter o 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

Idea alternativa, 258 bytes.

Ligeramente inspirado por las soluciones Python de ovs , traté de escribir código que no usaría ninguna de las características de la teoría de gráficos de Mathematica y simplemente calcularía ciegamente las distancias. No pude hacerlo tan breve, pero sospecho que alguien podría mejorarlo:

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"])`

Este código es muy ineficiente. Básicamente, reemplaza "P"con 0y luego busca un "#"lado de algo que no es un "#"al recorrerlo todo dos veces y los reemplaza con números que representan la distancia "P", y para asegurarse de que termine, realiza los ntiempos de ese proceso . En realidad, esto ni siquiera calcula las distancias correctamente, ya que una rama podría pasar la antípoda, pero solo se numerará una ubicación n/2sin importar qué.

Marcas.
fuente