중국 체커 가장 긴 움직임


12

에서 중국어 체커 , 조각은 다른 조각을 통해 호핑에 의해 또는 홉 시퀀스를하여 이동할 수 있습니다. 당신의 임무는 가능한 가장 긴 홉 시퀀스를 찾는 것입니다.

입력

121 개의 0 또는 1의 시퀀스로 각각 보드 위의 위치를 ​​나타냅니다. 0은 장소가 비어 있음을 의미합니다. 하나는 장소가 점유되었음을 의미합니다. 위치는 왼쪽에서 오른쪽으로 나열됩니다. 위에서 아래로. 예를 들어,의 입력 이 설정은

1011110011000001000000000000000000000000100000000001000000000000000000000000000001000000000000000000000001000001100111111

설명:

맨 위 자리는 녹색 조각으로 채워져 있으므로 입력의 첫 번째 숫자는 1입니다. 두 번째 행에는 빈 위치가 하나 있고 점유 된 위치가 하나 있으므로 01다음에옵니다. 세 번째 행은 모두 차지 111합니다. 네 번째 행에는 두 개의 빈 공간과 두 개의 점유 공간이 있습니다 (왼쪽에서 오른쪽으로 이동) 0011. 그런 다음 다음 행에 5 0, a 1및 7이옵니다 0.

해당 설정과 마찬가지로 똑바로 위를 향하는 모서리가 있습니다. 보드에는 여러 개의 조각이있을 수 있습니다 (1에서 121까지). 다른 색상의 조각은 다르게 표현되지 않습니다.

산출

보드의 모든 부분을 사용하는 리갈 홉의 최대 길이입니다. 같은 장소를 두 번 이상 방문 할 수 없습니다 (시작 및 끝 위치 포함). 그러나 같은 조각을 두 번 이상 뛰어 넘을 수 있습니다. 유효한 홉이 없으면 output을 출력하십시오 0. 합법적 인 비홉 이동이 있는지 고려하지 마십시오.

예를 들어, 위에서 설명한 설정으로의 출력은 3입니다.

입력 및 출력은 stdin 및 stdout, 명령 행 인수, 함수 호출 또는 유사한 메소드를 통해 수행 될 수 있습니다.

테스트 사례

입력:

0100000010000000000000000100000000000000000000000000000001010010000000000000000000000101000000000000000000100000000100001

출력 : 0(두 조각이 서로 옆에 있지 않음)


입력:

0000000000111100000000011100000000011000000000100000000000000000000000000000000000000000000000000000000000000000000000000

출력 : 1(왼쪽 상단 모서리에있는 한 명의 플레이어에 대한 초기 설정)


나는 나의 이모와 함께 이것을한다; 우리 둘 다 합리적으로 좋습니다. 이것은 흥미로운 도전이다.
cjfaure

1
입력이 어떻게 저장되고 어떤 비트가 어디로 가는지에 대해 더 자세히 지정해야 할 것입니다.
TheDoctor

어떤 조각을 "홉핑"할 수 있습니까? 엄마와 내가 연주하는 방식에 따라, 조각이없는 한 6 조각 중 어느 방향 으로든 멀리 떨어진 한 조각을 뛰어 넘을 수 있습니다. 그 홉의 경로. 다른 사람들은 인접한 조각 위로 뛰어 다닐 수 있다고 말합니다.
Joe Z.

1
@ TheDoctor 더 자세한 설명을 추가했습니다.
Ypnypn

세부 사항을 명확히 할 수 있습니까? 같은 위치를 두 번 차지할 수 있습니까? 무한 반복 할 수 없다고 가정하지만 왼쪽에서 오른쪽으로 이동하는 위치를 쳤다가 나중에 왼쪽에서 오른쪽으로 이동하면 다시 가능성이 열립니다.
데본 파슨스

답변:


1

345 322

편집 : 약간 골프.

더 많은 테스트 사례가 좋을 것이지만 지금은 작동하는 것처럼 보입니다. 필요한 경우 나중에 의견을 추가하겠습니다. 가독성을위한 줄 바꿈 및 들여 쓰기

$_=<>;
$s=2x185;
substr$s,(4,22,unpack'C5(A3)*','(:H[n129148166184202220243262281300')[$i++],0,$_ 
    for unpack A.join A,1..4,13,12,11,10,9..13,4,3,2,1;
$_=$s;
sub f{
    my(@a,%h)=@_;
    $h{$_}++&&return for@a;
    $-+=$#a>$-;
    $s=~/^.{$a[0]}$_/&&f($+[1],@a)
        for map{("(?=.{$_}1.{$_}(0))","(?<=(0).{$_}1.{$_}.)")}0,17,18
}
f$+[0]while/1/g;
print$-

몇 가지 테스트 사례를 추가했습니다.
Ypnypn

그것들은 정상적으로 작동하지만 너무 쉽습니다 :-).
user2846289

2

C, 262 260

골프 코드 (디버깅 코드 및 불필요한 공백 제거. stdin을 통한 입력에서 명령 행을 통한 입력으로 변경되었으며 변수 i를 선언 할 수있는 기회를 활용했습니다. 최신 편집 : 코드는 for루프의 대괄호로 이동하여 두 개의 세미콜론을 저장했습니다.)

t[420],j,l,x,y;f(p,d){int z,q,k;for(k=6;k--;t[q]&!t[p+z]?t[q]=0,f(q,d+1),t[q]=1:0)z="AST?-,"[k]-64,q=p+z*2;l=d>l?d:l;}main(int i,char**s){for(i=840;i--;x>3&y>5&x+y<23|x<13&y<15&x+y>13?i>420?t[i-420]=49-s[1][j++]:t[i]||f(i,0):0)x=i%20,y=i/20%21;printf("%d",l);}

설명

이것은 20x21 보드에 의존하며 프로그램이 시작될 때 처음에는 0으로 채워집니다 (이 ASCII 아트는 프로그램의 수정 된 버전에 의해 생성되었으며 i루프가 아래쪽으로 내려감에 따라 0은 오른쪽 하단 모서리에 있음).

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

ix와 y를 사용하여 정사각형이 실제로 바둑판에 속하는지 여부를 계산하기 위해 루프 가이 보드를 두 번 실행됩니다 (여기서 x와 y에 6 개의 별도 부등식이 필요합니다).

만약 그렇다면, 그것은 라운드 첫 시간은 사각형, 퍼팅 채우고 0A의 (falsy)을 1(점유)와 1A의 (truthy) 0(빈)을. 모든 범위를 벗어난 사각형에는 이미 0이 포함되어 있기 때문에이 반전은 중요합니다. 즉, 점유 된 사각형과 유사하며 특정 검사가 필요하지 않고 뛰어 넘을 수 없습니다.

두 번째 라운드는 사각형이 점유되면 (0 포함) f이동을 검색 하는 함수 를 호출합니다 .

f식에서 인코딩 된 +/- 1 (수평), +/- 20 (수직) 및 +/- 19 (대각선)으로 인코딩 된 6 가지 가능한 방향으로 재귀 적으로 검색합니다 "AST?-,"[k]-64. 적중을 찾으면 재귀 적으로 호출하기 전에 해당 셀을 0 (점유)으로 설정 한 다음 함수가 리턴 될 때 다시 1 (비어 있음)로 설정합니다. 해당 셀에 두 번 이상 호핑되지 않도록 재귀 호출 전에 셀 값을 변경해야합니다.

Ungolfed 코드

char s[999];                           //input string.
t[420],i,j,l,x,y;                      //t=board. i=board counter, j=input counter. l=length of longest hop found so far.

f(p,d){                                //p=position, d= recursion depth.
  //printf("%d,%d ",p,d);              //debug code: uncomment to show the nodes visited.
  int k,z,q;                           //k=counter,z=displacement,q=destination
  for(k=6;k--;)                        //for each direction
    z="AST?-,"[k]-64,                  //z=direction
    q=p+z*2,                           //q=destination cell
    t[q]&!t[p+z]?                      //if destination cell is empty (and not out of bounds) and intervening cell is full
      t[q]=0,f(q,d+1),t[q]=1           //mark destination cell as full, recurse, then mark it as empty again.
      :0;
  l=d>l?d:l;                           //if d exceeds the max recorded recursion depth, update l
}

main(){
  gets(s);                             //get input
  for(i=840;i--;)                      //cycle twice through t
    x=i%20,                            //get x
    y=i/20%21,                         //and y coordinates
    x>3&y>5&x+y<23|x<13&y<15&x+y>13?   //if they are in the bounds of the board
      i>420?
        t[i-420]=49-s[j++]             //first time through the array put 0 for a 1 and a 1 for a 0 ('1'=ASCII49)
        :t[i]||f(i,0)                  //second time, if t[i]=0,call f(). 
       //,puts("")                     //puts() formats debug output to 1 line per in-bounds cell of the board
      :0;
  printf("%d",l);                      //print output
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.