Calcola l'antipode di un punto sulla curva


14

Una curva è un insieme di punti su una griglia quadrata in modo tale che ogni punto abbia esattamente due vicini nel vicinato dei quattro vicini e che i punti formino un singolo componente collegato. Cioè, il grafico indotto dai punti su un grafico a griglia è isomorfo a un singolo ciclo. "Indotto" significa che due punti non possono toccare l'input senza essere vicini nel ciclo.

Un antipode di un vertice V in un grafico è un vertice più lontano da V. L'antipode è sempre unico su un ciclo di lunghezza pari (e ogni ciclo su un grafico a griglia è di lunghezza pari). La distanza deve essere misurata come indotta dal ciclo stesso senza rispettare la griglia quadrata sottostante.

Il tuo input deve essere l'immagine di una curva. La curva verrà contrassegnata con una sequenza di caratteri di segno numerico ( #) su uno sfondo di caratteri spaziali ( ). Uno dei punti sulla curva sarà contrassegnato dal Pcarattere ("pode"). L'output deve essere uguale all'ingresso tranne un punto curva deve essere sostituito con A("antipode").

Puoi presumere che i personaggi saranno riempiti con una forma rettangolare. Puoi presumere che la prima e l'ultima riga e colonna di input siano composte interamente da spazi (l'input è riempito con lo sfondo). In alternativa puoi supporre che la prima e l'ultima riga e colonna contengano ciascuna un punto curva (l'input ha una spaziatura minima).

È possibile immettere e generare questa griglia come una singola stringa separata da nuova riga, come una matrice di righe o come una matrice 2D di singoli caratteri. Questa scelta sarà la stessa per l'input e l'output. Se la tua lingua lo consente, puoi produrre l'output modificando l'input sul posto invece di restituire la stringa o l'array modificato.

Ingressi possibili:

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

Uscite corrispondenti:

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

Distanze dei vertici dai pod (modulo 10) (non emetterli):

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

Risposte:


4

JavaScript (ES6), 193 181 byte

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)

Versione che fornisce un'animazione in loop:

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

Python 2 , 333 221 215 byte

-17 byte grazie 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

Provalo online!


Python 3 , 402 288 282 byte, IO stringa

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

Provalo online!


Animazione del codice in esecuzione:

Animazione del codice in esecuzione


4

MATL , 43 42 byte

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

Il codice accetta una quantità arbitraria di spaziatura spaziale nella prima e nell'ultima riga e colonna. L'input è una matrice rettangolare di caratteri, che utilizza ;come separatore di riga. Ad esempio, l'input

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

è rappresentato come

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

oppure, in una riga (in modo che possa essere inserito tramite STDIN),

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

Provalo online! Oppure verifica gli ultimi quattro casi: 1 , 2 , 3 , 4 (questi sono stati scelti perché hanno le curve più complicate; l'ultimo ha un po 'di spazio).

Spiegazione

TL; WR: numeri complessi, molta indicizzazione, nessuna convoluzione.

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 , 421 byte

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

Provalo online!


0

Mathematica, 234 223 byte

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

Questo codice vcostituisce l'elenco dei vertici per il grafico: gli indici di "#"e "P"s. Quindi nè la lunghezza (necessariamente pari) eq estrae il vertice input-th (ignorando così la forma del loop).

Quindi hè una funzione che costruisce il grafico con vertici ve bordi non indirizzati tra i vertici quando la lunghezza della differenza delle loro coppie di indici è esattamente 1 (quindi la loro differenza è simile a {-1,0}o {0,1}) e quindi trova un elenco di tutti i cicli e fornisce il primo (solo) ciclo (come un elenco di spigoli) e quindi prende l'input-th edge e prende il primo vertice che compone quel edge.

Usando h, possiamo trovare l'indice di "P"nel ciclo e andare a metà strada (usando Mod per andare in giro se superiamo i limiti dell'elenco dei cicli) per trovare l'antipode, e quindi possiamo sostituire la voce corrispondente dell'originale input mcon"A"

Puoi provarlo online incollando quanto segue in Sandbox Wolfram Cloud e facendo clic su "valuta cella" o premendo Maiusc + Invio o Invio tastierino numerico:

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

Leggermente ispirato alle soluzioni Python di ovs , ho cercato di scrivere un codice che non usasse alcuna funzionalità di teoria dei grafi di Mathematica e calcolasse solo alla cieca le distanze. Non potrei ottenerlo in breve, ma sospetto che qualcuno possa migliorarlo:

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

Questo codice è molto inefficiente. Fondamentalmente, sostituisce "P"con 0e quindi cerca un "#"prossimo a qualcosa che non è un "#"ciclo attraverso l'intera cosa due volte e li sostituisce con numeri che rappresentano la distanza da "P", e per assicurarsi che finisca, fa i ntempi di processo . Questo in realtà non calcola nemmeno le distanze correttamente poiché un ramo potrebbe oltrepassare l'antipode, ma solo una posizione verrà numerata, n/2indipendentemente da cosa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.