그리드는 곡선이 될 수 있습니다. 당신의 기간은 얼마나 되나요?


12

곡선의 일부를 나타내며 빈 공간을 나타내며 다른 문자는 사용하지 않는 H 높이의 텍스트 격자에 의해 W 너비의 W 넓이에 단순 하고 개방 된 2 차원 곡선을 묘사하는 것을 고려하십시오 .X.

모든 그리드 공간에는 8 개의 인접한 그리드 공간 인 Moore 인근이 있습니다. 경계를 벗어난 그리드 공간은 비어있는 것으로 간주됩니다.

그리드에 정확히 하나의 OR이 있으면 그리드에 다음이있는 경우 둘 이상인 경우에 커브 가 포함 됩니다 .X X

  • 정확히 두 개 X는 이웃이 하나뿐입니다 X. 이들은 커브의 끝점입니다.
  • 모든 X엔드 포인트의 이웃 정확히 두 이외 X의. 이들은 대부분의 곡선을 형성합니다.

예를 들어 W = 9이고 H = 4 인이 그리드에는 곡선이 포함됩니다.

....X....
.X.X.X.X.
X..X..X.X
.XX.....X

마찬가지로이 그리드 (W = 4, H = 3)에는 곡선이 있습니다.

....  .X..  ....  ....  .X.X
....  X..X  ..X.  XX..  X.X.
..X.  .XX.  .X..  ....  ....

그러나이 그리드에는 곡선이 없습니다.

....  .XX.  ...X  XX..  ....  X.X.
....  X..X  ..XX  XX..  .X.X  .X..
....  .XX.  .X..  ....  ...X  X.X.

이웃하는 모든 쌍 사이의 거리를 합하여 곡선의 길이를 찾을 수 있습니다 X.

  • 두 개의 직교하는 Xs 사이의 거리는 1 단위입니다.

    XX
    X
    X
  • 두 개의 대각선으로 인접한 Xs 사이의 거리는 √2 단위입니다.

    X.
    .X
    .X
    X.

예를 들어, 그리드에서 커브의 길이

XXX.
...X
..X.

로 시각화 할 수 있습니다

길이 예

그래서 우리는 그것이 1 + 1 + √2 + √2 = 4.828427임을 알 수 있습니다 ...

하나만있는 곡선의 길이 X는 0입니다.

그리드가 곡선을 형성하지 않으면 길이가 잘 정의되지 않습니다.

도전

Xs와 .s 의 텍스트 그리드가 주어지면 포함 된 커브의 길이를 출력 -1하거나 Null그리드에 커브가 없음을 나타내는 또는와 같은 것을 출력 하십시오.

입력의 경우는 이외의 문자를 사용할 수 X.원하는 경우, 필요한 경우 H와 W는 입력으로 취할 수있다. 문자열 대신 1과 0으로 채워진 중첩 목록 또는 행렬로 입력해도 좋습니다.

곡선 길이에 대한 float 또는 두 개의 정수 A와 B를 출력 할 수 있습니다 length = A + B*√2.

바이트 단위의 가장 짧은 코드가 이깁니다.

테스트 사례

XXX.
...X
..X.
2 + 2*√2 = 4.828427...

....X....
.X.X.X.X.
X..X..X.X
.XX.....X
3 + 8*√2 = 14.313708...

....
....
..X.
0 + 0*√2 = 0

.X..
X..X
.XX.
1 + 3*√2 = 5.242640...

....
..X.
.X..
0 + 1*√2 = 1.414213...

....
XX..
....
1 + 0*√2 = 1

.X.X
X.X.
....
0 + 3*√2 = 4.242640...

....
....
....
....
-1

.XX.
X..X
.XX.
-1

...X
..XX
.X..
-1

....
.X.X
...X
-1

X.X.
.X..
X.X.
-1

솔버가 곡선이없는 그리드 (m, n≥0에 대해 m + n * sqrt (2) 형식이 아닌 일관된 값)가없는 그리드에 대한 출력 형식을 선택할 수 있도록하는 것이 좋습니다.
Greg Martin

@Greg 괜찮습니다. 완료
캘빈의 취미

[x.x,...,.x.]유효한 곡선이 아닌가?
Magic Octopus Urn

@ carusocomputing 올바른
캘빈의 취미

답변:


3

MATL , 52 51 바이트

t2Y6~Z+*ssGt3Y6Z+*tt1=z2=wssGzqE=*Gz1=+?}_q]ssy-h2/

입력은 0과 1의 행렬입니다.

출력은 B다음 A. 비 곡선은 음수를 나타 A냅니다.

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 .

설명

곡선의 길이를 계산하는 데는 두 개의 2D 컨벌루션 1이 사용됩니다 . 하나는 무어 마스크를 사용하고 다른 하나는 대각선 이웃 만 포함하는 마스크를 사용합니다. 결과는 입력 크기가 동일한 두 개의 행렬이며 각각 MD 로 표시됩니다 . M 은 각 점에 대한 총 이웃 수를 제공하는 반면, D 는 대각선 이웃 수를 제공합니다.

곡선에 속하지 않는 점을 버리려면 MD 의 결과를 필터링해야합니다. 또한 "인접 이웃"은 대칭 관계이므로 곡선의 각 점은 두 번 계산되므로 2로 나눠야합니다.

커브가 유효한지 결정하는 것이 예상보다 번거 롭습니다. 이를 위해 코드는 세 가지 조건을 테스트합니다.

  1. M 의 개수는 같 2습니까? (즉, 하나의 이웃과 정확히 두 점이 있습니까?)
  2. M의 총합이 입력 곡선의 포인트 수에서 2마이너스 2? (조건 1과 함께, 이것은 두 값을 제외한 M의 0이 아닌 모든 값이 같은지 테스트합니다 2)
  3. 입력 커브에 단일 점이 있습니까?

조건 1과 2가 참이거나 조건 3이 참이면 곡선이 유효합니다.

t       % Implicit input matrix of zeros and ones. Duplicate
2Y6~    % Push [1 0 1; 0 0 0; 1 0 1]
Z+      % 2D convolution, keeping size
*       % Multiply to zero out results for non-curve points. Gives matrix D
ss      % Sum of matrix D
Gt      % Push input again wtice
3Y6     % Push [1 1 1; 1 0 1; 1 1 1]
Z+      % 2D convolution, keeping size
*       % Multiply to zero out results for non-curve points. Gives matrix M
tt      % Duplicate twice
1=z     % Number of ones
2=      % Does it equal 2? This is condition 1
wss     % Swap. Sum of matrix
G       % Push input again
zqE     % Number of nonzeros values minus 1, and then multiplied by 2
=       % Are they equal? This is condition 2
*       % Multiply. This is a logical AND of conditions 1 and 2
G       % Push input again
z1=     % Does it contain exactly one nonzero value? This is condition 3
+       % Add. This is a logical OR with condition 3
?}      % If result was false
  _q    %   Negate and subtract 1. This makes sure we get a negative value
]       % End
ss      % Sum of matrix M
y       % Duplicate sum of matrix D from below
-       % Subtract
h       % Concatenate horizontally
2/      % Divide by 2. Implicitly display

1 컨볼 루션은 성공의 열쇠 입니다.


1

파이썬 3 , 316 315 311 바이트

나는 이것이 모든 경우를 다룬다 고 생각한다. 적어도 테스트 사례가 작동합니다.

또한 가장자리 케이스를 다루는 시작 부분에 골프를 치기에는 여전히 많은 것이 있습니다.

def f(d,R,C):
 s=sum;d=[0]*(C+2),*[[0,*r,0]for r in d],[0]*(C+2);o=-1,0,1;k=[[[(1,0),(0,1)][i*j]for i in o for j in o if d[r+i][c+j]and i|j]for c in range(1,-~C)for r in range(1,-~R)if d[r][c]];w=[x/2for x in map(s,zip(*s(k,[])))]or[0,0];print([w,-1][s(w)!=s([s(z)for z in d])-1or[len(t)for t in k].count(1)>2])

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

작동 방식 :

  1. d,R,C 1. 커브가 1이고 배경이 0 인 목록 목록, 2. 행 및 열 수
  2. 전후에 0의 행과 전후에 0의 열을 삽입 d하여 2d 배열의 가장자리에 대해 걱정할 필요가 없습니다.
  3. 2d 배열의 1마다 이웃을 1로 스캔하고 관계가 대각선이면 (1,0)을 목록에 추가하고, 그렇지 않으면 (0,1)을 추가하십시오
  4. 모든 튜플을 합하면 (n, m)은 대각선과 비대 각 이웃의 수를 각각 나타냅니다.
  5. 관계 수가 정확히 1에서 1을 뺀 수인지 확인하십시오. 그렇지 않으면 곡선이 아닙니다.

누락 된 사례를 지적 해 주신 @Helka Homba에게 감사합니다. 골프 팁을위한 @TuukkaX와 @Trelzevir에게 감사합니다.


같은 외모는 d=[[1,0,1],[0,1,0],[1,0,1]]여기 (추가 테스트 케이스)를 실패합니다.
Calvin 's Hobbies

@HelkaHomba 당신 말이 맞아요. 고마워요! (안타깝게도 더 많은 바이트로)
nile

1
s=sum4 바이트를 저장합니다.
Trelzevir

0

Mathematica, 153150 바이트

Switch[Sort[Join@@BlockMap[If[#[[2,2]]<1,Nothing,Tr[Tr/@#]]&,#~ArrayPad~1,{3,3},1]],{1},0,{2,2,3...},1/.#~ComponentMeasurements~"PolygonalLength",_,]&

0s는 .s, 1s 는 2d 배열을 취합니다 X. Null비 곡선에 대한 출력 .

1/.#~ComponentMeasurements~"PolygonalLength"&

Mathematica에는이를 위해 45 바이트가 내장되어 있지만, 비 곡선에 대해서는 일부 숫자를, 입력에 대해서는 1 / sqrt (2)를 출력 {{1}}합니다. 이 비용을 수정하면 105 바이트 (골프 가능)

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