숲길


9

당신의 비참한 카누 타기 후에 , 당신은 강 급류의 끝에 폭포에서 떨어지게되었다. 카누는 폭발했지만 폭발 후에도 살아 남았습니다. 그러나 당신의 강 여행은지도에서 완전히 벗어났습니다. 당신은 이제 숲 한가운데서 길을 잃었습니다. 운 좋게도 여전히 프로그래밍 기술을 보유하고 있으므로 프로그램을 나무 옆면에 새겨서 숲을 통과하는 길을 찾을 수 있습니다. 그러나 트리에는 표면적이 많지 않으므로 프로그램을 최대한 짧게 만들어야합니다.

숲은 nn( n > 5단지 소문자 문자로 구성됩니다 문자) 광장 a-z. 예제 숲 :

anehcienwlndm
baneiryeivown
bnabncmxlriru
anhahirrnrauc
riwuafuvocvnc
riwnbaueibnxz
hyirorairener
ruwiiwuauawoe
qnnvcizdaiehr
iefyioeorauvi
quoeuroenraib
cuivoaisdfuae
efoiebnxmcsua

이 포리스트에는 a왼쪽 위 모서리에서 오른쪽 아래 모서리 까지이 문자를 가로 지르는 대각선 문자가 있음을 알 수 있습니다. 이것은 숲을 통과하는 "경로"입니다. 당신의 임무는 단일 경로를 찾을 수있는 프로그램을 작성하는 것입니다. 이제이 과제에서 "경로"를 의미하는 것을 더 구체적으로 설명하겠습니다.

이 도전에서 "경로"는 다음과 같이 생성되었을 수있는 것과 비슷한 선으로 정의됩니다. Bresenham 알고리즘 되지만 다음과 같은 추가 요구 사항이 있습니다.

  • 줄은 6 자 이상이어야합니다
  • 줄의 각 공선 (완전히 인접한) 문자 그룹 길이는 같아야합니다 .
  • 숲의 한쪽 가장자리에서 시작하여 반대쪽 가장자리에서 끝납니다 (참조 여기 내 의견을 )

두 번째 요구 사항을보다 명확하게 설명하려면 다음 줄을 고려하십시오.

aaa
   aaa
      aaa
         aaa
            aaa

이 줄은 동일 선상 문자 "세그먼트"로 구성되며 각 문자는 정확히 3 자입니다. 경로로 규정됩니다. 이제이 줄을 고려하십시오.

a
 aa
   a
    aa
      a
       aa

이 줄은 정확히 같은 길이의 문자가 아닌 동일 선상 "세그먼트"로 구성됩니다 (일부 문자는 1 자 길이이고 일부는 2 자임). 따라서 이것은 경로로 적합하지 않습니다.

포리스트 맵이 제공된 프로그램에서 경로에 사용 된 문자를 식별합니다. 입력은 편리한 것이 무엇이든됩니다 (예 : 명령 행 인수, STDIN prompt(), 등). 변수로 사전 초기화 할 수 없습니다. 입력의 첫 번째 부분은 n포리스트의 크기를 나타내는 단일 정수 입니다 (포리스트는 항상 정사각형 임). 그 후에는 공백이 있고 전체 문자열이 단일 문자열입니다. 예를 들어 예제 포리스트는 다음과 같이 입력으로 표시됩니다.

13  anehcienwlndmbaneiryeivownbnabncmxlriruanhahirrnraucriwuafuvocvncriwnbaueibnxzhyirorairenerruwiiwuauawoeqnnvcizdaiehriefyioeorauviquoeuroenraibcuivoaisdfuaeefoiebnxmcsua

이에 대한 출력은 다음과 같습니다.

a

경로는 문자를 사용하여 형성되기 때문 a입니다. 포리스트에는 경로가 하나만 있습니다. 이것은 코드 골프이므로 문자 수가 가장 적습니다. 궁금한 점이 있으면 의견을 물어보십시오.


경로가 여러 개인 경우 어떻게합니까?
Eric Tressler

지정된 포리스트에는 경로가 하나만있을 것입니다. 이를 반영하여 사양을 편집하겠습니다.
absinthe

경로 문자가 경로에 속하지 않는 다른 곳에서 사용될 수 있습니까?
Martin Ender

예제 포리스트에는 아마도 그 내용이 포함되어 있습니다. 예제 숲에서이 라인의 첫 번째 a는 경로 anhahirrnrauc
Spade

@ MartinBüttner 예. 그러나 그들은 어느 시점에서든 같은 편지로 만들어진 두 가지 경로가 아닙니다.
압생트

답변:


3

APL (Dyalog 14) (70)

⎕ML←3⋄Z/⍨1=≢¨Z←∪¨(↓⍉F),(↓F),{(⍳≢⍵)⌷¨↓⍵}¨(⊂F),⊂⌽F←⊃{⍵⍴⍨2/⍎⍺}/I⊂⍨' '≠I←⍞

설명:

  • ⎕ML←3:로 설정 ML하면 3의미 는 APL2 의미를 갖습니다.
  • I←⍞: 키보드에서 줄을 읽고 저장합니다 I
  • I⊂⍨' '≠I: I공간에서 분리
  • {...}/ :이 함수를 결과 문자열 두 개에 적용합니다.
    • 2/⍎⍺: 왼쪽 인수를 평가하고 두 번 복제하여 행렬 크기를 지정합니다.
    • ⍵⍴⍨: 해당 크기를 사용하여 올바른 인수의 형식을 지정하십시오.
  • F←⊃: 박스를 개봉하여 보관하십시오 F.
  • {(⍳≢⍵)⌷¨↓⍵}¨(⊂F),⊂⌽F: 모두에서 각 행 : 대각선을 취득 F하고 ⌽F(수직 미러F ), X는 행 번호이고 X 열에서의 값을 얻을
  • (↓⍉F),(↓F),:의 행과 열을 얻는다 F
  • Z←∪¨: 각 행, 열 및 대각선에서 고유 한 값을 찾아에 저장하십시오 Z.

'숲'은 직사각형이므로 유효한 경로가 있으면 경로 문자 인 하나의 문자만으로 구성됩니다.

  • Z/⍨1=≢¨Z: Z하나의 요소 만 있는 하위 배열을 가져옵니다 .

유효한 모든 경로의 문자가 표시되지만 중요하지 않은 경로 만 있어야합니다.


4

루아 - 506 - 380 바이트

나는 당신이 당신의 잘 생각 된 도전에 대한 제출을받지 못해서 다소 안타까워서 함께 던졌습니다. 당신이 제공 한 정보로부터 경로가 가지고 있어야하는 최소한의 구별 가능한 특성을 유추하는 것은 재미있었습니다. 나는 그것이 옳았 으면 좋겠다 ... 그리고 올바르게 구현했다.

a=io.read"*l"n=a:match("%d+")+0 m=a:match"[a-z]+"o=""for i=1,n do for k=1,n^2,n do o=o..m:sub(i+k-1,i+k-1)end end q={m,o}for g=1,n^2 do for u=1,2 do l=q[u]:sub(g,g)for r=1,n do i=1 t=0 e=0 while i do s,e=q[u]:find(l:rep(r),e+1)if s then x=s-(e-s)-i-1 print(s,i,r,n,r)if x==n or x==n-2 or t==0 then t=t+1 i=s end else i=nil end end if t*r==n then print(l)os.exit()end end end end

다음과 같이 테스트 할 수 있습니다.

lua divisorPath.lua "input"

난폭 한 도전자가 나타나면 코드를 가치있게 활용 해 보겠습니다.

업데이트 : 우리 위로 올라올 사람들을 기리기 위해 골프를 쳤다. 내가있는 동안 오른쪽에서 왼쪽으로가는 경로를 인식하도록 코드를 수정해야했습니다. 죄송합니다.


3

MATLAB-270 자

다음은 x포리스트 문자열을 인수로 받아들이고 지정된 규칙에 따라 포리스트를 통해 유효한 "경로"를 나타내는 문자를 반환 하는 함수 를 정의합니다 .

function F=x(s),A=sscanf(s,'%d%s');n=A(1);A=reshape(A(2:end),n,n);for c=A(:)',B=A==c;for i=1:n,if~mod(n,i),C=[kron(eye(i),ones(n/i,1)),zeros(n,n-i)];for j=0:n-i,f=@(B)sum(sum(B&circshift(C,[0,j]))==n;D=fliplr(B);if f(B)|f(B')|f(D)|f(D'),F=char(c);end;end;end;end;end;end

축소되지 않은 버전은

function F = x(s)
    A = sscanf( s, '%d %s' );
    n = A(1);
    A = reshape( A(2:end), n,n );
    for c = A(:)'
        B = A==c;
        for i = 1:n
            if ~mod( n, i )
                C = [kron( eye(i), ones( n/i,1 ) ), zeros( n,n-i )];
                for j = 0:n-i
                    f = @(B) sum(sum( B & circshift( C, [0 j] ))) == n;
                    D = fliplr(B);
                    if f(B) | f(B') | f(D) | f(D')
                        F = char(c);
                    end
                end
            end
        end
    end
end

기본 전제는 가능한 모든 유효한 경로에 대해 부울 마스크를 구성하고 행렬의 인덱스 함수가 ​​마스크를 포함하는 모든 문자를 반환하는 것입니다. 이를 위해 수직 또는 위에서 아래로 백 슬래시 모양의 마스크 만 만들어 지지만 포리스트 매트릭스는 4 가지 방향 (동일성, 대칭 이동, 90 ° 회전, 90 ° 회전)에서 모두 비교됩니다.

이 함수는 모든에 대해 실행됩니다 n. 명령 행에서 호출되는 예는 다음과 같습니다.

x('13 anehcienwlndmbaneiryeivownbnabncmxlriruanhahirrnraucriwuafuvocvncriwnbaueibnxzhyirorairenerruwiiwuauawoeqnnvcizdaiehriefyioeorauviquoeuroenraibcuivoaisdfuaeefoiebnxmcsua')

ans =

    a

3

파이썬 - 384 325 275

이 알고리즘은 기본적으로 일치하는 문자가 있는지 행렬의 첫 번째 행과 마지막 행을 확인한 다음 각 선분의 길이를 계산합니다.

012345
------
aaVaaa|0
aaVaaa|1
aaaVaa|2
aaaVaa|3
aaaaVa|4
aaaaVa|5

위의 예에서 :
첫 번째 행의 V는 인덱스 2에 있고 마지막 행의 V는 인덱스 4에 있습니다.
따라서 각 선분의 길이는 n / (4-2) +1 = 2이고 n = 6입니다. .

그런 다음 줄이 유효한지 확인합니다.

왼쪽에서 오른쪽으로 경로를 찾기 위해 행을 열로 바꾸고 동일한 작업을 다시 수행합니다.

편집 : 270에 도달 할 수 없습니다 (아마도 파이썬과 망할 들여 쓰기!)

n,m=raw_input().split()
n,r=int(n),range
t=r(n)
a=[m[i:i+n]for i in r(0,n*n,n)]
for v in a,["".join([a[i][j]for i in t])for j in t]:
 for i in t:
  for j in t:
   p=1-2*(j-i<0);d,c=p*(j-i)+1,v[0][i]
   if 6<=sum([v[z][i+(z/(n/d))*p*(n%d==0)]==c for z in t])==n:print c;exit()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.