Babylonian spiral: Difference between revisions

m
→‎{{header|Julia}}: iterator version
m (→‎{{header|Raku}}: rephrase logic, less bracketing)
m (→‎{{header|Julia}}: iterator version)
Line 147:
</pre>
[[File:babylonuanspiral.png]]
 
=== iterator version ===
See Python iterator version.
<syntaxhighlight lang="julia">using Plots
 
struct SquareSums end
 
function Base.iterate(ss::SquareSums, state = (1, Tuple{Int, Int, Int}[]))
i, sums = state
while isempty(sums) || i^2 <= sums[1][1]
push!(sums, (i^2, i, 0))
i += 1
end
sort!(sums)
nextsum, xy = sums[1][1], Tuple{Int, Int}[]
while !isempty(sums) && sums[1][1] == nextsum # pop all vectors with same length
nextsum, a, b = popfirst!(sums)
push!(xy, (a, b))
if a > b
push!(sums, (a^2 + (b + 1)^2, a, b + 1))
end
end
return xy, (i, sums)
end
 
function babylonian_spiral(N)
sqsums = SquareSums()
dx, dy, xydeltas = 0, 1, [(0, 0)]
for xys in sqsums
for i in 1:length(xys)
a, b = xys[i]
a != b && push!(xys, (b, a))
a != 0 && push!(xys, (-a, b), (b, -a))
b != 0 && push!(xys, (a, -b), (-b, a))
a * b != 0 && push!(xys, (-a, -b), (-b, -a))
end
filter!(p -> p[1] * dy - p[2] * dx >= 0, xys)
_, idx = findmax(p -> p[1] * dx + p[2] * dy, xys)
dx, dy = xys[idx]
push!(xydeltas, (dx, dy))
length(xydeltas) >= N && break
end
return accumulate((a, b) -> (a[1] + b[1], a[2] + b[2]), @view xydeltas[begin:N])
end
 
println("The first 40 Babylonian spiral points are:")
for (i, p) in enumerate(babylonian_spiral(40))
print(rpad(p, 10), i % 10 == 0 ? "\n" : "")
end
 
Plots.plot(babylonian_spiral(10_000))
</syntaxhighlight>
 
=={{header|Perl}}==
4,102

edits