Railway circuit: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(Added Go)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(45 intermediate revisions by 12 users not shown)
Line 1:
{{draft task}}
'''Railway circuit'''
 
;Railway circuit:
Given n sections of curve tracks, each one being an arc of 30° of radius R, the goal is to build and count all possible different railway circuits.
Given   '''n'''   sections of curve tracks,   each one being an arc of   '''30°'''   of radius   '''R'''.
 
The goal is to build and count all possible different railway circuits.
'''Constraints''' :
 
 
* n = 12 + k*4 (k = 0, 1 , ...)
;Constraints:
* The circuit must be a closed, connected graph, and the last arc must joint the first one
*   '''n''' = 12 + k*4     (k = 0, 1,  ...)
* Duplicates, either by symmetry, translation, reflexion or rotation must be eliminated.
*   The circuit must be a closed, connected graph, and the last arc must join the first one
* Paths may overlap or cross each other.
*   Duplicates, either by symmetry, translation, reflexion, or rotation must be eliminated.
* All tracks must be used.
*   Paths may overlap or cross each other.
*   All tracks must be used.
 
''';Illustrations''' : http://www.echolalie.org/echolisp/duplo.html
http://www.echolalie.org/echolisp/duplo.html
 
''';Task:'''
Write a function which counts and displays all possible circuits   '''Cn'''   for   '''n''' = 12, 16, 20.
 
Write a function which counts and displays all possible circuits Cn for n = 12, 16 , 20. Extra credit for   '''n''' = 24, 28, ... 48     (no display, only counts). A circuit Cn will be displayed as a list, or sequence of n Right=1/Left=-1 turns.
 
A circuit   '''Cn'''   will be displayed as a list, or sequence of   '''n'''   Right=1/Left=-1 turns.
Example:
 
;Examples:
C12 = (1,1,1,1,1,1,1,1,1,1,1,1) or C12 = (-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1)
:::: C12 = (1,1,1,1,1,1,1,1,1,1,1,1)               and
:::: C12 = (-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1)
 
''';Straight tracks (extra-extra credit)''':
Suppose we have   '''m''' = k*2   sections of straight tracks, each of length   L.
 
Such a circuit is denoted   '''Cn,m'''
Suppose we have m = k*2 sections of straight tracks, each of length L. Such a circuit is denoted Cn,m . A circuit is a sequence of +1,-1, or 0 = straight move. Count the number of circuits Cn,m with n same as above and m = 2 to 8 .
 
A circuit is a sequence of   +1,   -1,   or   0 = straight move.
 
Count the number of circuits   '''Cn,m'''   with   '''n'''   same as above and   '''m''' = 2  to  8
<br><br>
 
=={{header|11l}}==
{{trans|Kotlin}}
 
<syntaxhighlight lang="11l">
-V
RIGHT = 1
LEFT = -1
STRAIGHT = 0
 
F normalize(tracks)
V a = tracks.map(tr -> ‘abc’[tr + 1]).join(‘’)
 
V norm = a
L 0 .< tracks.len
I a < norm
norm = a
a = a[1..]‘’a[0]
 
R norm
 
F full_circle_straight(tracks, nStraight)
I nStraight == 0
R 1B
 
I sum(tracks.map(i -> Int(i == :STRAIGHT))) != nStraight
R 0B
 
V straight = [0] * 12
V i = 0
V idx = 0
L i < tracks.len & idx >= 0
I tracks[i] == :STRAIGHT
straight[idx % 12]++
idx += tracks[i]
i++
 
R !(any((0.<6).map(i -> @straight[i] != @straight[i + 6]))
& any((0.<8).map(i -> @straight[i] != @straight[i + 4])))
 
F full_circle_right(tracks)
I sum(tracks) * 30 % 360 != 0
R 0B
 
V rTurns = [0] * 12
V i = 0
V idx = 0
L i < tracks.len & idx >= 0
I tracks[i] == :RIGHT
rTurns[idx % 12]++
idx += tracks[i]
i++
 
R !(any((0.<6).map(i -> @rTurns[i] != @rTurns[i + 6]))
& any((0.<8).map(i -> @rTurns[i] != @rTurns[i + 4])))
 
T PermutationsGen
[Int] indices, choices
carry = 0
 
F (numPositions, choices)
.indices = [0] * numPositions
.choices = copy(choices)
 
F next()
.carry = 1
 
V i = 1
L i < .indices.len & .carry > 0
.indices[i] += .carry
.carry = 0
I .indices[i] == .choices.len
.carry = 1
.indices[i] = 0
i++
 
R .indices.map(i -> @.choices[i])
 
F has_next()
R .carry != 1
 
F get_permutations_gen(nCurved, nStraight)
assert((nCurved + nStraight - 12) % 4 == 0, ‘input must be 12 + k * 4’)
 
V trackTypes = [:RIGHT, :LEFT]
I nStraight != 0
I nCurved == 12
trackTypes = [:RIGHT, :STRAIGHT]
E
trackTypes = [:RIGHT, :LEFT, :STRAIGHT]
 
R PermutationsGen(nCurved + nStraight, trackTypes)
 
F report(sol, numC, numS)
print("\n#. solution(s) for C#.,#. ".format(sol.len, numC, numS))
I numC <= 20
L(tracks) sorted(sol.values())
L(track) tracks
print(‘#2 ’.format(track), end' ‘’)
print()
 
F circuits(nCurved, nStraight)
[String = [Int]] solutions
 
V gen = get_permutations_gen(nCurved, nStraight)
L gen.has_next()
V tracks = gen.next()
I !full_circle_straight(tracks, nStraight)
L.continue
I !full_circle_right(tracks)
L.continue
solutions[normalize(tracks)] = tracks
 
report(solutions, nCurved, nStraight)
 
L(n) (12..24).step(4)
circuits(n, 0)
circuits(12, 4)
</syntaxhighlight>
 
{{out}}
<pre>
 
1 solution(s) for C12,0
1 1 1 1 1 1 1 1 1 1 1 1
 
1 solution(s) for C16,0
1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1
 
6 solution(s) for C20,0
1 1 1 1 -1 1 1 1 1 -1 1 1 1 1 -1 1 1 1 1 -1
1 1 1 1 1 -1 1 1 1 -1 1 1 1 1 1 -1 1 1 1 -1
1 1 1 1 1 1 -1 1 1 -1 1 1 1 1 1 1 -1 1 1 -1
1 1 1 1 1 1 1 -1 1 -1 1 1 1 1 1 1 1 -1 1 -1
1 1 1 1 1 1 1 -1 1 1 -1 1 1 1 1 1 1 1 -1 -1
1 1 1 1 1 1 1 1 -1 -1 1 1 1 1 1 1 1 1 -1 -1
 
40 solution(s) for C24,0
 
4 solution(s) for C12,4
1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0
1 1 1 1 0 1 1 0 1 1 1 1 0 1 1 0
1 1 1 1 1 0 1 0 1 1 1 1 1 0 1 0
1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0
</pre>
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
;; R is turn counter in right direction
;; The nb of right turns in direction i
Line 131 ⟶ 291:
(printf "Number of circuits C%d,%d : %d" maxn straight (vector-length *circuits*)))
(when (< (vector-length *circuits*) 20) (for-each writeln *circuits*)))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 168 ⟶ 328:
=={{header|Go}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 367 ⟶ 527:
}
circuits(12, 4)
}</langsyntaxhighlight>
 
{{out}}
Line 397 ⟶ 557:
1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0
</pre>
 
=={{header|J}}==
Implementation (could be further optimized0:<syntaxhighlight lang="j">NB. is circuit valid?
vrwc=: {{ */1=({:,1++/)*/\^j.1r6p1*y }}"1
 
NB. canonical form for circuit:
crwc=: {{ {.\:~,/(i.#y)|."0 1/(,|.)y,:-y }}"1
 
NB. all valid railway circuits with y 30 degree curves
rwc=: {{
r=. EMPTY
h=. -:y
sfx=. (]/.~ 2|+/"1)#:i.2^h
for_pfx. (-h){."1 #:i.2^_3+h do. p=.2|+/pfx
r=. r,~.crwc (#~ vrwc) _1^pfx,"1 p{sfx
end.
'SLR'{~~.r
}}
 
NB. all valid railway circuits with y 30 degree curves and x straight segments
rwcs=: {{
r=. EMPTY
h=. -:y+x
sfx=. (h#3)#:i.3^h
for_pfx. sfx do.
r=. r,~.crwc (#~ vrwc) (#~ x= 0 +/ .="1]) 0 1 _1{~pfx,"1 sfx
end.
'SLR'{~~.r
}}</syntaxhighlight>
 
Task examples:<syntaxhighlight lang="j"> rwc 12
LLLLLLLLLLLL
rwc 16
LLLLLLLRLLLLLLLR
rwc 20
LLLLLLLLRRLLLLLLLLRR
LLLLLLLRLLRLLLLLLLRR
LLLLLLLRLRLLLLLLLRLR
LLLLLLRLLRLLLLLLRLLR
LLLLLRLLLRLLLLLRLLLR
LLLLRLLLLRLLLLRLLLLR
#rwc 24
40
#rwc 28
293
#rwc 32
2793
4 rwcs 12
LLLLLLSSLLLLLLSS
LLLLLSLSLLLLLSLS
LLLLSLLSLLLLSLLS
LLLSLLLSLLLSLLLS</syntaxhighlight>
 
Symbols:
R: right (-1)
L: left ( 1)
S: straight ( 0)
 
=={{header|Java}}==
{{works with|Java|8}}
<langsyntaxhighlight lang="java">package railwaycircuit;
 
import static java.util.Arrays.stream;
Line 561 ⟶ 778:
return carry != 1;
}
}</langsyntaxhighlight>
<pre>1 solution(s) for C12,0
1 1 1 1 1 1 1 1 1 1 1 1
Line 589 ⟶ 806:
1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0
1 1 1 1 0 1 1 0 1 1 1 1 0 1 1 0
</pre>
 
=={{header|Julia}}==
[[File:Railway_circuit_examples.png|320px]]
<syntaxhighlight lang="julia">
#=
Exhaustive search for complete railway (railroad track) circuits. A valid circuit begins and ends at the
same point faciing in the same direction. Track are either right handed or left handed 30 degree
curves or are straight track that can be placed at -90, 0, or 90 degree angles from starting points.
 
Turns are defined by 1 for right turn, -1 for left turn, 0 for no turn (0 only with straight track)
 
Equivalent circuits are all in the same equivalence group, as follows:
 
The equivalence group of rotational (circular) permutations of the turns vector in product with the
complementation (scalar multiplication by -1) of those turns determines the equivalence group
for a turns vector.
 
So, the equivalence group is composed: (rotational permutations) X (scalar multiplication by -1)
 
There is another factor in equivalence groups not mentioned in the task as of June 2022: __vector reversal__.
If __vector reversal__ is included, (1 -1 1 1 1 -1 -1) is considered to group with (-1 -1 1 1 1 -1 1).
 
Furthermore, if chosen, reversal of the turns vector (not mentioned as a source of symmetry in the task)
is also multiplied in for a larger equivalence group:
 
(rotational permutations) X (scalar multiplication by -1) X (vector reversal)
 
Each unique and valid turn vector is chosen to be the maximum vector in its
equivalence group. All turns vectors must represent a closed path ending in a direction
identical to (mod 2π radians from) its initial vector direction on the plane.
 
Time required for an N turns solution is O(2^N) for curved track and O(3^N) for straight track.
 
Graphic displays of solutions are via a Gtk app and Cairo graphics.
=#
""" Rosetta Code task rosettacode.org/wiki/Railway_circuit. """
 
using Gtk, Cairo
 
""" Point is a 2D point in the plane: type T can be Float64 for this usage """
struct Point{T}
x::T
y::T
end
 
""" add Points as vectors on plane """
Base.:+(p::Point, q::Point) = Point(p.x + q.x, p.y + q.y)
 
""" Tracks align if within absolute tolerance of 1 in 100 (with radius of curvature 1) """
Base.:≈(p::Point, q::Point) =
isapprox(p.x, q.x, atol = 0.01) && isapprox(p.y, q.y, atol = 0.01)
 
""" a curve section 30 degrees is 1/12 of a circle angle or π/6 radians """
const twelvesteps = [Point(sinpi(a / 6), cospi(a / 6)) for a = 1:12]
 
""" a straight section 90 degree angle is 1/4 of a circle angle or π/2 radians """
const foursteps = [Point(sinpi(a / 2), cospi(a / 2)) for a = 1:4]
 
""" Determine if vector `turns` is in an equivalence group with the vector `groupmember` """
function isinequivalencegroup(turns, groupmember, reversals = false)
for i in eachindex(turns)
groupmember == circshift(turns, i - 1) && return true
end
invturns = -1 .* turns
for i in eachindex(invturns)
groupmember == circshift(invturns, i - 1) && return true
end
if reversals
revturns = reverse(turns)
for i in eachindex(revturns)
groupmember == circshift(revturns, i - 1) && return true
end
invturns = -1 .* revturns
for i in eachindex(invturns)
groupmember == circshift(invturns, i - 1) && return true
end
end
return false
end
 
""" get the maximum member of the equivalence group containing vector turns """
function maximumofsymmetries(turns, groupsfound, reversals = false)
maxofgroup = turns
for i in eachindex(turns)
t = circshift(turns, i - 1)
push!(groupsfound, t)
if t > maxofgroup
maxofgroup = t
end
end
invturns = -1 .* turns
for i in eachindex(invturns)
t = circshift(invturns, i - 1)
push!(groupsfound, t)
if t > maxofgroup
maxofgroup = t
end
end
if reversals # [1 -1 1 1] => [1 1 -1 1]
revturns = reverse(turns)
for i in eachindex(revturns)
t = circshift(revturns, i - 1)
push!(groupsfound, t)
if t > maxofgroup
maxofgroup = t
end
end
revinvturns = -1 .* revturns
for i in eachindex(revinvturns)
t = circshift(revinvturns, i - 1)
push!(groupsfound, t)
if t > maxofgroup
maxofgroup = t
end
end
end
return maxofgroup
end
 
""" Returns true if the path of turns returns to starting point, and on that return is
moving in a direction opposite to the starting direction.
"""
function isclosedpath(turns, straight, start = Point(0.0, 0.0))
if sum(turns) % (straight ? 4 : 12) != 0 # turns angle sum must be a multiple of 2π
return false
end
angl, point = 0, start
if straight
for turn in turns
angl += turn
point += foursteps[mod1(angl, 4)]
end
else
for turn in turns
angl += turn
point += twelvesteps[mod1(angl, 12)]
end
end
return point ≈ start
end
 
""" Draw the curves found, display on a Gtk canvas. """
function RailroadLayoutApp(turnsarray, savefilename; straight = false, reversals = false)
win = GtkWindow("Showing $(length(turnsarray)) circuits with $(length(turnsarray[1])) turns ($(reversals ? "excl" : "incl")uding reversed curves)",
720, 1000) |> (can = GtkCanvas())
set_gtk_property!(can, :expand, true)
 
@guarded draw(can) do widget
ctx = getgc(can)
h, w = height(can), width(can)
r = (w + h) / 96
nsquares = length(turnsarray[1])
gridx = isqrt(nsquares)
gridy = (nsquares + gridx - 1) ÷ gridx
x0, y0, = 6r, 6r
for (i, turns) in enumerate(turnsarray)
x, y = x0 + 6 * r * (i % gridx), y0 + 6 * r * ((i - 1) ÷ gridx)
angle = 0
if straight
for turn in turns
# black dot at layout track segment start point
set_source_rgb(ctx, 0, 0, 0)
arc(ctx, x, y, 2, 0, 2π)
fill(ctx)
# red line segment for track
set_source_rgb(ctx, 255, 0, 0)
angle += turn * π/2
newx, newy = x + r * cos(angle), y + r * sin(angle)
move_to(ctx, x, y)
line_to(ctx, newx, newy)
x, y = newx, newy
stroke(ctx)
end
else
for turn in turns
# black dot at layout track segment start point
set_source_rgb(ctx, 0, 0, 0)
arc(ctx, x, y, 2, 0, 2π)
fill(ctx)
# bluegreen dot at center of radius of curvature
set_source_rgb(ctx, 0, 120, 180)
centerangle = (-angle - turn * π/2) % 2π
centerx, centery = x - r * cos(centerangle), y - r * sin(centerangle)
arc(ctx, centerx, centery, 2, 0, 2π)
fill(ctx)
# red curve for track
set_source_rgb(ctx, 255, 0, 0)
centerangle2 = (centerangle + turn * π/6) % 2π
a1, a2 = min(centerangle, centerangle2), max(centerangle, centerangle2)
if a2 - a1 > π
a1, a2 = a2, a1
end
arc(ctx, centerx, centery, r, a1, a2)
stroke(ctx)
# compute x and y of next start point (endppoint of curve just drawn)
x, y = centerx + r * cos(centerangle2), centery + r * sin(centerangle2)
# compute next starting angle
angle -= turn * π/6
end
end
end
end
showall(win)
end
 
"""
function allvalidcircuits(N; verbose = false, straight = false, reversals = true, graphic = true)
 
Count the complete circuits by their equivalence groups. Show the unique highest sorting vectors
from each equivalence group if verbose. Use 30 degree curved track if straight is false, otherwise
straight track. Allow reversed circuits if otherwise in another grouup if reversals is false,
otherwise do not consider reversed order vectors unique. Show graphic representation of the unique
paths if graphic is true.
"""
function allvalidcircuits(N; verbose = false, straight = false, reversals = false, graphic = false)
found = Vector{Vector{Int}}()
groupmembersfound = Set{Vector{Int}}()
println("\nFor N of $N and ", straight ? "straight" : "curved", " track, $(reversals ? "excl" : "incl")uding reversed curves: ")
for i in (straight ? (0:3^N-1) : (0:2^N-1))
turns =
straight ?
[d == 0 ? 0 : (d == 1 ? 1 : -1) for d in digits(i, base = 3, pad = N)] :
[d == 0 ? 1 : -1 for d in digits(i, base = 2, pad = N)]
if isclosedpath(turns, straight) && !(turns in groupmembersfound)
if length(found) == 0 || all(t -> !isinequivalencegroup(turns, t), found)
canon = maximumofsymmetries(turns, groupmembersfound, reversals)
verbose && println(canon)
push!(found, canon)
end
end
end
println("Found $(length(found)) unique valid circuits.")
graphic && @async begin RailroadLayoutApp(deepcopy(found), "N$N.png"; reversals = reversals) end
return found
end
 
# Note 4:2:36 takes a long time, for shorter runs do 4:4:24 here for i
for i = 4:2:36, rev in false:true, str in false:true
str && i > 16 && continue
@time allvalidcircuits(i; verbose = !str && i < 28, reversals = rev, straight = str, graphic = i == 24)
end
</syntaxhighlight>{{out}}
<pre>
For N of 4 and curved track, including reversed curves:
Found 0 unique valid circuits.
0.000907 seconds (70 allocations: 4.461 KiB)
 
For N of 4 and straight track, including reversed curves:
Found 1 unique valid circuits.
0.000675 seconds (209 allocations: 17.836 KiB)
 
For N of 4 and curved track, excluding reversed curves:
Found 0 unique valid circuits.
0.000737 seconds (68 allocations: 4.430 KiB)
 
For N of 4 and straight track, excluding reversed curves:
Found 1 unique valid circuits.
0.000724 seconds (218 allocations: 18.477 KiB)
 
For N of 6 and curved track, including reversed curves:
Found 0 unique valid circuits.
0.000748 seconds (165 allocations: 15.727 KiB)
 
For N of 6 and straight track, including reversed curves:
Found 1 unique valid circuits.
0.001228 seconds (1.51 k allocations: 162.398 KiB)
 
For N of 6 and curved track, excluding reversed curves:
Found 0 unique valid circuits.
0.000816 seconds (164 allocations: 15.430 KiB)
 
For N of 6 and straight track, excluding reversed curves:
Found 1 unique valid circuits.
0.001109 seconds (1.52 k allocations: 164.227 KiB)
 
For N of 8 and curved track, including reversed curves:
Found 0 unique valid circuits.
0.000728 seconds (548 allocations: 65.430 KiB)
 
For N of 8 and straight track, including reversed curves:
Found 7 unique valid circuits.
0.004763 seconds (13.64 k allocations: 1.665 MiB)
 
For N of 8 and curved track, excluding reversed curves:
Found 0 unique valid circuits.
0.000924 seconds (549 allocations: 65.727 KiB)
 
For N of 8 and straight track, excluding reversed curves:
Found 7 unique valid circuits.
0.003679 seconds (13.77 k allocations: 1.680 MiB)
 
For N of 10 and curved track, including reversed curves:
Found 0 unique valid circuits.
0.000959 seconds (2.08 k allocations: 289.430 KiB)
 
For N of 10 and straight track, including reversed curves:
Found 23 unique valid circuits.
0.044344 seconds (123.94 k allocations: 17.029 MiB, 33.72% gc time)
 
For N of 10 and curved track, excluding reversed curves:
Found 0 unique valid circuits.
0.001132 seconds (2.08 k allocations: 289.430 KiB)
 
For N of 10 and straight track, excluding reversed curves:
Found 15 unique valid circuits.
0.027965 seconds (121.00 k allocations: 16.624 MiB)
 
For N of 12 and curved track, including reversed curves:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Found 1 unique valid circuits.
0.004032 seconds (8.37 k allocations: 1.259 MiB)
 
For N of 12 and straight track, including reversed curves:
Found 141 unique valid circuits.
0.308568 seconds (1.31 M allocations: 200.564 MiB, 17.57% gc time)
 
For N of 12 and curved track, excluding reversed curves:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Found 1 unique valid circuits.
0.004644 seconds (8.39 k allocations: 1.262 MiB)
 
For N of 12 and straight track, excluding reversed curves:
Found 95 unique valid circuits.
0.235373 seconds (1.18 M allocations: 180.146 MiB, 13.06% gc time)
 
For N of 14 and curved track, including reversed curves:
Found 0 unique valid circuits.
0.005226 seconds (32.80 k allocations: 5.501 MiB)
 
For N of 14 and straight track, including reversed curves:
Found 871 unique valid circuits.
3.911026 seconds (20.58 M allocations: 3.374 GiB, 15.87% gc time)
 
For N of 14 and curved track, excluding reversed curves:
Found 0 unique valid circuits.
0.007905 seconds (32.80 k allocations: 5.501 MiB)
 
For N of 14 and straight track, excluding reversed curves:
Found 465 unique valid circuits.
2.412965 seconds (12.72 M allocations: 2.086 GiB, 14.93% gc time)
 
For N of 16 and curved track, including reversed curves:
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1]
Found 1 unique valid circuits.
0.013655 seconds (131.30 k allocations: 24.013 MiB)
 
For N of 16 and straight track, including reversed curves:
Found 6045 unique valid circuits.
75.173632 seconds (689.14 M allocations: 123.235 GiB, 22.65% gc time)
 
For N of 16 and curved track, excluding reversed curves:
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1]
Found 1 unique valid circuits.
0.015041 seconds (131.33 k allocations: 24.019 MiB)
 
For N of 16 and straight track, excluding reversed curves:
Found 3217 unique valid circuits.
48.776209 seconds (432.90 M allocations: 77.415 GiB, 21.55% gc time)
 
For N of 18 and curved track, including reversed curves:
[1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1]
Found 1 unique valid circuits.
0.108705 seconds (524.53 k allocations: 104.014 MiB, 10.93% gc time)
 
For N of 18 and curved track, excluding reversed curves:
[1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1]
Found 1 unique valid circuits.
0.098171 seconds (524.57 k allocations: 104.022 MiB, 14.81% gc time)
 
For N of 20 and curved track, including reversed curves:
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1]
Found 6 unique valid circuits.
0.542609 seconds (2.10 M allocations: 448.222 MiB, 16.18% gc time)
 
For N of 20 and curved track, excluding reversed curves:
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1]
Found 6 unique valid circuits.
0.524247 seconds (2.10 M allocations: 448.411 MiB, 17.80% gc time)
 
For N of 22 and curved track, including reversed curves:
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1]
Found 5 unique valid circuits.
2.097615 seconds (8.39 M allocations: 1.875 GiB, 19.04% gc time)
 
For N of 22 and curved track, excluding reversed curves:
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1]
Found 4 unique valid circuits.
2.079754 seconds (8.39 M allocations: 1.875 GiB, 18.72% gc time)
 
For N of 24 and curved track, including reversed curves:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1]
Found 40 unique valid circuits.
8.816823 seconds (33.60 M allocations: 8.010 GiB, 18.48% gc time)
 
For N of 24 and curved track, excluding reversed curves:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1]
Found 27 unique valid circuits.
8.891642 seconds (33.73 M allocations: 8.016 GiB, 18.45% gc time, 1.16% compilation time)
 
For N of 26 and curved track, including reversed curves:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1]
Found 58 unique valid circuits.
36.909355 seconds (134.32 M allocations: 34.024 GiB, 18.53% gc time, 0.04% compilation time)
 
For N of 26 and curved track, excluding reversed curves:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1]
Found 35 unique valid circuits.
36.537159 seconds (134.29 M allocations: 34.017 GiB, 18.66% gc time)
 
For N of 28 and curved track, including reversed curves:
Found 293 unique valid circuits.
152.393778 seconds (539.33 M allocations: 144.659 GiB, 18.92% gc time)
 
For N of 28 and curved track, excluding reversed curves:
Found 174 unique valid circuits.
153.737110 seconds (538.62 M allocations: 144.470 GiB, 18.69% gc time)
 
For N of 30 and curved track, including reversed curves:
Found 670 unique valid circuits.
603.015572 seconds (2.16 G allocations: 611.883 GiB, 19.12% gc time, 0.00% compilation time)
 
For N of 30 and curved track, excluding reversed curves:
Found 357 unique valid circuits.4
588.433178 seconds (2.16 G allocations: 610.226 GiB, 19.45% gc time)
 
For N of 32 and curved track, including reversed curves:
Found 2793 unique valid circuits.
1010.080701 seconds (8.84 G allocations: 2.703 TiB, 14.50% gc time)
 
For N of 32 and curved track, excluding reversed curves:
Found 1485 unique valid circuits.
1333.508776 seconds (8.73 G allocations: 2.669 TiB, 16.66% gc time)
 
For N of 34 and curved track, including reversed curves:
Found 7797 unique valid circuits.
6864.782575 seconds (36.46 G allocations: 11.141 TiB, 18.28% gc time, 0.00% compilation time)
 
For N of 34 and curved track, excluding reversed curves:
Found 3975 unique valid circuits.
5092.741859 seconds (35.46 G allocations: 10.836 TiB, 18.86% gc time, 0.00% compilation time)
 
For N of 36 and curved track, including reversed curves:
Found 30117 unique valid circuits.
45086.603365 seconds (170.55 G allocations: 57.081 TiB, 22.00% gc time)
 
For N of 36 and curved track, excluding reversed curves:
Found 15391 unique valid circuits.
45082.100206 seconds (154.85 G allocations: 51.828 TiB, 21.72% gc time)
</pre>
 
Line 594 ⟶ 1,433:
{{trans|Java}}
It takes several minutes to get up to n = 32. I called it a day after that!
<langsyntaxhighlight lang="scala">// Version 1.2.31
 
const val RIGHT = 1
Line 721 ⟶ 1,560:
for (n in 12..32 step 4) circuits(n, 0)
circuits(12, 4)
}</langsyntaxhighlight>
 
{{out}}
Line 751 ⟶ 1,590:
1 1 1 1 0 1 1 0 1 1 1 1 0 1 1 0
</pre>
 
=={{header|Nim}}==
{{trans|Kotlin}}
Instead of using integers for Left, Straight and Right, I used an enumeration with values -1, 0, 1 and string representations L, S, R.
I avoided to use functions and templates from module <code>sequtils</code>. They are convenient but allocate intermediate sequences which is not good for performance. Using explicit code is a lot more efficient.
 
It took about 2 min 25 s to get the result for a maximum of 32 and 41 min 15 s for a maximum of 36.
 
<syntaxhighlight lang="nim">import algorithm, sequtils, strformat, strutils, sugar, tables
 
type
 
Direction {.pure.} = enum Left = (-1, "L"), Straight = (0, "S"), Right = (1, "R")
 
PermutationsGen = object
indices: seq[int]
choices: seq[Direction]
carry: int
 
 
func initPermutationsGen(numPositions: int; choices: seq[Direction]): PermutationsGen =
result.indices.setLen(numPositions)
result.choices = choices
 
 
func next(pg: var PermutationsGen): seq[Direction] =
pg.carry = 1
# The generator skips the first index, so the result will always start
# with a right turn (0) and we avoid clockwise/counter-clockwise
# duplicate solutions.
var i = 1
while i < pg.indices.len and pg.carry > 0:
pg.indices[i] += pg.carry
pg.carry = 0
if pg.indices[i] == pg.choices.len:
pg.carry = 1
pg.indices[i] = 0
inc i
result.setLen(pg.indices.len)
for i, idx in pg.indices:
result[i] = pg.choices[idx]
 
 
template hasNext(pg: PermutationsGen): bool = pg.carry != 1
 
 
func normalize(tracks: seq[Direction]): string =
let length = tracks.len
var a = collect(newSeq, for val in tracks: $val).join()
 
# Rotate the array and find the lexicographically lowest order
# to allow the hashmap to weed out duplicate solutions.
result = a
for _ in 2..length:
a.rotateLeft(1)
if a < result: result = a
 
 
func fullCircleStraight(tracks: seq[Direction]; nStraight: int): bool =
if nStraight == 0: return true
 
# Do we have the requested number of straight tracks?
if tracks.count(Straight) != nStraight: return false
 
# Check symmetry of straight tracks: i and i + 6, i and i + 4.
var straight: array[12, int]
var i, idx = 0
while i < tracks.len and idx >= 0:
if tracks[i] == Straight: inc straight[idx mod 12]
idx += ord(tracks[i])
inc i
result = true
for i in 0..5:
if straight[i] != straight[i + 6]:
result = false
break
if result: return
result = true
for i in 0..7:
if straight[i] != straight[i + 4]: return false
 
 
func fullCircleRight(tracks: seq[Direction]): bool =
# All tracks need to add up to a multiple of 360.
var s = 0
for dir in tracks: s += ord(dir) * 30
if s mod 360 != 0: return false
 
# Check symmetry of right turns: i and i + 6, i and i + 4.
var rTurns: array[12, int]
var i, idx = 0
while i < tracks.len and idx >= 0:
if tracks[i] == Right: inc rTurns[idx mod 12]
idx += ord(tracks[i])
inc i
result = true
for i in 0..5:
if rTurns[i] != rTurns[i + 6]:
result = false
break
if result: return
result = true
for i in 0..7:
if rTurns[i] != rTurns[i + 4]: return false
 
 
func getPermutationsGen(nCurved, nStraight: int): PermutationsGen =
doAssert (nCurved + nStraight - 12) mod 4 == 0, "input must be 12 + k * 4"
let trackTypes =
if nStraight == 0: @[Right, Left]
elif nCurved == 12: @[Right, Straight]
else: @[Right, Left, Straight]
result = initPermutationsGen(nCurved + nStraight, trackTypes)
 
 
proc report(sol: Table[string, seq[Direction]]; nCurved, nStraight: int) =
let length = sol.len
let plural = if length > 1: "s" else: ""
echo &"\n{length} solution{plural} for C{nCurved},{nStraight}"
if nCurved <= 20:
for track in sol.values:
echo track.join(" ")
 
proc circuits(nCurved, nStraight: Natural) =
var solutions: Table[string, seq[Direction]]
var gen = getPermutationsGen(nCurved, nStraight)
while gen.hasNext():
let tracks = gen.next()
if not fullCircleStraight(tracks, nStraight): continue
if not fullCircleRight(tracks): continue
solutions[tracks.normalize()] = tracks
report(solutions, nCurved, nStraight)
 
for n in countup(12, 36, 4):
circuits(n, 0)
circuits(12, 4)</syntaxhighlight>
 
{{out}}
<pre>1 solution for C12,0
R R R R R R R R R R R R
 
1 solution for C16,0
R R R R R R R L R R R R R R R L
 
6 solutions for C20,0
R R R R R R R L R L R R R R R R R L R L
R R R R R L R R R L R R R R R L R R R L
R R R R R R R R L L R R R R R R R R L L
R R R R R R R L R R L R R R R R R R L L
R R R R R R L R R L R R R R R R L R R L
R R R R L R R R R L R R R R L R R R R L
 
40 solutions for C24,0
 
243 solutions for C28,0
 
2134 solutions for C32,0
 
22938 solutions for C36,0
 
4 solutions for C12,4
R R R R S R R S R R R R S R R S
R R R R R R S S R R R R R R S S
R R R R R S R S R R R R R S R S
R R R S R R R S R R R S R R R S</pre>
 
=={{header|Perl}}==
{{trans|Raku}}
{{libheader|ntheory}}
<syntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
use experimental 'signatures';
use List::Util qw(sum);
use ntheory 'todigits';
 
{
package Point;
use Class::Struct;
struct( x => '$', y => '$',);
}
 
use constant pi => 2 * atan2(1, 0);
use enum qw(False True);
 
my @twelvesteps = map { Point->new( x => sin(pi * $_/6), y => cos(pi * $_/6) ) } 1 .. 12;
my @foursteps = map { Point->new( x => sin(pi * $_/2), y => cos(pi * $_/2) ) } 1 .. 4;
 
sub add ($p, $q) { Point->new( x => $p->x + $q->x , y => $p->y + $q->y) }
 
sub approx_eq ($p, $q) { use constant eps => .0001; abs($p->x - $q->x)<eps and abs($p->y - $q->y)<eps }
 
sub digits($n, $base, $pad=0) {
my @output = reverse todigits($n, $base);
push @output, (0) x ($pad - +@output) if $pad > +@output;
@output
}
 
sub rotate { my($i,@a) = @_; @a[$i .. @a-1, 0 .. $i-1] }
 
sub circularsymmetries(@c) { map { join ' ', rotate($_, @c) } 0 .. $#c }
 
sub addsymmetries($infound, @turns) {
my @allsym;
push @allsym, circularsymmetries(@turns);
push @allsym, circularsymmetries(map { -1 * $_ } @turns);
$$infound{$_} = True for @allsym;
(sort @allsym)[-1]
}
 
sub isclosedpath($straight, @turns) {
my $start = Point->new(x=> 0, y =>0);
return False if sum(@turns) % ($straight ? 4 : 12);
my ($angl, $point) = (0, $start);
for my $turn (@turns) {
$angl += $turn;
$point = add($point, $straight ? $foursteps[$angl % 4] : $twelvesteps[$angl % 12]);
}
approx_eq($point, $start);
}
 
sub allvalidcircuits($N, $doPrint = False, $straight = False) {
my ( @found, %infound );
say "\nFor N of ". $N . ' and ' . ($straight ? 'straight' : 'curved') . ' track:';
for my $i (0 .. ($straight ? 3 : 2)**$N - 1) {
my @turns = $straight ?
map { $_ == 0 ? 0 : ($_ == 1 ? -1 : 1) } digits($i,3,$N) :
map { $_ == 0 ? -1 : 1 } digits($i,2,$N);
if (isclosedpath($straight, @turns) && ! exists $infound{join ' ', @turns} ) {
my $canon = addsymmetries(\%infound, @turns);
push @found, $canon;
}
}
say join "\n", @found if $doPrint;
say "There are " . +@found . ' unique valid circuits.';
@found
}
 
allvalidcircuits($_, True) for 12, 16, 20;
allvalidcircuits($_, True, True) for 4, 6, 8;</syntaxhighlight>
{{out}}
<pre>For N of 12 and curved track:
1 1 1 1 1 1 1 1 1 1 1 1
There are 1 unique valid circuits.
 
For N of 16 and curved track:
1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1
There are 1 unique valid circuits.
 
For N of 20 and curved track:
1 1 1 1 1 1 1 1 -1 -1 1 1 1 1 1 1 1 1 -1 -1
1 1 1 1 1 1 1 -1 1 1 -1 1 1 1 1 1 1 1 -1 -1
1 1 1 1 1 1 1 -1 1 -1 1 1 1 1 1 1 1 -1 1 -1
1 1 1 1 1 1 -1 1 1 -1 1 1 1 1 1 1 -1 1 1 -1
1 1 1 1 1 -1 1 1 1 -1 1 1 1 1 1 -1 1 1 1 -1
1 1 1 1 -1 1 1 1 1 -1 1 1 1 1 -1 1 1 1 1 -1
There are 6 unique valid circuits.
 
For N of 4 and straight track:
1 1 1 1
There are 1 unique valid circuits.
 
For N of 6 and straight track:
1 1 0 1 1 0
There are 1 unique valid circuits.
 
For N of 8 and straight track:
1 1 0 0 1 1 0 0
1 0 1 0 1 0 1 0
1 1 0 1 0 1 1 -1
1 1 1 0 -1 -1 -1 0
1 1 1 1 1 1 1 1
1 1 1 1 -1 -1 -1 -1
1 1 1 -1 1 1 1 -1
There are 7 unique valid circuits.</pre>
 
=={{header|Phix}}==
{{trans|Go}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">right</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">left</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">straight</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">fullCircleStraight</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">tracks</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">nStraight</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">nStraight</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">true</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000080;font-style:italic;">-- check symmetry of straight tracks: i and i + 6, i and i + 4</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">straightTracks</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tracks</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">tracks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">straight</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">stdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
<span style="color: #000000;">straightTracks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">stdx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">idx</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">tracks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">idx</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">any</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">6</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">straightTracks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">!=</span> <span style="color: #000000;">straightTracks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">6</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">any</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">any</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">true</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">any</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">straightTracks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">!=</span> <span style="color: #000000;">straightTracks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">any</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #008080;">not</span> <span style="color: #000000;">any</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">fullCircleRight</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">tracks</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- all tracks need to add up to a multiple of 360, aka 12*30</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">tot</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tracks</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">tot</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">tracks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tot</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000080;font-style:italic;">-- check symmetry of right turns: i and i + 6, i and i + 4</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">rTurns</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tracks</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">tracks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">right</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">rtdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
<span style="color: #000000;">rTurns</span><span style="color: #0000FF;">[</span><span style="color: #000000;">rtdx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">idx</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">tracks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">idx</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">any</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">6</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">rTurns</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">!=</span> <span style="color: #000000;">rTurns</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">6</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">any</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">any</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">true</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">any</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">rTurns</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">!=</span> <span style="color: #000000;">rTurns</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">any</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #008080;">not</span> <span style="color: #000000;">any</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">lc</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">sdx</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tStraight</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">choices</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">indices</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tracks</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">next</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">nStraight</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">/* The generator skips the first index, so the result will always start
with a right turn (0) and we avoid clockwise/counter-clockwise
duplicate solutions. */</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">indices</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ii</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">indices</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ii</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">lc</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">indices</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ii</span>
<span style="color: #000000;">tracks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">choices</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ii</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">tStraight</span> <span style="color: #0000FF;">+=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">ii</span><span style="color: #0000FF;">=</span><span style="color: #000000;">sdx</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">indices</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">tracks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">choices</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">sdx</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">tStraight</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">carry</span> <span style="color: #008080;">or</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">tStraight</span><span style="color: #0000FF;">=</span><span style="color: #000000;">nStraight</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">circuits</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">nCurved</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">nStraight</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">solutions</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">seen</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">(),</span>
<span style="color: #000000;">nCS</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nCurved</span><span style="color: #0000FF;">+</span><span style="color: #000000;">nStraight</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nCS</span><span style="color: #0000FF;">-</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"input must be 12 + k * 4"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">nStraight</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">choices</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">right</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">left</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">choices</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">right</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">straight</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">default</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">choices</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">right</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">left</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">straight</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #000000;">lc</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">choices</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">sdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">straight</span><span style="color: #0000FF;">,</span><span style="color: #000000;">choices</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">tStraight</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #000000;">indices</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">nCS</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">tracks</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">right</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">nCS</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">carry</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">next</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nStraight</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">fullCircleStraight</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tracks</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">nStraight</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">and</span> <span style="color: #000000;">fullCircleRight</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tracks</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">getd_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tracks</span><span style="color: #0000FF;">,</span><span style="color: #000000;">seen</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">solutions</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tracks</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- mark all rotations seen</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">nCS</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tracks</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #000000;">seen</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (data (=true) is ignored)</span>
<span style="color: #000000;">tracks</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tracks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]&</span><span style="color: #000000;">tracks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">destroy_dict</span><span style="color: #0000FF;">(</span><span style="color: #000000;">seen</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ls</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ls</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?</span><span style="color: #008000;">""</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"s"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n%d solution%s for C%d,%d \n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">ls</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">nCurved</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">nStraight</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">nCurved</span> <span style="color: #0000FF;"><=</span> <span style="color: #000000;">20</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">,{</span><span style="color: #004600;">pp_Nest</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">12</span> <span style="color: #008080;">to</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">JS</span><span style="color: #0000FF;">?</span><span style="color: #000000;">20</span><span style="color: #0000FF;">:</span><span style="color: #000000;">28</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">by</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">circuits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">circuits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
1 solution for C12,0
{{1,1,1,1,1,1,1,1,1,1,1,1}}
 
1 solution for C16,0
{{1,-1,1,1,1,1,1,1,1,-1,1,1,1,1,1,1}}
 
6 solutions for C20,0
{{1,-1,1,-1,1,1,1,1,1,1,1,-1,1,-1,1,1,1,1,1,1},
{1,1,-1,-1,1,1,1,1,1,1,1,1,-1,-1,1,1,1,1,1,1},
{1,-1,1,1,-1,1,1,1,1,1,1,1,-1,-1,1,1,1,1,1,1},
{1,-1,1,1,-1,1,1,1,1,1,1,-1,1,1,-1,1,1,1,1,1},
{1,-1,1,1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,1,1,1},
{1,-1,1,1,1,1,-1,1,1,1,1,-1,1,1,1,1,-1,1,1,1}}
 
40 solutions for C24,0
 
243 solutions for C28,0
 
4 solutions for C12,4
{{1,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1},
{1,0,1,0,1,1,1,1,1,0,1,0,1,1,1,1},
{1,0,1,1,0,1,1,1,1,0,1,1,0,1,1,1},
{1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1}}
</pre>
 
=={{header|Python}}==
<syntaxhighlight lang="python">from itertools import count, islice
import numpy as np
from numpy import sin, cos, pi
 
# ANGDIV can't be 2, though
ANGDIV = 12
ANG = 2*pi/ANGDIV
 
def draw_all(sols):
import matplotlib.pyplot as plt
 
def draw_track(ax, s):
turn, xend, yend = 0, [0], [0]
 
for d in s:
x0, y0 = xend[-1], yend[-1]
a = turn*ANG
cs, sn = cos(a), sin(a)
ang = a + d*pi/2
cx, cy = x0 + cos(ang), y0 + sin(ang)
 
da = np.linspace(ang, ang + d*ANG, 10)
xs = cx - cos(da)
ys = cy - sin(da)
ax.plot(xs, ys, 'green' if d == -1 else 'orange')
 
xend.append(xs[-1])
yend.append(ys[-1])
turn += d
 
ax.plot(xend, yend, 'k.', markersize=1)
ax.set_aspect(1)
 
ls = len(sols)
if ls == 0: return
 
w, h = min((abs(w*2 - h*3) + w*h - ls, w, h)
for w, h in ((w, (ls + w - 1)//w)
for w in range(1, ls + 1)))[1:]
 
fig, ax = plt.subplots(h, w, squeeze=False)
for a in ax.ravel(): a.set_axis_off()
 
for i, s in enumerate(sols):
draw_track(ax[i//w, i%w], s)
 
plt.show()
 
 
def match_up(this, that, equal_lr, seen):
if not this or not that: return
 
n = len(this[0][-1])
n2 = n*2
 
l_lo, l_hi, r_lo, r_hi = 0, 0, 0, 0
 
def record(m):
for _ in range(n2):
seen[m] = True
m = (m&1) << (n2 - 1) | (m >> 1)
 
if equal_lr:
m ^= (1<<n2) - 1
for _ in range(n2):
seen[m] = True
m = (m&1) << (n2 - 1) | (m >> 1)
 
l_n, r_n = len(this), len(that)
tol = 1e-3
 
while l_lo < l_n:
while l_hi < l_n and this[l_hi][0] - this[l_lo][0] <= tol:
l_hi += 1
 
while r_lo < r_n and that[r_lo][0] < this[l_lo][0] - tol:
r_lo += 1
 
r_hi = r_lo
while r_hi < r_n and that[r_hi][0] < this[l_lo][0] + tol:
r_hi += 1
 
for a in this[l_lo:l_hi]:
m_left = a[-2]<<n
for b in that[r_lo:r_hi]:
if (m := m_left | b[-2]) not in seen:
if np.abs(a[1] + b[2]) < tol:
record(m)
record(int(f'{m:b}'[::-1], base=2))
yield(a[-1] + b[-1])
 
l_lo, r_lo = l_hi, r_hi
 
def track_combo(left, right):
n = (left + right)//2
n1 = left + right - n
 
alphas = np.exp(1j*ANG*np.arange(ANGDIV))
def half_track(m, n):
turns = tuple(1 - 2*(m>>i & 1) for i in range(n))
rcnt = np.cumsum(turns)%ANGDIV
asum = np.sum(alphas[rcnt])
want = asum/alphas[rcnt[-1]]
return np.abs(asum), asum, want, m, turns
 
res = [[] for _ in range(right + 1)]
for i in range(1<<n):
b = i.bit_count()
if b <= right:
res[b].append(half_track(i, n))
 
for v in res: v.sort()
if n1 == n:
return res, res
 
res1 = [[] for _ in range(right + 1)]
for i in range(1<<n1):
b = i.bit_count()
if b <= right:
res1[b].append(half_track(i, n1))
 
for v in res: v.sort()
return res, res1
 
def railway(n):
seen = {}
 
for l in range(n//2, n + 1):
r = n - l
if not l >= r: continue
 
if (l - r)%ANGDIV == 0:
res_l, res_r = track_combo(l, r)
 
for i, this in enumerate(res_l):
if 2*i < r: continue
that = res_r[r - i]
for s in match_up(this, that, l == r, seen):
yield s
 
sols = []
for i, s in enumerate(railway(30)):
# should show 357 solutions for 30 tracks
print(i + 1, s)
sols.append(s)
 
draw_all(sols[:40])</syntaxhighlight>
 
=={{header|Racket}}==
Line 757 ⟶ 2,201:
Made functional, so builds the track up with lists. A bit more expense spent copying vectors, but this solution avoids mutation (except internally in <code>vector+=</code> . Also got rid of the maximum workload counter.
 
<langsyntaxhighlight lang="racket">#lang racket
 
(define-syntax-rule (vector+= v idx i)
Line 827 ⟶ 2,271:
(gen 20)
(gen 24)
(gen 12 4))</langsyntaxhighlight>
 
{{out}}
Line 857 ⟶ 2,301:
(0 1 1 0 1 1 1 1 0 1 1 0 1 1 1 1)
(0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1)</pre>
 
=={{header|Raku}}==
 
{{trans|Julia}}
<syntaxhighlight lang="raku" line>#!/usr/bin/env raku
 
# 20200406 Raku programming solution
 
class 𝒫 { has ($.x, $.y) } # Point
 
multi infix:<⊞>(𝒫 \p, 𝒫 \q) { 𝒫.bless: x => p.x + q.x , y => p.y + q.y }
multi infix:<≈>(𝒫 \p, 𝒫 \q) { my $*TOLERANCE = .0001; p.x ≅ q.x and p.y ≅ q.y }
 
constant twelvesteps = (1..12).map: { 𝒫.new: x =>sin(π*$_/6), y=>cos(π*$_/6) };
constant foursteps = (1..4).map: { 𝒫.new: x =>sin(π*$_/2), y=>cos(π*$_/2) };
 
sub digits($n!, $base!, $pad=0) {
my @output = $n.base($base).comb.reverse;
@output.append: 0 xx ($pad - +@output) if $pad > +@output;
return @output
} # rough port of https://docs.julialang.org/en/v1/base/numbers/#Base.digits
 
sub addsymmetries(%infound, \turns) {
my @allsym.push: | .&{ (0..^+@$_).map: -> $n {rotate @$_, $n} } for turns, -«turns;
%infound{$_} = True for @allsym;
return @allsym.max
}
 
sub isclosedpath(@turns, \straight, \start= 𝒫.bless: x => 0, y => 0) {
return False unless ( @turns.sum % (straight ?? 4 !! 12) ) == 0;
my ($angl, $point) = (0, start);
for @turns -> $turn {
$angl += $turn;
$point ⊞= straight ?? foursteps[$angl % 4] !! twelvesteps[$angl % 12];
}
return $point ≈ start;
}
 
sub allvalidcircuits(\N, \doPrint=False, \straight=False) {
my ( @found, %infound );
say "\nFor N of ",N," and ", straight ?? "straight" !! "curved", " track: ";
for (straight ?? (0..^3**N) !! (0..^2**N)) -> \i {
my @turns = straight ??
digits(i,3,N).map: { $_ == 0 ?? 0 !! ($_ == 1 ?? -1 !! 1) } !!
digits(i,2,N).map: { $_ == 0 ?? -1 !! 1 } ;
if isclosedpath(@turns, straight) && !(%infound{@turns.Str}:exists) {
my \canon = addsymmetries(%infound, @turns);
say canon if doPrint;
@found.push: canon.Str;
}
}
say "There are ", +@found, " unique valid circuits.";
return @found
}
 
allvalidcircuits($_, $_ < 28) for 12, 16, 20; # 12, 16 … 36
allvalidcircuits($_, $_ < 12, True) for 4, 6, 8; # 4, 6 … 16;</syntaxhighlight>
{{out}}
<pre>For N of 12 and curved track:
[1 1 1 1 1 1 1 1 1 1 1 1]
There are 1 unique valid circuits.
 
For N of 16 and curved track:
[1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1]
There are 1 unique valid circuits.
 
For N of 20 and curved track:
[1 1 1 1 1 1 1 1 -1 -1 1 1 1 1 1 1 1 1 -1 -1]
[1 1 1 1 1 1 1 -1 1 1 -1 1 1 1 1 1 1 1 -1 -1]
[1 1 1 1 1 1 1 -1 1 -1 1 1 1 1 1 1 1 -1 1 -1]
[1 1 1 1 1 1 -1 1 1 -1 1 1 1 1 1 1 -1 1 1 -1]
[1 1 1 1 1 -1 1 1 1 -1 1 1 1 1 1 -1 1 1 1 -1]
[1 1 1 1 -1 1 1 1 1 -1 1 1 1 1 -1 1 1 1 1 -1]
There are 6 unique valid circuits.
 
For N of 4 and straight track:
[1 1 1 1]
There are 1 unique valid circuits.
 
For N of 6 and straight track:
[1 1 0 1 1 0]
There are 1 unique valid circuits.
 
For N of 8 and straight track:
[1 1 0 0 1 1 0 0]
[1 0 1 0 1 0 1 0]
[1 1 0 1 0 1 1 -1]
[1 1 1 0 -1 -1 -1 0]
[1 1 1 1 1 1 1 1]
[1 1 1 1 -1 -1 -1 -1]
[1 1 1 -1 1 1 1 -1]
There are 7 unique valid circuits.</pre>
 
=={{header|Swift}}==
 
{{trans|Kotlin}}
 
<syntaxhighlight lang="swift">enum Track: Int, Hashable {
case left = -1, straight, right
}
 
extension Track: Comparable {
static func < (lhs: Track, rhs: Track) -> Bool {
return lhs.rawValue < rhs.rawValue
}
}
 
func < (lhs: [Track], rhs: [Track]) -> Bool {
for (l, r) in zip(lhs, rhs) where l != r {
return l < r
}
 
return false
}
 
func normalize(_ tracks: [Track]) -> [Track] {
let count = tracks.count
var workingTracks = tracks
var norm = tracks
 
for _ in 0..<count {
if workingTracks < norm {
norm = workingTracks
}
 
let temp = workingTracks[0]
 
for j in 1..<count {
workingTracks[j - 1] = workingTracks[j]
}
 
workingTracks[count - 1] = temp
}
 
return norm
}
 
func fullCircleStraight(tracks: [Track], nStraight: Int) -> Bool {
guard nStraight != 0 else {
return true
}
 
guard tracks.filter({ $0 == .straight }).count == nStraight else {
return false
}
 
var straight = [Int](repeating: 0, count: 12)
var i = 0
var idx = 0
 
while i < tracks.count && idx >= 0 {
if tracks[i] == .straight {
straight[idx % 12] += 1
}
 
idx += tracks[i].rawValue
i += 1
}
 
return !((0...5).contains(where: { straight[$0] != straight[$0 + 6] }) &&
(0...7).contains(where: { straight[$0] != straight[$0 + 4] })
)
}
 
func fullCircleRight(tracks: [Track]) -> Bool {
guard tracks.map({ $0.rawValue * 30 }).reduce(0, +) % 360 == 0 else {
return false
}
 
var rightTurns = [Int](repeating: 0, count: 12)
var i = 0
var idx = 0
 
while i < tracks.count && idx >= 0 {
if tracks[i] == .right {
rightTurns[idx % 12] += 1
}
 
idx += tracks[i].rawValue
i += 1
}
 
return !((0...5).contains(where: { rightTurns[$0] != rightTurns[$0 + 6] }) &&
(0...7).contains(where: { rightTurns[$0] != rightTurns[$0 + 4] })
)
}
 
func circuits(nCurved: Int, nStraight: Int) {
var solutions = Set<[Track]>()
 
for tracks in getPermutationsGen(nCurved: nCurved, nStraight: nStraight)
where fullCircleStraight(tracks: tracks, nStraight: nStraight) && fullCircleRight(tracks: tracks) {
solutions.insert(normalize(tracks))
}
 
report(solutions: solutions, nCurved: nCurved, nStraight: nStraight)
}
 
func getPermutationsGen(nCurved: Int, nStraight: Int) -> PermutationsGen {
precondition((nCurved + nStraight - 12) % 4 == 0, "input must be 12 + k * 4")
 
let trackTypes: [Track]
 
if nStraight == 0 {
trackTypes = [.right, .left]
} else if nCurved == 12 {
trackTypes = [.right, .straight]
} else {
trackTypes = [.right, .left, .straight]
}
 
return PermutationsGen(numPositions: nCurved + nStraight, choices: trackTypes)
}
 
func report(solutions: Set<[Track]>, nCurved: Int, nStraight: Int) {
print("\(solutions.count) solutions for C\(nCurved),\(nStraight)")
 
if nCurved <= 20 {
for tracks in solutions {
for track in tracks {
print(track.rawValue, terminator: " ")
}
 
print()
}
}
}
 
struct PermutationsGen: Sequence, IteratorProtocol {
private let choices: [Track]
private var indices: [Int]
private var sequence: [Track]
private var carry = 0
 
init(numPositions: Int, choices: [Track]) {
self.choices = choices
self.indices = .init(repeating: 0, count: numPositions)
self.sequence = .init(repeating: choices.first!, count: numPositions)
}
 
mutating func next() -> [Track]? {
guard carry != 1 else {
return nil
}
 
carry = 1
var i = 1
 
while i < indices.count && carry > 0 {
indices[i] += carry
carry = 0
 
if indices[i] == choices.count {
carry = 1
indices[i] = 0
}
 
i += 1
}
 
for j in 0..<indices.count {
sequence[j] = choices[indices[j]]
}
 
return sequence
}
}
 
for n in stride(from: 12, through: 32, by: 4) {
circuits(nCurved: n, nStraight: 0)
}
 
circuits(nCurved: 12, nStraight: 4)</syntaxhighlight>
 
{{out}}
 
<pre>1 solutions for C12,0
1 1 1 1 1 1 1 1 1 1 1 1
 
1 solutions for C16,0
-1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1
 
6 solutions for C20,0
-1 1 -1 1 1 1 1 1 1 1 -1 1 -1 1 1 1 1 1 1 1
-1 1 1 -1 1 1 1 1 1 1 -1 1 1 -1 1 1 1 1 1 1
-1 -1 1 1 1 1 1 1 1 1 -1 -1 1 1 1 1 1 1 1 1
-1 1 1 1 -1 1 1 1 1 1 -1 1 1 1 -1 1 1 1 1 1
-1 -1 1 1 1 1 1 1 1 -1 1 1 -1 1 1 1 1 1 1 1
-1 1 1 1 1 -1 1 1 1 1 -1 1 1 1 1 -1 1 1 1 1
 
40 solutions for C24,0
 
243 solutions for C28,0
 
2134 solutions for C32,0
 
4 solutions for C12,4
0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1
0 1 0 1 1 1 1 1 0 1 0 1 1 1 1 1
0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1
0 1 1 0 1 1 1 1 0 1 1 0 1 1 1 1</pre>
 
=={{header|Wren}}==
{{trans|Julia}}
{{libheader|Wren-seq}}
{{libheader|Wren-math}}
Terminal output only.
 
A tough task for the Wren interpreter requiring about 7 minutes 48 seconds to run. Unlike the Julia example, I've not attempted the straight track for N = 16 (which I estimate would take about an hour in isolation) and have not tried to go beyond N = 24.
<syntaxhighlight lang="wren">import "./seq" for Lst
import "./math" for Int, Nums
 
// Returns whether 'a' and 'b' are approximately equal within a tolerance of 'tol'.
var IsApprox = Fn.new { |a, b, tol| (a - b).abs <= tol }
 
// Returns whether a1 < a2 where 'a1' and 'a2' are lists of numbers.
var isLess = Fn.new { |a1, a2|
for (pair in Lst.zip(a1, a2)) {
if (pair[0] > pair[1]) return false
if (pair[0] < pair[1]) return true
}
return a1.count < a2.count
}
 
// Represents a 2D point.
class Point {
construct new(x, y) {
_x = x
_y = y
}
 
x { _x }
y { _y }
 
+(other) { Point.new(this.x + other.x, this.y + other.y) }
 
==(other) { IsApprox.call(this.x, other.x, 0.01) && IsApprox.call(this.y, other.y, 0.01) }
 
toString { "(%(_x), %(_y))" }
}
 
// A curve section 30 degrees is 1/12 of a circle angle or π/6 radians.
var twelveSteps = List.filled(12, null)
for (a in 0..11) twelveSteps[a] = Point.new((Num.pi * (a+1)/6).sin, (Num.pi * (a+1)/6).cos)
 
// A straight section 90 degree angle is 1/4 of a circle angle or π/2 radians.
var fourSteps = List.filled(4, null)
for (a in 0..3) fourSteps[a] = Point.new((Num.pi * (a+1)/2).sin, (Num.pi * (a+1)/2).cos)
 
// Returns whether 'turns' and 'groupMember' are in an equivalence group.
var isInEquivalenceGroup = Fn.new { |turns, groupMember, reversals|
if (Lst.areEqual(groupMember, turns)) return true
var turns2 = turns.toList
for (i in 1...turns.count) {
if (Lst.areEqual(groupMember, Lst.rshift(turns2, 1))) return true
}
var invTurns = turns.map { |e| (e == 0) ? 0 : -e }.toList
if (Lst.areEqual(groupMember, invTurns)) return true
for (i in 1...invTurns.count) {
if (Lst.areEqual(groupMember, Lst.rshift(invTurns, 1))) return true
}
if (reversals) {
var revTurns = turns[-1..0]
if (Lst.areEqual(groupMember, revTurns)) return true
var revTurns2 = revTurns.toList
for (i in 1...revTurns.count) {
if (Lst.areEqual(groupMember, Lst.rshift(revTurns2, 1))) return true
}
invTurns = revTurns.map { |e| (e == 0) ? 0 : -e }.toList
if (Lst.areEqual(groupMember, invTurns)) return true
for (i in 1...invTurns.count) {
if (Lst.areEqual(groupMember, Lst.rshift(invTurns, 1))) return true
}
}
return false
}
 
// Returns the maximum member of the equivalence group containing 'turns'.
var maximumOfSymmetries = Fn.new { |turns, groupsFound, reversals|
var maxOfGroup = turns.toList
for (i in 0...turns.count) {
var t = Lst.rshift(turns.toList, i)
groupsFound[t.toString] = true
if (isLess.call(maxOfGroup, t)) maxOfGroup = t
}
var invTurns = turns.map { |e| (e == 0) ? 0 : -e }
for (i in 0...invTurns.count) {
var t = Lst.rshift(invTurns.toList, i)
groupsFound[t.toString] = true
if (isLess.call(maxOfGroup, t)) maxOfGroup = t
}
if (reversals) {
var revTurns = turns[-1..0]
for (i in 0...revTurns.count) {
var t = Lst.rshift(revTurns.toList, i)
groupsFound[t.toString] = true
if (isLess.call(maxOfGroup, t)) maxOfGroup = t
}
var revInvTurns = revTurns.map { |e| (e == 0) ? 0 : -e }
for (i in 0...revInvTurns.count) {
var t = Lst.rshift(revInvTurns.toList, i)
groupsFound[t.toString] = true
if (isLess.call(maxOfGroup, t)) maxOfGroup = t
}
}
return maxOfGroup
}
 
// Returns true if the path of 'turns' returns to starting point, and on that return is
// moving in a direction opposite to the starting direction.
var isClosedPath = Fn.new { |turns, straight, start|
if ((Nums.sum(turns) % (straight ? 4 : 12)) != 0) return false
var angle = 0
var point = Point.new(start.x, start.y)
if (straight) {
for (turn in turns) {
angle = angle + turn
point = point + fourSteps[angle % 4]
}
} else {
for (turn in turns) {
angle = angle + turn
point = point + twelveSteps[angle % 12]
}
}
return point == start
}
 
// Finds and returns all valid circuits on the following basis.
//
// Count the complete circuits by their equivalence groups. Show the unique
// highest sorting lists from each equivalence group if verbose.
//
// Use 30 degree curved track if straight is false, otherwise straight track.
//
// Allow reversed circuits if otherwise in another grouup if reversals is false,
// otherwise do not consider reversed order lists unique.
var allValidCircuits = Fn.new { |n, verbose, straight, reversals|
var found = []
var groupMembersFound = {}
var t1 = straight ? "straight" : "curved"
var t2 = (reversals ? "excl" : "incl") + "uding reversed curves: "
System.print("\nFor N of %(n) and %(t1) track, %(t2)")
for (i in 0..(straight ? 3.pow(n)-1 : 2.pow(n)-1)) {
var turns
if (straight) {
var digs = Int.digits(i, 3)[-1..0]
if (digs.count < n) digs = digs + ([0] * (n - digs.count))
turns = digs.map { |d| (d == 0) ? 0 : ((d == 1) ? 1 : -1) }.toList
} else {
var digs = Int.digits(i, 2)[-1..0]
if (digs.count < n ) digs = digs + ([0] * (n - digs.count))
turns = digs.map { |d| (d == 0) ? 1 : -1 }.toList
}
if (isClosedPath.call(turns, straight, Point.new(0, 0)) &&
!groupMembersFound.containsKey(turns.toString)) {
if (found.isEmpty || found.all { |t| !isInEquivalenceGroup.call(turns, t, false) }) {
var canon = maximumOfSymmetries.call(turns, groupMembersFound, reversals)
if (verbose) System.print(canon)
found.add(canon)
}
}
}
System.print("Found %(found.count) unique valid circuit(s).")
return found
}
 
var n = 4
while (n <= 24) {
for (rev in [false, true]) {
for (str in [false, true]) {
if (str && n > 14) continue
allValidCircuits.call(n, !str, str, rev)
}
}
n = n + 2
}</syntaxhighlight>
 
{{out}}
<pre>
For N of 4 and curved track, including reversed curves:
Found 0 unique valid circuit(s).
 
For N of 4 and straight track, including reversed curves:
Found 1 unique valid circuit(s).
 
For N of 4 and curved track, excluding reversed curves:
Found 0 unique valid circuit(s).
 
For N of 4 and straight track, excluding reversed curves:
Found 1 unique valid circuit(s).
 
For N of 6 and curved track, including reversed curves:
Found 0 unique valid circuit(s).
 
For N of 6 and straight track, including reversed curves:
Found 1 unique valid circuit(s).
 
For N of 6 and curved track, excluding reversed curves:
Found 0 unique valid circuit(s).
 
For N of 6 and straight track, excluding reversed curves:
Found 1 unique valid circuit(s).
 
For N of 8 and curved track, including reversed curves:
Found 0 unique valid circuit(s).
 
For N of 8 and straight track, including reversed curves:
Found 7 unique valid circuit(s).
 
For N of 8 and curved track, excluding reversed curves:
Found 0 unique valid circuit(s).
 
For N of 8 and straight track, excluding reversed curves:
Found 7 unique valid circuit(s).
 
For N of 10 and curved track, including reversed curves:
Found 0 unique valid circuit(s).
 
For N of 10 and straight track, including reversed curves:
Found 23 unique valid circuit(s).
 
For N of 10 and curved track, excluding reversed curves:
Found 0 unique valid circuit(s).
 
For N of 10 and straight track, excluding reversed curves:
Found 15 unique valid circuit(s).
 
For N of 12 and curved track, including reversed curves:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Found 1 unique valid circuit(s).
 
For N of 12 and straight track, including reversed curves:
Found 141 unique valid circuit(s).
 
For N of 12 and curved track, excluding reversed curves:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Found 1 unique valid circuit(s).
 
For N of 12 and straight track, excluding reversed curves:
Found 95 unique valid circuit(s).
 
For N of 14 and curved track, including reversed curves:
Found 0 unique valid circuit(s).
 
For N of 14 and straight track, including reversed curves:
Found 871 unique valid circuit(s).
 
For N of 14 and curved track, excluding reversed curves:
Found 0 unique valid circuit(s).
 
For N of 14 and straight track, excluding reversed curves:
Found 465 unique valid circuit(s).
 
For N of 16 and curved track, including reversed curves:
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1]
Found 1 unique valid circuit(s).
 
For N of 16 and curved track, excluding reversed curves:
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1]
Found 1 unique valid circuit(s).
 
For N of 18 and curved track, including reversed curves:
[1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1]
Found 1 unique valid circuit(s).
 
For N of 18 and curved track, excluding reversed curves:
[1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1]
Found 1 unique valid circuit(s).
 
For N of 20 and curved track, including reversed curves:
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1]
Found 6 unique valid circuit(s).
 
For N of 20 and curved track, excluding reversed curves:
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1]
Found 6 unique valid circuit(s).
 
For N of 22 and curved track, including reversed curves:
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1]
Found 5 unique valid circuit(s).
 
For N of 22 and curved track, excluding reversed curves:
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1]
Found 4 unique valid circuit(s).
 
For N of 24 and curved track, including reversed curves:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1]
Found 40 unique valid circuit(s).
 
For N of 24 and curved track, excluding reversed curves:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1]
[1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1]
[1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1]
Found 27 unique valid circuit(s).
</pre>
 
=={{header|zkl}}==
{{trans|EchoLisp}}
<langsyntaxhighlight lang="zkl"> // R is turn counter in right direction
// The nb of right turns in direction i
// must be = to nb of right turns in direction i+6 (opposite)
Line 937 ⟶ 3,057:
else println("Number of circuits C%,d,%d : %d".fmt(maxn,straight,_circuits.len()));
if(_circuits.len()<20) _circuits.apply2(T(T("toString",*),"println"));
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">gen(12); println();
gen(16); println();
gen(20); println();
gen(24); println();
gen(12,4);</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits