-63 Bytes dank @Arnauld. Beeindruckend.
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
Probieren Sie es online!
Erstens ein Dank an Arnauld, dessen Antwort mir die Inspiration gab, tiefer zu graben. Ich habe mich sehr bemüht, mit meinen Algorithmen originell zu sein, obwohl ich absichtlich einen Teil meines Codes geändert habe, um dieselben Variablen wie Arnauld zu verwenden, damit der Code einfacher verglichen werden kann.
Suche nach leeren Feldern
Die Suche nach Kreaturen ist:
- Initialisieren Sie die Liste der Kacheln mit Kachel 1 auf 0,0
- Rekursiv:
- Suche nach einem leeren Hexfeld, das zur Vollendung der Kreatur benötigt wird
- Wenn ein leeres Hex gefunden wurde
- Füge jede Art von Plättchen 0,1,2 hinzu, um das Feld zu leeren und den Fluch zu wiederholen
- Wird kein leeres Hex gefunden
- Wenn die Kreatur die richtige Größe hat und noch nicht im Zoo ist
- Erhöhen Sie die Anzahl der verschiedenen Kreaturen, die von einer gefunden wurden
- Fügen Sie dem Zoo alle Rotationen und Reflexionen der Kreatur hinzu
Die Suche nach leeren Feldern ergab eine interessante Symmetrie. Arnauld entdeckte, dass eine der sechs Richtungen ignoriert werden kann, aber tatsächlich können drei von sechs ignoriert werden!
Hier ist Arnauld's ursprüngliche Richtung und der Kachelschlüssel:
Stellen Sie sich vor, wir beginnen bei Kachel A vom Typ 1 am blauen Punkt. Es scheint, dass wir in d = 0 und d = 5 rekursieren müssen. Unabhängig davon, welches Plättchen in d = 0 platziert ist, wird es mit Sicherheit einen Ausgang in d = 4 haben, der dasselbe Feld wie der Ausgang in A in d = 5 aufsucht. Das ist Arnauld's Entdeckung und es hat mich zum Nachdenken gebracht.
Beachte das:
- Jedes Plättchen mit einem Ausgang in d = 0 hat einen Ausgang in d = 5
- Jedes Plättchen mit einem Ausgang in d = 2 hat einen Ausgang in d = 1
Jedes Plättchen mit einem Ausgang in d = 4 hat einen Ausgang in d = 3
Jede Kachel, die von d = 0 eingegeben werden kann, hat einen Ausgang in d = 4
- Jede Kachel, die von d = 2 eingegeben werden kann, hat einen Ausgang in d = 0
- Jedes Plättchen, das von d = 4 eingegeben werden kann, hat einen Ausgang in d = 2
Dies bedeutet, dass wir nur die Richtungen 0,2,4 berücksichtigen müssen. Alle Ausgänge in den Richtungen 1,3,5 können ignoriert werden, da die in den Richtungen 1,3,5 erreichbaren Felder stattdessen von einem benachbarten Feld aus mit den Richtungen 0,2 oder 4 erreicht werden können.
Wie cool ist das!?
Relabelled Richtungen
Also beschrifte ich die Richtungen und Kacheln wie folgt neu (Arnauld's Bild bearbeitet):
Jetzt haben wir die folgende Beziehung zwischen Kacheln, Ein- und Ausgängen:
| 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
Ausgänge sind also: d + t == 2? (4-t)% 3: 2-t und 2 * t% 3
Sechseckige Rotationen und Reflexionen
Für Rotationen und Reflexionen habe ich mich entschieden, die hexagonalen Achsenkoordinaten x, y anstelle der Würfelkoordinaten x, y, z zu verwenden.
-1,2 0,2 1,2 2,2
0,1 1,1 2,1
0,0 1,0 2,0 3,0
In diesem System waren die Rotation und Reflektion einfacher als ich erwartet hatte:
120 Rotation: x=-x-y y=x t=(t+1)%3
Reflection: x=-x-y y=y t=(t*2)%3
Um alle Kombinationen zu erhalten, die ich durchgeführt habe: rot, rot, rot, reflektieren, rot, rot
Code (ursprünglich 480 Byte)
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
)
Code (Arnauld 417 Byte)
Arnauld übermittelte freundlicherweise eine 63-Byte-Speicherung, die Tricks verwendete, die mich einige Zeit gekostet haben, um meinen Kopf herumzuwickeln. Da es viele interessante Änderungen gibt, dachte ich, ich würde seinen Code unten einfügen (ich habe meine Kommentare hinzugefügt), damit er meiner Version gegenübergestellt werden kann.
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 unterstützen." - Wenn dies eine Anforderung für die Ausführungsgeschwindigkeit ist, verwenden Sie bitte Code-Challenge anstelle von Code-Golf . Letzteres bezieht sich auf eine reine Byte-Optimierungsaufgabe.