숲길


9

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

숲은 n 로 n( 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.