หมากฮอสจีนเคลื่อนไหวที่ยาวที่สุด


12

ในหมากฮอสจีนหมากสามารถเคลื่อนที่โดยการกระโดดข้ามหมากอื่นหรือโดยการเรียงลำดับของการกระโดด งานของคุณคือการหาลำดับฮ็อปที่ยาวที่สุดเท่าที่จะเป็นไปได้

อินพุต

ลำดับของ 121 ศูนย์หรือแต่ละอันแสดงถึงตำแหน่งบนกระดาน ศูนย์หมายถึงสถานที่ว่างเปล่า หนึ่งหมายถึงสถานที่ที่ถูกครอบครอง ตำแหน่งที่ระบุไว้จากซ้ายไปขวา; บนลงล่าง ตัวอย่างเช่นอินพุตของการตั้งค่านี้จะเป็น

1011110011000001000000000000000000000000100000000001000000000000000000000000000001000000000000000000000001000001100111111

คำอธิบาย:

1สถานที่บนสุดถูกครอบครองโดยชิ้นสีเขียวเพื่อให้หลักแรกในการป้อนข้อมูลเป็น แถวที่สองมีตำแหน่งว่างหนึ่งตำแหน่งจากนั้นหนึ่งตำแหน่งที่ว่างดังนั้นจึง01มาถัดไป 111แถวที่สามคือทั้งหมดที่ครอบครองดังนั้น แถวที่สี่มีสองและสองช่องว่างครอบครองว่างเปล่า (ไปทางซ้ายไปขวา) 0011ดังนั้น แล้วก็มาถึงห้า0'S, A 1และเจ็ด0' s สำหรับแถวถัดไปและอื่น ๆ

เช่นเดียวกับการตั้งค่านั้นมีมุมที่ชี้ขึ้น อาจมีจำนวนชิ้นบนกระดาน (จาก 1 ถึง 121) โปรดทราบว่าชิ้นส่วนของสีที่ต่างกันจะไม่แสดงแตกต่างกัน

เอาท์พุต

ความยาวสูงสุดของการกระโดดตามกฎหมายโดยใช้ชิ้นส่วนใด ๆ บนกระดาน คุณไม่สามารถเยี่ยมชมสถานที่เดียวกันมากกว่าหนึ่งครั้ง (รวมถึงตำแหน่งเริ่มต้นและตำแหน่งสุดท้าย) อย่างไรก็ตามคุณอาจกระโดดข้ามสิ่งเดียวกันมากกว่าหนึ่งครั้ง 0ถ้าไม่มีการฟ้อนรำตามกฎหมายเอาท์พุท อย่าพิจารณาว่ามีการย้ายแบบ non-hop ตามกฎหมายหรือไม่

3ยกตัวอย่างเช่นการส่งออกที่จะติดตั้งที่อธิบายข้างต้นคือ

อินพุตและเอาต์พุตอาจทำได้ผ่าน stdin และ stdout ผ่านอาร์กิวเมนต์บรรทัดคำสั่งผ่านการเรียกใช้ฟังก์ชันหรือวิธีการอื่นที่คล้ายคลึงกัน

กรณีทดสอบ

การป้อนข้อมูล:

0100000010000000000000000100000000000000000000000000000001010010000000000000000000000101000000000000000000100000000100001

เอาท์พุท: 0(ไม่มีสองชิ้นติดกัน)


การป้อนข้อมูล:

0000000000111100000000011100000000011000000000100000000000000000000000000000000000000000000000000000000000000000000000000

เอาต์พุต: 1(การตั้งค่าเริ่มต้นสำหรับผู้เล่นหนึ่งคนที่มุมบนซ้าย)


ฉันเล่นกับป้าที่ดีของฉัน เราทั้งคู่ค่อนข้างดี นี่คือความท้าทายที่น่าสนใจ
cjfaure

1
บางทีคุณควรระบุเพิ่มเติมเกี่ยวกับวิธีการจัดเก็บอินพุต / บิตใดไปที่
TheDoctor

คุณสามารถ "กระโดดข้าม" ส่วนไหนได้บ้าง วิธีที่แม่ของฉันและฉันเคยเล่นคุณสามารถกระโดดข้ามท่อนใดก็ได้ในหนึ่งใน 6 ทิศทางไกล ๆ (ไปยังจุดที่ตรงข้ามของชิ้นที่คุณกระโดดข้าม) ตราบใดที่ไม่มีส่วนใดขวางทาง เส้นทางสำหรับการกระโดดนั้น คนอื่นเล่นว่าคุณสามารถกระโดดข้ามสิ่งที่อยู่ติดกันได้เท่านั้น
Joe Z.

1
@TheDoctor ฉันเพิ่มคำอธิบายรายละเอียดเพิ่มเติม
Ypnypn

คุณช่วยอธิบายรายละเอียดได้ไหม: ฉันได้รับอนุญาตให้ดำรงตำแหน่งเดิมสองครั้งหรือไม่? ฉันคิดว่าฉันไม่สามารถวนซ้ำได้ไม่ จำกัด แต่ถ้าฉันสามารถตีตำแหน่งที่เคลื่อนที่ไปทางซ้ายขวาจากนั้นก็กดอีกครั้งจากนั้นเลื่อนไปทางซ้ายไปทางขวาอีกครั้ง
Devon Parsons

คำตอบ:


1

Perl, 345 322

แก้ไข: golfed เล็กน้อย

กรณีทดสอบเพิ่มเติมจะดี แต่ตอนนี้ดูเหมือนว่าจะใช้งานได้ ฉันจะเพิ่มความคิดเห็นในภายหลังหากจำเป็น ด้วยการขึ้นบรรทัดใหม่และการเยื้องเพื่อให้อ่านง่าย:

$_=<>;
$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

งานเหล่านั้นใช้ได้ แต่ก็ง่ายเกินไป :-)
2846289

2

C, 262 260

รหัส Golfed ( รหัสการแก้จุดบกพร่องและลบช่องว่างที่ไม่จำเป็นเปลี่ยนจากอินพุตผ่าน 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 ซึ่งมีลักษณะดังนี้เต็มไปด้วยเลขศูนย์เมื่อโปรแกรมเริ่มต้น (ASCII art นี้สร้างขึ้นโดยโปรแกรมที่แก้ไขแล้วและiลูปนับลงด้านล่างศูนย์อยู่ที่มุมล่างขวา):

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

วนiซ้ำวิ่งผ่านบอร์ดนี้สองครั้งโดยใช้ x และ y เพื่อคำนวณว่าสี่เหลี่ยมจัตุรัสเป็นของกระดานหมากรุกจริงหรือไม่ (ต้องใช้ความไม่เท่าเทียมกัน 6 จุดใน x และ y)

ถ้าเป็นเช่นนั้นรอบแรกจะเติมสี่เหลี่ยมให้วาง0(falsy) สำหรับ1(ครอบครอง) และ a 1(ความจริง) สำหรับ a 0(ว่าง) การผกผันนี้มีความสำคัญเนื่องจากสแควร์สนอกขอบเขตทั้งหมดมี 0 อยู่แล้วซึ่งหมายความว่าพวกเขามีลักษณะคล้ายกับสแควร์สที่ถูกครอบครองและเห็นได้ชัดว่าพวกเขาไม่สามารถข้ามไปได้โดยไม่จำเป็นต้องตรวจสอบเฉพาะ

รอบที่สองถ้าสี่เหลี่ยมถูกครอบครอง (มี 0) จะเรียกฟังก์ชันfที่ค้นหาการเคลื่อนไหว

fค้นหาซ้ำในทิศทางที่เป็นไป 6 เข้ารหัสโดย +/- 1 (แนวนอน) +/- 20 (แนวตั้ง) และ +/- 19 (เส้นทแยงมุม) "AST?-,"[k]-64การเข้ารหัสในการแสดงออก เมื่อพบการโจมตีมันจะตั้งค่าเซลล์นั้นเป็น 0 (ถูกครอบครอง) ก่อนที่จะเรียกตัวเองซ้ำแล้วตั้งค่ากลับเป็น 1 (ว่าง) เมื่อฟังก์ชันถูกส่งกลับ ต้องเปลี่ยนค่าของเซลล์ก่อนการเรียกซ้ำเพื่อป้องกันการกระโดดเข้าไปในเซลล์นั้นมากกว่าหนึ่งครั้ง

รหัสไม่ได้รับการตอบ

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.