Island Golf # 1: Çevresi


43

Bu, bir dizi Ada Golf mücadelesinde ilkidir. Bir sonraki meydan okuma

ASCII-sanatında bir ada göz önüne alındığında, çevresini dolaşmak için optimal bir yol çıkar.

Giriş

Girişiniz, kara ve suyu temsil eden iki karakterden oluşan dikdörtgen bir ızgara olacaktır. Aşağıdaki örneklerde, toprak #ve su ., ancak istediğiniz iki karakterin yerine geçebilirsiniz.

...........
...##......
..#####....
..#######..
.#########.
...#######.
...#####.#.
....####...
...........

Her zaman en az bir kara kiremit olacak. Kara kiremitlerinin tümü bitişik olacaktır (yani sadece bir ada vardır). Su karoları da bitişik olacaktır (yani göl yoktur). Şebekenin dış kenarının tamamı su kiremitleri olacaktır. Kara fayans olacak değil çapraz bağlanabilir: yani gibi bir şey görmek asla

....
.#..
..#.
....

Çıktı

Kodunuz, aynı ızgarayı, üzerinde çizilen en kısa örnekleme ile vermelidir . Aşağıdaki örneklerde, dairesel yol çizme yolu çizilir o, ancak toprak ve su karakterlerinden farklı olduğu sürece herhangi bir karakteri kullanabilirsiniz.

Bir circumnavigation tam ızgara üzerinde tüm toprak kiremit etrafını saran, su fayans tamamen çekilmiş basit bir kapalı eğrisidir. Çapraz bağlantıları vardır izin verdi. Örneğin, bu yukarıdaki adanın bir örneğidir (en kısa olanı değil):

.ooooo.....
o..##.oo...
o.#####.o..
o.#######o.
o#########o
ooo#######o
..o#####.#o
..oo####..o
....oooooo.

Bir çevre araştırmasının uzunluğu aşağıdaki şekilde hesaplanır: Yoldaki her bitişik fayans çifti için, yatay veya dikey olarak bağlanmışlarsa, 1 ekleyin; Çapraz bağlanmışlarsa add2 ekleyin. Yukarıdaki yolun uzunluğu 22 + 7√2'dir (≈ 31.9).

En kısa bir örnek, mümkün olan en kısa uzunluğa sahip bir örnek. Programınız bu koşulu karşılayan herhangi bir yolu çıkarmalıdır. Çoğu ada için, birçok olası çözüm olacaktır. 10 + 13√2 (≈ 28,4) uzunluktaki yukarıdaki ada için bir çözüm:

...oo......
..o##oo....
.o#####oo..
.o#######o.
o#########o
.o.#######o
..o#####.#o
...o####.o.
....ooooo..

ayrıntılar

Çözümünüz tam bir program veya işlev olabilir . Herhangi bir varsayılan giriş ve çıkış yöntemleri kabul edilebilir.

Giriş ve çıkışınız çok satırlı bir dize veya bir dize listesi olabilir. Eğer dil tek karakterlik dizeleri ayrı bir karakter türüne sahip, önceki cümlede "dizesi" için "karakter listesi" yerine. Dilinizin ızgaranın yüksekliğini ve / veya genişliğini girmesi gerekiyorsa, bunu yapabilirsiniz. Çıktınızın (isteğe bağlı olarak) tek bir izleyen yeni satırı olabilir. Yukarıda belirtildiği gibi, yerine herhangi bir üç karakter kullanabilirsiniz #.o(lütfen gönderiminizde kullandığınız karakterleri belirtin).

Test durumları

A. Eşsiz en kısa sirkülasyonlara sahip adalar:

...
.#.
...

.o.
o#o
.o.

......
.####.
......

.oooo.
o####o
.oooo.

......
......
..##..
...#..
......
......

......
..oo..
.o##o.
..o#o.
...o..
......

.......
.#####.
...#...
...#...
.#####.
.......

.ooooo.
o#####o
o..#..o
o..#..o
o#####o
.ooooo.

.......
...#...
...#...
.#####.
...#...
...#...
.......

...o...
..o#o..
.o.#.o.
o#####o
.o.#.o.
..o#o..
...o...

.......
.#####.
.##..#.
..#..#.
.......

.ooooo.
o#####o
o##..#o
.o#..#o
..oooo.

B. Birden fazla olası çözümü olan bir ada örneği:

........
....##..
...####.
..###...
.#####..
.#####..
..##....
........

Olası çıkışlar:

....oo..
...o##o.
..o####o
.o###.o.
o#####o.
o#####o.
.o##oo..
..oo....

....oo..
...o##o.
..o####o
.o###.o.
o#####o.
o#####o.
.o##.o..
..ooo...

....oo..
...o##o.
..o####o
.o###..o
o#####.o
o#####o.
.o##oo..
..oo....

....oo..
...o##o.
..o####o
.o###..o
o#####.o
o#####o.
.o##.o..
..ooo...

C. Bir Gist olarak büyük test durumu


Bu : Her dilde en kısa kod kazanır.


1
3. test davası için en kısa örnek, Conway'in Yaşam Oyununda 'somun' örneği!
Yoldaş SparklePony

Yanıtlar:


18

Mathematica (sürüm 9), 165 bayt

ConvexHullMeshGreg Martin'in kullandığı güzel ve kısa işlev yalnızca Mathematica sürüm 10'da tanıtılmıştı, bu yüzden eski Mathematica sürüm 9'umu kullanarak onsuz bir girişimde bulunacağımı düşündüm. Bu alır ve dizgi listesi geri döndüren bir fonksiyon (ile ., #ve osemboller gibi).

""<>#&/@("o"MorphologicalTransform[MorphologicalComponents[#,Method->"ConvexHull"],Max[#(1-#[[2,2]])CrossMatrix@1]&]+"#"#/.{0->"."})&[Characters@#/.{"."->0,"#"->1}]&

Açıklama:

  • İlk Characters@# /. {"."->0, "#"->1}olarak, girişi 0s ve 1s matrisine dönüştürür .
  • "o"MorphologicalTransform[MorphologicalComponents[#,Method->"ConvexHull"],Max[#(1-#[[2,2]])CrossMatrix@1]&]+"#"#daha sonra, önce adanın dışbükey kabuğunu doldurmak için Mathematica'nın güçlü (ancak aşırı derecede bayt-ağır…) görüntü işleme yeteneklerini kullanır (bu, etrafına bir ip geçirirseniz alacağınız şeklidir) ve sonra sınırını alır. Daha sonra s ve s "o"matrisini elde etmek için bu matrisi dizeyle çarptık (Mathematica'nın türlerle ilgili etkileyici uyarlaması sayesinde) ve bunu adanın matrisinin zamanına ekledik.0"o""#"
  • Son olarak, ""<>#& /@ (... /. {0->"."})bu matris döner "o", s "#"s ve 0bir matris içine s "o"s, "#"s ve "."s ve bir dizeye her satır katılır.

Bunu B örneğinde test ettiğimizde çıktıyı alırız.

{"....oo..",
 "...o##o.",
 "..o####o",
 ".o###..o",
 "o#####o.",
 "o#####o.",
 ".o##oo..",
 "..oo...."}

[Düzenle, Greg Martin sayesinde:] Dizge listeleri yerine karakter dizilerini kullanmamıza izin verilirse, bunu 144 bayta indirebiliriz:

"o"MorphologicalTransform[MorphologicalComponents[#,Method->"ConvexHull"],Max[#(1-#[[2,2]])CrossMatrix@1]&]+"#"#/.{0->"."}&[#/.{"."->0,"#"->1}]&

1
Güzel bitti! Hiç bilmedim MorphologicalComponents[#, Method->"ConvexHull"] :) Girdinin zaten karakterlere ayrıldığını varsayarak ve ayrıca bir 2D karakter dizisini döndürerek daha fazla bayttan tasarruf edebilirsiniz.
Greg Martin

@GregMartin, şu ana MorphologicalComponentskadar bu kullanım hakkında hiçbir şey bilmiyordum !
Bir ağaç değil

Burada Mathematica acemi: Bu işlevi nasıl çağırmalıyım? Denedim f[{"...",".#.","..."}]ve bazı hatalar aldım.
DLosc

@DLosc, İşlev sadece bir şey değil, her şeydir f. (Eh, kesinlikle, noktalı virgülden sonraki şeylerdir.) İşlevi çağırmak için, her şeyi bir Mathematica penceresine yazın, ardından [girişinizi girin ve ]bu nedenle f@m_:=m(1-m[[2,2]]) . . . #/.{"."->0,"#"->1}]&[{"...", ".#.", "..."}](boşluk için kısaltılmış) gibi bir şey görünmelidir .
Ağaç değil

@DLosc Eh, çünkü kod bozuk. Sanırım şimdi düzelttim! (Orada ne olduğu hakkında hiçbir fikrim yok; üzgünüm…)
bir ağaç değil.

11

(Ama Notatree'nin çözümünü yükselt , daha iyi!)

Mathematica, 168 bayt

(x_~n~y_:=Min[Norm[x-#]&/@y];i=#;p=i~Position~#&;t=p["#"|"."]~Select~#&;(i~Part~##="o")&@@@t[#~n~t[ConvexHullMesh[Join[s=p@"#",#+{.1,.1}&/@s]]~RegionMember~#&]==1&];i)&

2B karakter dizisini girdi olarak alan ve 2B karakter dizisini döndüren salt işlev. Okunması kolay bir sürüm:

1  (x_~n~y_ := Min[Norm[x - #] & /@ y];
2  i = #; p = i~Position~# &; 
3  t = p["#" | "."]~Select~# &;
4  (i~Part~## = "o") & @@@ 
5    t[#~n~
6      t[ConvexHullMesh[
7        Join[s = p@"#", # + {.1, .1} & /@ s]]
8      ~RegionMember~# &] == 1 &];
9  i) &

Çizgi 1 , düzlemdeki nbir nokta xile bir dizi ydiğer nokta arasındaki (en küçük) mesafeyi üreten işlevi tanımlar . Satır 2 i, hem körleme belirsizliğini daha sonra gidermek hem de nihai çıktısını üretmek için onu değiştirebilmek için değişkeni girdiye başlatır ; Satır 2 ayrıca pgirişindeki tüm oluşumların koordinatlarını döndüren bir fonksiyon tanımlar i.

3. satırda p["#" | "."], giriş haritasındaki her bir koordinatı temsil eder (tüm karakterleri ya "#"da "."olduğundan dolayı), tyalnızca henüz belirtilmemiş bir özelliği karşılayan koordinatları seçen bir işlevdir. 4. satırda karaktere yapılan i~Part~## = "o"girişleri değiştirecek ; bu karakterler 5-8. satırlardaki öğelere göre olası koordinatlar kümesinden seçilecektir. Ve 9. satır, hesaplandıktan sonra yanıtı döndürür.i"o"

Tamam, altyapı bitti, şimdi gerçek hesaplamaya. ConvexHullMeshMathematica'nın, bir nokta kümesinin dışbükey kabuğunu (bu noktaları içeren en küçük dışbükey çokgen) hesaplamak için yerleşiktir. Ahlaki açıdan konuşursak, bu s = p@"#"onları adamızın koylarını ve fiyortlarını "doldurmalı", onları da dışlanmamamızın dışında bırakmak için. ConvexHullMeshBu nokta kümesinin tümü bir satırda olduğunda (teşekkür ederim, sınama durumu # 2), s7 satırında kendisinin biraz dengelenmiş bir sürümünü ekleyerek çözdüğümüzle ilgili küçük bir sorun var . -9 (t[...~RegionMember~# &]) o poligonda tamsayı koordinatlarına sahip noktaların bir listesini üretir. Son olarak, satır 5 ve satır 9'un sonu, bu tamsayı nokta kümesinden tam olarak 1 olan (yani 0 olmayan) tüm noktaları hesaplar; bu küme dairesel dolaşıma girer.

Aşağıda OP'nin linkindeki büyük test senaryosu için çıktı verilmiştir. Sol üstte dikkat edin, ne zaman batıya karşı güneybatıya gidilecek sıradışı seçimler iki yarımada arasında (2, 3, 3, 2, 3, 2, 2) 'nin görünmeyen bir eğim çizgisini gölgelediği gerçeğini ima eder.

........................
.............o..........
...........oo#ooooooo...
..........o#.#.##...#o..
........oo.#.#.###.##o..
.......o..########.##o..
.....oo...############o.
...oo#....############o.
..o#.###.##############o
.o##.##################o
.o####################o.
.o.##################.o.
.o##################..o.
.o..################..o.
o###################..o.
o#####################o.
o.##################.o..
o####################o..
o#...##############.o...
o##...#############o....
o#.....###....#oooo.....
.oooooo#ooooooo.........
.......o................

Mathematica, genellikle karakterleri 1B karakter dizisi olarak mı gösterir? Değilse, bunun yerine 1D dizge dizisini almanız / döndürmeniz gerekir. (Ayrıca, açıklamayı dört gözle bekliyorum! Bunu Mathematica'ya sahip olmadan çalıştırabileceğimi sanmıyorum, değil mi?)
DLosc

Mathematica'da bir dize veri tipi vardır, ancak bu sitenin amaçları için bir karakter dizisinin de geçerli olduğu anlaşılmaktadır (yani, PPCG'ye başladığımda bunu öğrendim ama nedeninin yasallıklarını unutuyorum). Evet, ne yazık ki, Mathematica ücretsiz değil ve bu nedenle birçok insan için erişilebilir değil :(
Greg Martin

1
Hep de Mathematica çözümleri denemek @GregMartin sandbox.open.wolframcloud.com
ovs

Mevcut fikir birliği , tek karakterli dizelerin listelerinin bir dizenin yerine kullanılamayacağını söylüyor. Söyleyebileceğim kadarıyla, Mathematica'daki "karakterler" Python'da olduğu gibi sadece tek karakterli dizelerdir. Durum, ayrı bir chartüre sahip olan Java gibi bir dilde farklı ; Bu durumda, bir chardize yerine bir dizi kullanılabilir.
DLosc

1
İşte nasıl okudum: En önemli yanıtlanan cevap 2014'te yayınlandı. Bağladığım cevap, önceki cevaptaki belirsizliği açıklığa kavuşturmak amacıyla 2016 yılında yayınlandı. Bu yüzden yeni cevabın olumsuz puanını, insanların “Hayır, eski cevabın tek-karakterli dizelerin listelerinin tamam olduğu anlamına gelmesini istemesini istemiyoruz” dediği gibi okudum. Ancak metadan bağımsız olarak, bu sorudaki tek-karakterli dizgelerin listelerine izin vermiyorum (ve bunu yansıtacak ifadeleri açıklığa kavuşturdum).
DLosc

10

Python 3, 779 bayt (sekmelerle girintili)

Bütün program bu. Stdin'den girdi okur ve onu stdout'a yazdırır. Stdin, EOF ile bitmelidir. Büyük girişle çalışan örnek: https://ideone.com/XIfYY0

import itertools,sys
L=list
C=itertools.count
d=L(map(L,filter(None,sys.stdin.read().split('\n'))))
X=len(d[0])
Y=len(d)
R=range
def P(r):return all(d[y][x]=='.'for x,y in r)
def S(f):
    for n in C(0):
        if P(f(n)):l=n
        else:break
    for n in C(l+1):
        if P(f(n)):return l,n
def f(V,a,*b):return L(eval('lambda '+a+':('+i+')',V)for i in b)
V=locals()
def D(n):
    y=min(n,Y-1);x=n-y
    while y>=0and x<X:yield(x,y);x+=1;y-=1
def E(n):
    x=max(0,n-Y);y=x+Y-n
    while y<Y and x<X:yield(x,y);x+=1;y+=1
F=f(V,'p','(p,y)for y in R(0,Y)','(x,p)for x in R(0,X)')+[D,E]
r=f(V,'x,y','x','y','x+y','x-y+Y')
B=L(map(S,F))
for x in R(0,X):
    for y in R(0,Y):
        z=L(zip(r,B))
        if all(g(x,y)in R(a,b+1)for g,(a,b)in z)and any(g(x,y)in e for g,e in z):d[y][x]='o'
print('\n'.join(''.join(x)for x in d))

Fikir basit: en küçük sekizgen sınırlarını hesaplar ve hesaplanan tüm sınırların içinde bulunan ve kenarlardan en az birini kesişen hücreleri çizer.


1
Gerçekten sys.stdingirdi olarak kullanmanıza gerek yok . input(), multiline almak işi yapar ve daha az byte eder
Dead Possum 23.03

2
R(0,x)R(x)
Ceilingcat

Yerleşik kullanmadığınız için +1.
Robert Fraser

1
Güzel! Bazı golf önerileri: tanımlamak için lambda kullanarak 5 bayttan tasarruf edin Pve f; L(generator expression)=> [generator expression]; F, rve Byalnızca bir kez kullanıldığında göründüğü için satır içi olabilir.
DLosc

8

JavaScript (ES6), 369 343 bayt

f=s=>(a=s.split`
`.map(s=>[...s]),m=Array(8),a.map((b,i)=>b.map((c,j)=>c>'#'||[i-j,i,j+i,j,j-i,-i,-i-j,-j].map((d,k)=>d>m[k]||(m[k]=d-1)))),[o,p,q,r,t,u,v,w]=m,g=(i,j,k,l,...p)=>i-k|j-l?a[i][j]=g(i+(k>i)-(k<i),j+(l>j)-(l<j),k,l,...p):1/p[0]?g(k,l,...p):'o',g(p,p-o,p,q-p,q-r,r,r-t,r,-u,t-u,-u,u-v,w-v,-w,o-w,-w,p,p-o),a.map(b=>b.join``).join`
`)

Açıklama: Dize bir karakter dizisine bölündü (karakter dizisi girişinin kabul edilip edilmediği konusunda belirsizim). Ardından dizi tekrarlanır ve tüm arazi karelerinin konumları bulunur. Denklemlerle verilen sınırlayıcı hatları x - y = o, x = p, x + y = q, y = r, y - x = t, -x = u, -x - y = v, -y = wmümkün olan maksimum parametre çizgisinin ötesine nerede bütün kara yalan seçilmesi öyle belirlenir. Bunun, adanın bir sekizgen içine çevrilmesi etkisi vardır. Sekizgen köşelerinin koordinatları parametrelerden kolaylıkla hesaplanır ve kenarlarındaki hücreler doldurulur. Dizi daha sonra bir dizgeye geri birleştirilir. Bir sekizgenin yeterli olmasının nedeni şöyledir:

   /o#     /o#     /o#
 |/o #   |/o #   |/ o#
 *o###   * o #   *  o#
/|o #   /|o #   /| o#
 |o#     |o#     |o#

Sekizgen bir köşe düşünün. İki kenar boyunca bir noktada, karayla mümkün olduğu kadar yakın temas edecek sekizgen inşa ettikten sonra yol toprakla sınırlı olacaktır. Köşenin kendisinde bir arazi yoksa, yol sağda gösterilen şekilde alternatif rotalara gidebilir, ancak bu hala aynı dikey ve çapraz adımlarla aynıdır, bu nedenle mesafe değişmez.


'' P 'ne yapar?
Robert Fraser,

@RobertFraser Teknik isim dizi imha ediyor. Ancak bu durumda, sadece rest of argumentsparametre olarak işlev görür .
Neil

@Neil Aslında, teknik isim rest parametresidir . Spread operatörü için aynı sözdizimi kullanılır . (Her ikisini de ...pfarklı yerlerdeki gibi kullanıyorsunuz .) Yıkım başka bir şeydir (yayılma operatörü yıkımda kullanılabilir).
Brian McCutchon

@BrianMcCutchon Haklısın, yayılma operatörünü kastettim, ancak yine de tartışma listelerinde çalışmaları yok etmek.
Neil

6

Python 3.5, 224, 263, 234 218 bayt

İç içe geçmiş işlevden kurtularak ve tek bir astar yaparak, başka bir 16 baytlık golf attı.

def h(s,k=0,i=0):w=s.find('\n')+1;x=s.find('X')-w;k=k or x;d=[1,w+1,w,w-1,-1,-w-1,-w,-w+1]*2;u=s[:k]+'o'+s[k+1:];return['X'>s[k]and i<8and(h(u,k+d[i+2],i+2)or h(u,k+d[i+1],i+1)or h(u,k+d[i],i))or'',s][s[k]>'X'and k==x]

29 byte golf oynadı:

def f(s):
 w=s.find('\n')+1;x=s.find('X')-w;d=[1,w+1,w,w-1,-1,-w-1,-w,-w+1]*2
 def h(s,k,i):u=s[:k]+'o'+s[k+1:];return['X'>s[k]and i<8and(h(u,k+d[i+2],i+2)or h(u,k+d[i+1],i+1)or h(u,k+d[i],i))or'',s][s[k]>'X'and k==x]
 return h(s,x,0)

Giriş, okyanus için '~', kara için 'X' ve sınır için 'o' kullanan tek bir dizedir. ('X' kullanımı '==' yerine '>' için bayt kazandırır)

Yorumlarla daha az golf versiyonu:

def f(s):
    w=s.find('\n')+1                         # width of one row
    x=s.find('X')-w                          # starting point
    d=[1,w+1,w,w-1,-1,-w-1,-w,-w+1]*2        # delta to add to current index to move in 
                                             # the 8 directions: E, SE, S, SW, W, NW, 
                                             # N, NE. Make it long to avoid
                                             # lots of modulo operations in 
                                             #    the recursive calls

    def h(s,k,i):                            # s is the island string, k the current
                                             # position, i the direction index
        if s[k]>'X'and k==x:                 # if back at the begining,
            return s                         #   return the map

        elif 'X'>s[k] and i<8:               # if there is water here, and haven't
                                             #  looped around,
            u=s[:k]+'o'+s[k+1:]              #  make a new map with an 'o' in the 
                                             #  current spot

            r = h(u,k+d[i+2],i+2)            # try a 90 degree right turn
            if r: return r

            r = h(u,k+d[i+1],i+1)            # try a 45 degree turn
            if r: return r

            r= h(u,k+d[i],i)                 # try straight ahead
            if r: return r

        return ''                            # this path failed

    return h(s,x,0)

@DLosc düzeltildi. (eski cevabı
silmeli miyim

Güzel! (Evet, eski cevabı kaldırmalısınız - eğer birileri görmek isterse,
yazının

5

C # 7 - 414 369 327 bayt

Düzenleme : 1D döngü, bilgi işlem ive janında

Düzenleme : girdi yöntemini değiştirdi, arama tablosunu daralttı ve iyi tanımlanmış başlangıç ​​sınırlarına geçti ... ve son dış for-loop'daki anlamsız boşluğu kaldırdı

using C=System.Console;class P{static void Main(){var D=C.In.ReadToEnd().Replace("\r","");int W=D.IndexOf('\n')+1,H=D.Length,z=H,k,q,c;int P()=>z%W*(k%3-1)+z/W*(k/3-1)+H;var B=new int[9];for(;z-->0;)for(k=9;k-->0&D[z]%7<1;)if(B[k]<=P())B[k]=P()+1;for(;++z<H;C.Write(q>9?'o':D[z]))for(q=k=9;k-->0;)q*=(c=P()-B[k])>0?0:c<0?1:2;}}

Çevrimiçi Deneyin

Komple program, standart in girdi alır standart dışı onu yazdırır, kullanımları #, .ve o. Her hücre için, bir 'profili' hesaplar (8 yönden uzak olan mesafedir (kolaylık sağlamak için dokuzuncu bir hesaplama yapar, ancak bu her zaman böyledir 0) ve bunların her birinin maksimumunu kaydeder. Sonra tüm haritayı yazar. Yine, hem sınırda olan, hem de dışında olmayan bir hücrenin yerini 'o' ile değiştirir .. Aşağıdaki yorum kodu her şeyin nasıl çalıştığını açıklar.

Soyları tükenişten kurtarmak için verdiğim cevaba göre , bu, adayı sınırlayan en küçük sekizgenleri (en geniş alana sahip geçerli örnekleme) üretir.

Not : Hayatımda bir kez mevcut on yıldan bir şey kullanıyorum ve bu kodun derlenmesi için C # 7 gerekiyor. C # 7'niz yoksa, değiştirilmesi gereken ve kodda açıkça işaretlenmiş olan bir satır var.

Örnek kullanım ve çıktı:

type t7.txt | IslandGolf1.exe

.........ooooooooooo....
........o....#......o...
.......o...#.#.##...#o..
......o....#.#.###.##.o.
.....o....########.##..o
....o.....############.o
...o.#....############.o
..o#.###.##############o
.o##.##################o
o.####################.o
o..##################..o
o.##################...o
o...################...o
o###################...o
o#####################.o
o.##################..o.
o####################o..
o#...##############.o...
o##...#############o....
o#.....###....#...o.....
.o.....#.........o......
..ooooooooooooooo.......

Biçimlendirilmiş ve yorumlanmış kod:

using C=System.Console;

class P
{
    static void Main()
    {
        // \n 10
        // # 35
        // . 46
        // o 111


        var D=C.In.ReadToEnd().Replace("\r",""); // map

        int W=D.IndexOf('\n')+1, // width
            H=D.Length, // length
            z=H, // position in map (decomposed into i and j by and for P)
            k, // bound index
            q, // bound distance, and later cell condition (0 -> outside, 8 -> inside, >8 -> on boudary)
            c; // (free), comparison store

        // 'indexes' into a profile for the point z at index k
        // effectively {i=z%W,j=z/W,-i,-j,i+j,j-i,-i-j,i-j,0}[k] (inside order is a bit different) (0 const is always treated as 'inside bounds')
        // each non-zero-const entry describes the distance in one of the 8 directions: we want to maximise these to find the 'outer bounds'
        // the non-zero-const bounds describe 8 lines, together an octogen
        int P()=>z%W*(k%3-1)+z/W*(k/3-1)+H; // new C#7 local method syntax (if you don't have C#7, you can test this code with the line below instead)
        //k=0;System.Func<int>P=()=>z%W*(k%3-1)+z/W*(k/3-1)+H; // old lambda syntax (must pre-assign k to make static checker happy)

        var B=new int[9]; // our current bounds, each is initially null (must only call P() when on a #)
        // B[k] starts off a 0, P() has a +H term, and W+(H/W)<H for W >= 3, so B[k] is assigned the first time we compare it (H-i-j always > 0)

        for(;z-->0;) // for each cell
            for(k=9;k-->0& // for each bound
                D[z]%7<1;) // if this cell is #
                if(B[k]<=P())B[k]=P()+1; // update bound if necessary (add one so that we define the bound _outside_ the hashes)
        // z=-1
        for(;++z<H; // for each cell
                C.Write(q>9?'o':D[z])) // print the cell (if q > 9, then we are on the bounds, otherwise, spit out whatever we were before)
            // check we are not 'outside' any of the bounds, and that we are 'on' atleast one of them
            for(q=k=9;k-->0;) // for each bound
                q*=(c=P()-B[k])>0?0: // outside bound (q=0)    (??0 is cheaper than (int) or .Value)
                    c<0?1: // inside (preserve q)
                    2; // on bound (if q != 0, then q becomes > 9)
    }
}

en büyük sekizgen mi? veya en küçük?
Sarge Borsch

@SargeBorsch teşekkürler, metni düzeltti.
VisualMelon
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.