Eğri üzerindeki bir noktanın antipodunu hesapla


14

Bir eğri, kare bir ızgara üzerindeki bir nokta kümesidir, öyle ki her nokta dört komşu mahallede tam olarak iki komşuya sahiptir ve noktalar tek bir bağlı bileşen oluşturur. Yani, bir ızgara grafiğindeki noktaların indüklediği grafik, tek bir döngüye izomorfiktir. "İndüklenmiş", döngüde komşu olmadan iki noktanın girişe dokunamayacağı anlamına gelir.

Bir grafikteki tepe noktasının V antipodu, V'den en uzak olan bir tepe noktasıdır. Antipode, her zaman eşit uzunlukta bir döngüde benzersizdir (ve bir ızgara grafiğindeki her döngü eşit uzunlukta). Mesafe, alttaki kare ızgaraya saygı duyulmaksızın, döngünün kendisi tarafından indüklendiği şekilde ölçülecektir.

Girişiniz bir eğrinin görüntüsü olmalıdır. Eğri #, boşluk karakterleri olmayan bir arka plan üzerinde bir dizi sayı işareti karakteriyle ( ) işaretlenir . Eğri üzerindeki noktalardan biri Pkarakterle ("pode") işaretlenir. Çıktınız, bir eğri noktasının A("antipode") ile değiştirilmesi dışında giriş ile aynı olacaktır .

Karakterlerin dikdörtgen bir şekle doldurulacağını varsayabilirsiniz. İlk ve son satırın ve sütununun tamamen boşluklardan oluşacağını varsayabilirsiniz (giriş arka planla doldurulur). Alternatif olarak, ilk ve son satır ve sütunun her birinin bir eğri noktası içereceğini varsayabilirsiniz (girişin minimum dolgusu vardır).

Bu ızgarayı satır satırından oluşan tek bir dize, satır dizisi veya tek tek karakterlerin 2B dizisi olarak girebilir ve çıktısını alabilirsiniz. Bu seçim giriş ve çıkış için aynı olacaktır. Diliniz buna izin veriyorsa, değiştirilen dize veya diziyi döndürmek yerine girdiyi değiştirerek çıktı alabilirsiniz.

Olası girişler:

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

Karşılık gelen çıktılar:

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

Kodlardan köşe mesafeleri (modulo 10) (bunları çıktılamayın):

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

Yanıtlar:


4

JavaScript (ES6), 193 181 bayt

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)

Döngü animasyonu sağlayan sürüm:

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 bayt

@JanDvorak sayesinde -17 bayt

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

Çevrimiçi deneyin!


Python 3 , 402 288 282 bayt, dize 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)))

Çevrimiçi deneyin!


Çalışan kodun animasyonu:

Çalışan kodun animasyonu


4

MATL , 43 42 bayt

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

Kod, ilk ve son satır ve sütunlarda rastgele miktarda boşluk doldurmayı kabul eder. Girdi, ;satır ayırıcı olarak kullanılan dikdörtgen bir dizi dizidir . Örneğin, girdi

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

olarak temsil edilir

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

veya bir satırda (STDIN ile girilebilir),

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

Çevrimiçi deneyin! Veya son dört vakayı doğrulayın: 1 , 2 , 3 , 4 (bunlar en karmaşık eğrilere sahip oldukları için seçildi; sonuncusunda biraz boşluk dolgusu var).

açıklama

TL; WR: Karmaşık sayılar, çok sayıda indeksleme, evrişim yok.

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 bayt

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

Çevrimiçi deneyin!


0

Mathematica, 234223 bayt

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

Bu kod v, grafiğin tepe noktası listesini oluşturur: "#"ve "P"s indeksleri . Daha sonra nuzunluk (zorunlu olarak eşittir) ve qgiriş-tepe noktasını çıkarır (böylece halkanın şeklini görmezden gelir).

Ardından h, vdizin çiftlerinin farkının uzunluğu tam olarak 1 olduğunda (böylece farkları {-1,0}veya benzeri bir şeydir {0,1}) ve sonra tüm döngülerin bir listesini bulur ve (sadece) döngüsünü (kenarların listesi olarak) ve sonra giriş kenarını alır ve bu kenarı oluşturan ilk tepe noktasını alır.

Kullanarak h, "P"antipodu bulmak için döngüdeki indeksini bulabiliriz ve yarıya kadar dolaşabiliriz (döngü listesinin sınırlarını geçersek etrafta dolaşmak için Mod'u kullanarak) ve ardından orijinalin ilgili girişini değiştirebiliriz. giriş mile"A"

Şunları yapabilirsiniz çevrimiçi denemek de aşağıdaki yapıştırarak ile Wolfram Bulut Sandbox "hücreyi değerlendirmek" ve tıklayarak veya + Enter veya Numpad Enter Shift isabet:

(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

Alternatif fikir, 258 bayt

Ovs'un Python çözümlerinden biraz esinlenerek , Mathematica'nın herhangi bir grafik teorisi özelliğini kullanmayacak ve sadece körü körüne mesafeleri hesaplayacak bir kod yazmaya çalıştım. Kısa olarak alamadım, ancak birinin geliştirebileceğinden şüpheleniyorum:

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

Bu kod çok verimsiz. Temelde, yerini "P"ile 0bir arar ve sonra "#"bir olduğunu şeye sonraki "#"mesafeyi temsil eden sayılar ile iki kez ve birinci cümledeki onları bütün şey döngü tarafından "P"o süreç yapar ve bitirir emin olmak için nkez. Bu aslında mesafeleri doğru olarak hesaplamaz, çünkü bir dal antipodu geçebilir, ancak n/2ne olursa olsun sadece bir konum numaralandırılacaktır .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.