-63 ไบต์ขอบคุณ @Arnauld ว้าว.
n=>(E=(x,y,d,k,h)=>V[k=[x+=1-(d%=3),y+=~d%3+1,d]]?0:(V[k]=1,h=H.find(h=>h[0]==x&h[1]==y))?(d^(t=2-h[2])?E(x,y,t)||E(x,y,h[2]*2):E(x,y,t+2)):[x,y,0],I=c=>c.map(([x,y,t])=>[x-g(0),y-g(1),t],g=p=>Math.min(...c.map(h=>h[p]))).sort(),S=e=>(V={},e=E(0,0,0))?(--n&&H.pop(H.push(e),S(),S(e[2]=1),S(e[2]=2)),++n):n-1||E[I(c=H)]||[0,0,0,++N,0,0].map(r=>E[I(c=c.map(([x,y,t])=>[-x-y,r?y:x,(r?t*2:t+1)%3]))]=1))(H=[[N=0,0,1]])&&N
ลองออนไลน์!
ประการแรกกลับไปที่ Arnauld ซึ่งคำตอบให้แรงบันดาลใจแก่ฉันที่จะขุดลึกลงไป ฉันพยายามอย่างหนักที่จะเป็นต้นฉบับของอัลกอริทึมของฉันแม้ว่าฉันตั้งใจเปลี่ยนรหัสบางส่วนของฉันเพื่อใช้ตัวแปรเดียวกับ Arnauld เพื่อให้รหัสสามารถเปรียบเทียบได้ง่ายขึ้น
ค้นหา hexes ที่ว่างเปล่า
การค้นหาสิ่งมีชีวิตคือ:
- เริ่มต้นรายการของกระเบื้องด้วยไพ่ 1 ที่ 0,0
- ซ้ำ:
- ค้นหา hex ที่ว่างเปล่าที่จำเป็นเพื่อให้สิ่งมีชีวิต
- หากพบ hex ที่ว่างเปล่า
- เพิ่ม tile แต่ละประเภท 0,1,2 ไปที่ hex ที่ว่างเปล่าและเรียกคืน
- หากไม่พบฐานสิบหกที่ว่างเปล่า
- หากสิ่งมีชีวิตมีขนาดที่ถูกต้องและไม่ได้อยู่ในสวนสัตว์
- จำนวนที่เพิ่มขึ้นของสิ่งมีชีวิตที่แตกต่างพบโดยหนึ่ง
- เพิ่มการหมุนทั้งหมดและการสะท้อนกลับของสิ่งมีชีวิตในสวนสัตว์
การค้นหา hexes ว่างเปล่าเปิดโปงสมมาตรที่น่าสนใจ Arnauld ค้นพบว่าหนึ่งในหกทิศทางนั้นอาจถูกละเว้น
นี่คือทิศทางดั้งเดิมของ Arnauld และปุ่มตัวต่อ:
ลองจินตนาการว่าเราเริ่มต้นที่ไทล์ A ของประเภท 1 ที่จุดสีน้ำเงิน ดูเหมือนว่าเราจะต้องจ่ายคืนใน d = 0 และ d = 5 อย่างไรก็ตามกระเบื้องใดก็ตามที่อยู่ใน d = 0 มันจะมีทางออกใน d = 4 ซึ่งจะไปที่ฐานสิบหกเดียวกันกับออกจากกระเบื้อง A ใน d = 5 นั่นคือการค้นพบของ Arnauld และมันเป็นสิ่งที่ทำให้ฉันเริ่มคิด
สังเกตว่า:
ซึ่งหมายความว่าเราจะต้องพิจารณาเส้นทาง 0,2,4 เท่านั้น ทางออกใด ๆ ในทิศทาง 1,3,5 สามารถละเว้นได้เพราะ hexes เข้าถึงได้ในทิศทาง 1,3,5 สามารถเข้าถึงได้จากฐานสิบหกที่อยู่ติดกันโดยใช้ทิศทาง 0,2 หรือ 4
มันเจ๋งแค่ไหน!?
ทิศทาง relabelled
ดังนั้นฉันจึงติดฉลากทิศทางและไทล์แบบนี้ (แก้ไขรูปภาพของ Arnauld):
ตอนนี้เรามีความสัมพันธ์ต่อไปนี้ระหว่างไทล์รายการและออก:
| t=0 | t=1 | t=2
----+-------+-------+-------
d=0 | 0,2 | 1,2 | 2
d=1 | 0,2 | 0 | 0,1
d=2 | 1 | 1,2 | 0,1
ดังนั้นทางออกคือ: d + t == 2? (4-t)% 3: 2-t และ 2 * t% 3
การหมุนและการสะท้อนกลับหกเหลี่ยม
สำหรับการหมุนและการสะท้อนกลับฉันตัดสินใจลองพิกัดแกน x, y หกเหลี่ยมแทนพิกัด x, y, z cube
-1,2 0,2 1,2 2,2
0,1 1,1 2,1
0,0 1,0 2,0 3,0
ในระบบนี้การหมุนและการสะท้อนนั้นง่ายกว่าที่ฉันคาดไว้:
120 Rotation: x=-x-y y=x t=(t+1)%3
Reflection: x=-x-y y=y t=(t*2)%3
ในการรับชุดค่าผสมทั้งหมดที่ฉันแสดง: rot, rot, rot, reflect, rot, rot
รหัส (Original 480 ไบต์)
f=n=>(
// H:list of filled hexes [x,y,tile] during search for a complete creature
// N:number of distinct creatures of size n
// B:record of all orientations of all creatures already found
H=[[0,0,1]],N=0,B={},
// E: find an empty hex required to complete creature starting in direction d from x,y
E=(x,y,d,k,h)=>(
x+=1-d,
y+=1-(d+1)%3,
// V: list of visited hexes during this search in E
V[k=[x,y,d]] ?
0
: (V[k]=1, h=H.find(h=>h[0]==x&&h[1]==y)) ?
// this hex is filled, so continue search in 1 or 2 directions
(d==2-h[2] ? E(x,y,(4-h[2])%3) : (E(x,y,2-h[2]) || E(x,y,h[2]*2%3)))
: [x,y,0] // return the empty hex
),
// I: construct unique identifier for creature c by moving it so x>=0 and y>=0
I=c=>(
M=[0,1].map(p=>Math.min(...c.map(h=>h[p]))),
c.map(([x,y,t])=>[x-M[0],y-M[1],t]).sort()
),
// A: add complete creature c to B
A=c=>{
n==1&&!B[I(c)]&&(
// creature is correct size and is not already in B
N++,
[0,0,0,1,0,0].map(
// Add all rotations and reflections of creature into B
// '0' marks a rotation, '1' marks a (vertical) reflection
// rotation: x=-x-y y=x t=(t+1)%3
// reflection: x=-x-y y=y t=(t*2)%3
r=>B[I(c=c.map(([x,y,t])=>[-x-y,r?y:x,(r?t*2:t+1)%3]))]=1)
)
},
// S: recursively search for complete creatures starting with hexes H
S=e=>{
V={};
(e=E(0,0,0)) ?
// e is a required empty hex, so try filling it with tiles 0,1,2
(--n && (H.push(e),S(),S(e[2]=1),S(e[2]=2),H.pop()), ++n)
: A(H) // creature is complete, so add it to B
},
S(),
N
)
รหัส (Arnauld 417 ไบต์)
Arnauld กรุณาส่งการประหยัด 63 ไบต์ซึ่งใช้เทคนิคที่ใช้เวลาค่อนข้างนานในการห่อหัวของฉัน เนื่องจากมีการแก้ไขที่น่าสนใจมากมายฉันคิดว่าฉันจะใส่รหัสของเขาด้านล่าง (ฉันได้เพิ่มความคิดเห็นของฉัน) เพื่อให้สามารถเปรียบเทียบกับเวอร์ชันของฉันได้
f=n=>(
// E:find an empty hex required to complete creature starting in direction d from x,y
E=(x,y,d,k,h)=>
V[k=[x+=1-(d%=3),y+=~d%3+1,d]] ?
0
:(V[k]=1,h=H.find(h=>h[0]==x&h[1]==y)) ?
(d^(t=2-h[2]) ? E(x,y,t) || E(x,y,h[2]*2) : E(x,y,t+2))
:[x,y,0],
// I: construct unique identifier for creature c by moving it so x>=0 and y>=0
I=c=>c.map(([x,y,t])=>[x-g(0),y-g(1),t],g=p=>Math.min(...c.map(h=>h[p]))).sort(),
// S: recursively search for complete creatures starting with hexes H
S=e=>
(V={},e=E(0,0,0)) ?
(--n&&H.pop(H.push(e),S(),S(e[2]=1),S(e[2]=2)),++n)
:n-1
||E[I(c=H)]
// creature is the correct size and has not been seen before
// so record all rotations and reflections of creature in E[]
||[0,0,0,++N,0,0].map(r=>E[I(c=c.map(([x,y,t])=>[-x-y,r?y:x,(r?t*2:t+1)%3]))]=1)
)
// This wonderfully confusing syntax initializes globals and calls S()
(H=[[N=0,0,1]]) && N
n=10
TIO ได้" - หากเป็นความต้องการความเร็วในการประมวลผลโปรดใช้ความท้าทายของโค้ดแทนcode-golfซึ่งหมายถึงภารกิจการเพิ่มประสิทธิภาพไบต์ที่แท้จริง