아일랜드 골프 # 1 : 우회 항


43

이것은 일련의 아일랜드 골프 도전에서 첫 번째입니다. 다음 도전

ASCII 예술의 섬이 주어지면 그것을 둘러싼 최적의 경로를 출력하십시오.

입력

입력 내용은 토지와 물을 나타내는 두 문자로 구성된 직사각형 격자입니다. 아래 예에서 land is #and water is .이지만 원하는 두 개의 다른 문자를 대체 할 수 있습니다.

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

항상 하나 이상의 랜드 타일이 있습니다. 랜드 타일은 모두 연속적입니다 (즉, 하나의 섬만 있습니다). 물 타일도 연속적입니다 (예 : 호수가 없음). 격자의 외부 경계는 모두 물 타일입니다. 랜드 타일은 대각선으로 연결 되지 않습니다 . 예를 들어

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

산출

코드는 동일한 그리드를 출력해야하며 가장 짧은 우회 항을 그려야합니다. 아래 예에서 circumnavigation 경로는로 표시 o되지만 토지 및 물 문자와 구분되지 않는 한 모든 문자를 대체 할 수 있습니다.

일주는 완전히 그리드에 모든 토지 타일을 둘러싸는 것으로, 물 타일에 전적으로 그려진 간단한 닫힌 곡선이다. 대각선 연결 허용됩니다. 예를 들어, 이것은 위 섬의 우회 항입니다 (가장 짧은 것은 아님).

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

circumnavigation의 길이는 다음과 같이 계산됩니다. 경로의 인접한 타일 쌍마다 수평 또는 수직으로 연결된 경우 1을 추가하십시오. 대각선으로 연결되어 있으면 √2를 더하십시오. 위 경로의 길이는 22 + 7√2 (≈ 31.9)입니다.

최단 일주는 최단 길이의 일주한다. 프로그램은이 조건을 만족하는 경로를 출력해야합니다. 대부분의 섬에는 여러 가지 가능한 솔루션이 있습니다. 길이 10 + 13√2 (≈ 28.4)의 위 섬에 대한 한 가지 해결책은 다음과 같습니다.

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

세부

귀하의 솔루션은 전체 프로그램 또는 기능 일 수 있습니다 . 임의의 기본 입출력 방법 으로 허용된다.

입력 및 출력은 여러 줄 문자열 또는 문자열 목록 일 수 있습니다. 경우 언어를 단일 문자열을 구별 문자 유형이, 당신은 이전 문장에서 "문자열"에 대한 "문자의 목록"을 대체 할 수 있습니다. 언어에서 그리드의 높이 및 / 또는 너비를 입력해야하는 경우 입력 할 수 있습니다. 출력물에 (선택 사항) 단일 후행 줄 바꿈이있을 수 있습니다. 위에서 언급 한 바와 같이, 대신 3 개의 다른 문자를 사용할 수 있습니다 #.o(제출시 사용중인 문자를 지정하십시오).

테스트 사례

A. 가장 짧은 우회 항을 가진 섬들 :

...
.#.
...

.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. 가능한 여러 솔루션이있는 섬의 예 :

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

가능한 출력 :

....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. 요점으로서의 큰 테스트 사례


이것은 : 각 언어에서 가장 짧은 코드가 승리합니다.


1
세 번째 테스트 사례에 대한 가장 짧은 우회 탐색은 Conway의 Game of Life에서 '로프'패턴입니다!
스파클 포니 동지

답변:


18

Mathematica (버전 9), 165 바이트

ConvexHullMeshGreg Martin이 사용하는 멋지고 짧은 기능은 Mathematica 버전 10에서만 소개되었으므로 고대 Mathematica 버전 9를 사용하여 시도하지 않고 시도 할 것이라고 생각했습니다. 그것은 받아 문자열 목록을 반환하는 함수의 (와 ., #그리고 o기호 등).

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

설명:

  • 먼저 Characters@# /. {"."->0, "#"->1}입력을 0s와 1s의 행렬로 바꿉니다 .
  • "o"MorphologicalTransform[MorphologicalComponents[#,Method->"ConvexHull"],Max[#(1-#[[2,2]])CrossMatrix@1]&]+"#"#그런 다음 Mathematica의 강력한 (그러나 매우 바이트가 많은) 이미지 처리 기능을 사용하여 먼저 섬의 볼록 껍질 (주변을 펼치면 얻을 수있는 모양)을 채우고 경계를 정합니다. 그런 다음이 행렬에 문자열 "o"을 곱하여 0s와 "o"s의 행렬 (Mathematica의 유형에 대한 인상적인 적응성 덕분에) 을 얻고 이것을 "#"섬의 행렬에 곱합니다.
  • 마지막으로, ""<>#& /@ (... /. {0->"."})이 행렬 온 "o", (S)을 "#"S 및 0매트릭스로 변환하는 "o"S, "#"S와 "."S 및 문자열로 각 행을 결합한다.

예제 B 에서 이것을 테스트 하면 출력을 얻습니다.

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

[Greg Martin 덕분에 편집 :] 문자열 목록 대신 문자 배열을 사용할 수 있다면이를 144 바이트로 줄일 수 있습니다.

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

1
잘 했어요! 나는 결코 몰랐다 MorphologicalComponents[#, Method->"ConvexHull"] :) 입력이 이미 문자로 나뉘어져 있다고 가정하고 2D 문자 배열을 반환하여 더 많은 바이트를 절약 할 수 있습니다.
Greg Martin

@GregMartin, MorphologicalComponents오늘까지 그 사용법에 대해 몰랐 습니다!
나무가 아님

Mathematica 초보자 :이 함수를 어떻게 호출해야합니까? 시도 f[{"...",".#.","..."}]하고 오류가 발생했습니다.
DLosc

@DLosc,이 기능은 단순한 것이 아니라 모든 것 f입니다. 함수를 호출 다음에하는 티카 창에 전체 일을 입력합니다 (음, 엄격하게.이 세미콜론 후 물건 말하기) [귀하의 의견, 그리고 ]그것과 같이 보일 것입니다, 그래서 f@m_:=m(1-m[[2,2]]) . . . #/.{"."->0,"#"->1}]&[{"...", ".#.", "..."}](공간 요약 된 참조).
나무가 아님

@DLosc 글쎄요, 코드가 깨 졌기 때문입니다. 그래도 내가 고쳤다 고 생각합니다! (무슨 일이 일어 났는지 전혀 모르겠습니다. 죄송합니다…)
나무가 아닙니다.

11

(그러나 Notatree의 솔루션을 upvote 하십시오 , 더 좋습니다!)

매스 매 티카, 168 바이트

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

2D 문자 배열을 입력으로 받아서 2D 문자 배열을 반환하는 순수한 기능. 읽기 쉬운 버전 :

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

라인 1은 평면 의 점과 다른 점 세트 n사이의 거리 (가장 작은 거리)를 생성 하는 함수 를 정의합니다 . 라인 2는 변수 를 입력으로 초기화합니다. 나중에 카레 링 모호성을 해결하고 최종 출력을 생성하도록 변수 를 수정할 수 있습니다. 2 행 은에 입력 된 모든 항목의 좌표를 반환 하는 함수도 정의합니다 .xyipi

3 행 p["#" | "."]에서, 모든 문자가 "#"또는 이므로 입력 맵에서 모든 단일 좌표를 나타내 "."므로 t아직 지정되지 않은 속성을 만족하는 좌표 만 선택하는 함수입니다. 라인 4 에서 캐릭터에 i~Part~## = "o"대한 여러 항목을 변경합니다 . 해당 문자는 5-8 행의 내용에 따라 가능한 좌표 세트에서 선택됩니다. 그리고 9 행은 일단 계산되면 답을 반환합니다.i"o"

좋아요, 이제 인프라가 완성되었습니다. ConvexHullMeshMathematica는 내장 된 포인트 세트 (그 포인트를 포함하는 가장 작은 볼록 다각형)의 볼록 껍질을 계산하기 위해 내장되어 있습니다. 도덕적으로 말하면, 이것은 섬의 코브와 피요르드 (즉 s = p@"#",)를 “채움”으로 채워서 cicrumnavigation에서 배제해야합니다. 그 ConvexHullMesh점 세트가 모두 한 줄에있을 때 약간의 문제가 있습니다 (감사합니다, 테스트 사례 # 2). 우리 s는 7 번째 줄에 약간 오프셋 된 버전을 추가하여 해결 합니다.이 출력은 다각형이므로 7 번째 줄 -9 (t[...~RegionMember~# &])는 해당 다각형에 정수 좌표가있는 점 목록을 생성합니다. 마지막으로, 라인 5와 라인 9의 끝은이 정수 포인트 세트로부터 정확히 1 (따라서 0이 아님) 거리에있는 모든 포인트를 계산합니다. 그 세트는 우회 경로가됩니다.

다음은 OP 링크에서 대규모 테스트 사례에 대한 결과입니다. 왼쪽 위의 서쪽에서 남서쪽으로 갈 때의 특이한 선택은 두 반도 사이에 보이지 않는 경사 선 -2/3을 가리고 있다는 사실을 암시합니다 (선 세그먼트는 볼록 껍질의 경계의 일부 임).

........................
.............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는 일반적으로 문자열을 1D 문자 배열로 표시합니까? 그렇지 않은 경우 대신 1D 문자열 배열을 가져 오거나 반환해야합니다. (또한 설명을 기대합니다! Mathematica없이 바로 실행할 수있을 것
같지

Mathematica에는 문자열 데이터 유형이 있지만이 사이트의 목적에 따라 문자 배열도 유효한 것 같습니다 (즉, PPCG를 시작할 때 이것을 배웠지 만 그 이유에 대한 합법성은 잊어 버렸습니다). 그렇습니다, 불행히도, Mathematica는 자유롭지 않으므로 많은 사람들이 이용할 수 없습니다 :(
Greg Martin

1
난 항상에서 매스 매 티카 솔루션을 시도 @GregMartin sandbox.open.wolframcloud.com
OVS

현재의 합의에 따르면 문자열 대신 단일 문자 문자열 목록을 사용할 수 없습니다. 내가 알 수있는 한, Mathematica의 "문자"는 Python과 같이 단일 문자 문자열입니다. Java와 같은 언어에서는 상황이 다르며 별도의 char유형이 있습니다. 이 경우 char문자열 대신 배열을 사용할 수 있습니다.
DLosc

1
내가 읽는 방법은 다음과 같습니다. 주요 upvoted 답변은 2014 년에 게시되었습니다. 내가 연결 한 답변은 2016 년에 게시되어 이전 답변의 모호성을 명확하게하기위한 것입니다. 그래서 나는 사람들이 "아니, 우리는 단일 문자 문자열 목록이 괜찮다는 것을 의미하는 오래된 대답을 원하지 않는다"고 말하면서 새로운 대답에 대한 부정적인 점수를 읽었습니다. 그러나 관계없이 메타, 나는에 단일 문자 문자열 목록을 허용하지있어 질문 (그리고 나는 그것을 반영하는 문구를 명확히).
DLosc

10

Python 3, 779 바이트 (탭으로 들여 쓰기)

이것은 전체 프로그램입니다. stdin에서 입력을 읽고 stdout에 인쇄합니다. Stdin은 EOF로 끝나야합니다. 큰 입력으로 실행하는 예제 : 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))

아이디어는 간단합니다. 가장 작은 팔각형 경계를 계산하고 모든 계산 된 경계 안에 있고 가장자리 중 하나 이상과 교차하는 셀을 그립니다.


1
실제로 sys.stdin입력 으로 사용할 필요는 없습니다 . input(), 여러
줄로

2
대체 할 수 있습니다 R(0,x)으로R(x)
ceilingcat

내장을 사용하지 않는 경우 +1
Robert Fraser

1
좋은! 더 많은 골프 팁 : 람다를 사용하여 각각 5 바이트를 절약 P하고 f; L(generator expression)=> [generator expression]; F, r그리고 B한 번 씩 사용하는 것으로 나타 때문에 인라인 될 수 있습니다.
DLosc

8

자바 스크립트 (ES6), 369 343 바이트

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

설명 : 문자열이 문자 배열로 나뉩니다 (문자 배열 입력이 허용되는지 확실하지 않습니다). 그런 다음 배열을 반복하고 모든 토지 사각형의 위치를 ​​찾습니다. 방정식에 의해 주어진 경계 라인은 x - y = o, x = p, x + y = q, y = r, y - x = t, -x = u, -x - y = v, -y = w최대 가능한 파라미터는 줄 여기서 이후 모든 랜드 거짓말을 선택하도록 결정된다. 이것은 팔각형으로 섬을 둘러싸는 효과가 있습니다. 팔각형의 모서리 좌표는 매개 변수에서 쉽게 계산되고 가장자리의 셀이 채워집니다. 그런 다음 배열이 다시 문자열로 결합됩니다. 팔각형이 충분한 이유는 다음과 같습니다.

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

팔각형의 모서리를 고려하십시오. 두 가장자리를 따라 어느 시점에서 우리는 팔각형이 가능한 한 땅에 닿도록 건설 되었기 때문에 경로가 땅에 의해 제한 될 것입니다. 코너 자체에 토지가없는 경우 경로는 오른쪽에 표시된대로 대체 경로를 사용할 수 있지만 여전히 같은 수의 직교 및 대각선 단계이므로 거리가 변경되지 않습니다.


‘... p’는 무엇을합니까?
Robert Fraser

@RobertFraser 기술적 이름은 배열을 파괴하는 것입니다. 그러나이 경우에는 rest of arguments매개 변수의 역할 만합니다 .
Neil

@Neil 실제로 기술명은 rest parameter 입니다. 스프레드 연산자에 동일한 구문이 사용됩니다 . (당신은 모두를 사용하는 ...p다른 장소에서 가능합니다.) Destructuring는 (확산 연산자 destructuring에서 사용할 수 있지만) 다른 무언가이다.
Brian McCutchon

@BrianMcCutchon 당신 말이 맞습니다. 저는 스프레드 연산자를 의미했지만 어쨌든 인수 목록에서 구조 작업이 중단되었습니다.
Neil

6

파이썬 3.5, 224, 263, 234218 바이트

중첩 함수를 제거하고 하나의 라이너로 만들어 16 바이트를 더 떨어 뜨렸다.

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 바이트에서 골프를 쳤다 :

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)

입력은 해양에 '~', 육지에 'X', 경계에 'o'를 사용하는 단일 문자열입니다. ( 'X'를 사용하면 '=='대신 '>'의 바이트가 절약됩니다)

댓글이 적은 골프 버전 :

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가 수정되었습니다. (이전 답변을 삭제해야합니까?)
RootTwo

좋은! (예, 이전 답변을 삭제해야합니다. 누구나보고 싶다면 게시물의 개정 내역을 볼 수 있습니다.)
DLosc

5

C # 7-414 369 327 바이트

편집 : 1D 루핑, 컴퓨팅 ij즉시 전환

편집 : 입력 방법 변경, 조회 테이블 축소 및 잘 정의 된 초기 경계로 전환 ... 마지막 외부 for 루프에서 무의미한 공간을 제거했습니다.

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;}}

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

전체 프로그램은 표준에 입력을 받아 표준 출력에 인쇄, 용도 #, .o. 각 셀에 대해 '프로파일'(8 방향 이상의 거리 (편의상 9 번째 계산으로 보이지만 항상 그렇습니다 0)) 을 계산하고 이들 각각의 최대 값을 기록한 다음 전체 맵을 작성합니다. 아래에 주석이 달린 코드는 모두 작동하는 방식을 설명합니다.

멸종에서 기러기 구하기에 대한 나의 대답에 따르면 , 이것은 섬을 경계하는 가장 작은 팔각형 (가장 큰 지역을 가진 유효한 circumnavigation)을 생성합니다.

참고 : 내 인생에서 한 번은 현재 10 년 동안 무언가를 사용하고 있으며이 코드는 C # 7을 컴파일해야합니다. C # 7이 없으면 코드에 명확하게 표시되어있는 한 줄을 바꿔야합니다.

사용법 및 출력 예 :

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

형식화 및 주석 처리 된 코드 :

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

가장 큰 팔각형? 또는 가장 작은?
Sarge Borsch

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