Find X,Y,Z coordinates from index
Python 3, 150 140 bytes
def f(n):
a=b=x=y=z=0
for i in range(n):
a=x-~x<y--~z//2*6+z%2
b=z<y//6+-~y//6
x=-~x*a
y+=not(a|b)
z+=b>a
z*=a|b
return x,y,z
Try it online!
Has \$O(n)\$ complexity. TIO footer prints first 720 values in about 0.5 seconds.
Thanks to @ElPedro and @PrincePolka for each saving 5 bytes!
Jelly, 31 bytes
5,1ṁ9ĖŒṙṚḊḊḊ$Ƭz0ZUṬ€€ỊŒṪ’ṙÞ1ị@‘
A monadic link accepting an integer in \$[0,719]\$ which yields a list of three integers \$[X, Y, Z]\$.
Try it online!
Or see the test-suite (which completes in around 12-20s on TIO)
How?
Builds a lookup table and indexes into it:
5,1ṁ9ĖŒṙṚḊḊḊ$Ƭz0ZUṬ€€ỊŒṪ’ṙÞ1ị@‘ - Link: integer, n
5,1 - pair literal = [5,1]
ṁ9 - mould like 9 = [5,1,5,1,5,1,5,1,5]
Ė - enumerate = [[1,5],[2,1],[3,5],[4,1],[5,5],[6,1],[7,5],[8,1],[9,5]]
Œṙ - run-length-decode = [1,1,1,1,1,2,3,...,7,7,7,7,7,8,9,9,9,9,9]
Ṛ - reverse = [9,9,9,9,9,8,7,7,7,7,7,...,3,2,1,1,1,1,1]
Ḋ - dequeue = [9,9,9,9,8,7,7,7,7,7,...,3,2,1,1,1,1,1]
Ƭ - collect until a fixed-point:
$ - last two links as a monad:
Ḋ - dequeue
Ḋ - dequeue
- } = [[9,9,9,9,8,7,7,7,7,7,...,3,2,1,1,1,1,1],[9,9,8,7,...],[8,7,...],...,[1,1],[]]
z0 - transpose with filler zero
Z - transpose
U - reverse each list
Ṭ€€ - un-truth each int (e.g. 5 -> [0,0,0,0,1])
Ị - insignificant? (abs(x)<=1) (e.g. [0,0,0,0,1]->[1,1,1,1,1])
ŒṪ - truthy multi-dimensional 1-indexed indices
’ - decrement (i.e. all the [X,Y,Z] values)
Þ - sort by:
ṙ 1 - the list value rotated left by one (i.e. by [Y,Z,X])
‘ - increment (n) (since Jelly is 1-indexed)
@ - with swapped arguments:
ị - index into
JavaScript, 93 85 bytes
A port of Nick's Python solution.
n=>(g=x=>n--?g(x<y+~z/2n*6n+z%2n>>1n?++x:z<y/6n-~y/6n?++z-z:z=++y-y):[x,y,z])(y=z=0n)
Try It Online!
Saved 8 bytes thank to Arnauld's suggestion of using BigInts, plus a couple of other tweaks.