A regular dodecahedron is one of the five Platonic solids. It has 12 pentagonal faces, 20 vertices, and 30 edges.


Your task is to output the vertex coordinates of a regular dodecahedron. The size, orientation, and position of the dodecahedron are up to you, as long as it is regular.

You may output the coordinates in any order, and in any reasonable format.

If the edge length of your dodecahedron is \$a\$, then the coordinates should be accurate to at least \$a/1000\$.

This is , so the shortest code in bytes wins.

Example output

This is one possible output. Your output does not have to match this.

  • 3
    \$\begingroup\$ Relative Wikipedia link \$\endgroup\$ Commented Jun 21, 2023 at 0:54
  • \$\begingroup\$ I believe you mean relevant. :) \$\endgroup\$
    – JakeRobb
    Commented Jun 28, 2023 at 22:28
  • \$\begingroup\$ @JakeRobb Yes, that was a typo on my part, but it's way too late to fix it now :) \$\endgroup\$ Commented Jun 30, 2023 at 12:25
  • \$\begingroup\$ Could you add to the challenge description that the coordinates have to be 3D, to rule out the silly Haskell answer? \$\endgroup\$
    – lynn
    Commented Jul 24, 2023 at 17:30

15 Answers 15


Wolfram Language (Mathematica), 15 bytes


Try it online!

20 evenly spaced points on the surface of a unit sphere.

ConvexHullMesh[SpherePoints@20, MeshCellStyle -> Opacity@0.75, ViewPoint -> {2, 2, 2}]

The more obvious PolyhedronCoordinates@Dodecahedron[] is a little bit longer.


05AB1E, 31 25 bytes


Uses \$\sqrt{3}\$ as the distance of each vector from the origin \$\{0,0\}\$. Will output the following 20 vertex-coordinates:


Try it online.


®X‚             # Push pair [-1,1]
   D            # Duplicate it
    3ã          # Get all possible triplets using the cartesian power of 3
   s            # Swap so the [-1,1] pair is at the top again
    ã           # Also get all possible pairs using the cartesian power of 2
     vy         # Loop over each pair of [±1,±1]:
       5t<;     #  Push the golden ratio: (sqrt(5)-1)/2
           D    #  Duplicate it
            >   #  Increase the copy by 1
             ‚  #  Pair it together with the (sqrt(5)-1)/2
      y       * #  Multiply the values in the pair to pair [±1,±1] at the same positions
        ¾š      #  Prepend a 0 to this pair
          2Ý    #  Push list [0,1,2]
            ._  #  Rotate the triplet that many times to the left
              « #  Merge it to the original list of [-1,1]-triplets
                # (after which the list of 20 triplets is output implicitly as result)

I started with a port of this SO C# answer, but noticed (for \$r=\sqrt{3}\$ at least):

  • \$±\frac{1}{\sqrt{3}}\times\phi\times\sqrt{3}\$ is simply \$±\phi\$
  • \$±\frac{\frac{1}{\sqrt{3}}}{\phi}\times\sqrt{3}\$ is simply \$±(\phi+1)\$

Try it online.

  • 1
    \$\begingroup\$ I'm not sure why the guy uses ϕ=0.618..., most people use ϕ=1.618... (the two are reciprocals of each other). \$\endgroup\$
    – Neil
    Commented Jun 21, 2023 at 23:38
  • \$\begingroup\$ Joined to upvote! \$\endgroup\$
    – Mitch
    Commented Jun 22, 2023 at 13:13

Python, 73 bytes

for s in(-1,1)*3:x|={(s*y,*z)for*z,y in x}

Attempt This Online!

Same approach as @xnor (I think), i.e. flip signs and rotate coordinates random-ish-ly. Only, I'm being more simple-minded about it ;-)

Retired Python, 103 bytes

for a in x,y:*map(print,a,a[1:],a[2:]),

Attempt This Online!

Integer coordinates from @alephalpha / @xnor via @Arnauld.

  • 1
    \$\begingroup\$ That's some nifty list assignment you have there \$\endgroup\$
    – xnor
    Commented Jun 22, 2023 at 4:31
  • \$\begingroup\$ @xnor still not good enough for beating you I notice \$\endgroup\$ Commented Jun 22, 2023 at 4:33
  • \$\begingroup\$ Ball is in your court, @xnor \$\endgroup\$ Commented Jun 23, 2023 at 0:57
  • \$\begingroup\$ @xnor Any chance this might qualify for that outgolfing bounty of yours? (Would look good in my CV ;-D ) \$\endgroup\$ Commented Jun 24, 2023 at 18:28
  • \$\begingroup\$ Oh nice idea doing all the sign flips. You definitely qualify for an outgoing bounty! I have to wait for the bounty on this question to expire before I can place it. \$\endgroup\$
    – xnor
    Commented Jun 25, 2023 at 19:52

JavaScript (ES6), 88 bytes

Returns a set of strings, where each string is a triplet x,y,z.

This version takes inspiration from xnor's approach.

_=>(g=(s,x,y=x,z=x,k=y)=>k--?g(s.add(x+[,y,z]),k%4?z:-z,x,y,k):s)(g(new Set,55),0,34,89)

Try it online!


_ => (               // main function ignoring its argument
  g = (              // g is a helper function taking:
    s,               //   s = output set
    x,               //   x = 1st coordinate
    y = x,           //   y = 2nd coordinate, or x by default
    z = x,           //   z = 3rd coordinate, or x by default
    k = y            //   k = counter, initialized to y
  ) =>               //
  k-- ?              // if k is not 0 (decrement afterwards):
    g(               //   do a recursive call:
      s.add(         //     add to the set:
        x + [, y, z] //       a stringified version of the triplet
      ),             //
      k % 4 ? z      //     rotate by putting z at the beginning
            : - z,   //     or -z if k is a multiple of 4
      x, y,          //     followed by x and y
      k              //     pass the updated counter
    )                //   end of recursive call
  :                  // else:
    s                //   stop and return the set
)(                   //
  g(new Set, 55),    // first call with x = y = z = 55
  0, 34, 89          // second call with (x, y, z) = (0, 34, 89)
)                    //

JavaScript (V8), 108 bytes

-5 bytes by using \$\phi\approx 89/55\$, as suggested by alephalpha
-3 bytes by scaling everything up (x55), as suggested by xnor

A full program printing 20 triplets x,y,z.


Try it online!


We use the Cartesian coordinates based on the golden ration as described on Wikipedia, but with a different scale.

Each triplet pattern is encoded with the following bit mask:

 |  |  | \__/
 |  |  |   |
 |  |  |   +--> number of triplets
 |  |  +------> x
 |  +---------> y
 +------------> z

where \$x\$, \$y\$ and \$z\$ are indices in the lookup array \$[0,1,\phi,\frac{1}{\phi}]\$.

This gives:

Triplet pattern x y z N Bit mask As decimal
\$(\pm 1,\pm 1,\pm 1)\$ 1 1 1 8 01 01 01 1000 344
\$(0,\pm\phi,\pm\frac{1}{\phi})\$ 0 2 3 4 11 10 00 0100 900
\$(\pm\frac{1}{\phi},0,\pm\phi)\$ 3 0 2 4 10 00 11 0100 564
\$(\pm\phi,\pm\frac{1}{\phi},0)\$ 2 3 0 4 00 11 10 0100 228
  • 2
    \$\begingroup\$ You can use 89/55 as an approximation of the golden ratio. \$\endgroup\$
    – alephalpha
    Commented Jun 21, 2023 at 8:37
  • 1
    \$\begingroup\$ I think you don't need to divide by 55 because the challenge allows the dodecahedron to be scaled. \$\endgroup\$
    – xnor
    Commented Jun 21, 2023 at 18:09

Haskell, 33 bytes


Try it online!


So this answer uses a trick, which some may consider a loophole. Actually uses two tricks. So I'm going to explain how it works.

If the OP wants to patch this approach out of the challenge, I will delete my answer.

Skew polyhedra

The exact definition of a polyhedron varies from person to person. Some circumstances require that a polyhedron be finite and not self intersect, this gives 5 regular polyhedra, some allow self intersection but still require finiteness, this gives 9 regular polyhedra, some times Euclidean tilings are considered as well giving 12.

However in the beginning of the 20th century Petrie and Coxeter discovered 3 regular polyhedra that hadn't been considered before. These were infinite polyhedra with flat non-intersecting faces, however they didn't have insides, so they hadn't been considered before. Pictured below is a section of the mucube, one of the three:


This discovery lead to a new definition of polytope (and by extension a new definition of polyhedron). This definition was first given by Branko Grünbaum in the paper Regular polyhedra - old and new, but has been used pretty extensively. Under this definition vertices (and edges) have exact locations, but the higher dimensional elements no longer needed to have exact interiors. A polygon is just a sequence of vertices pairwise connected by edges, such that you can reach any vertex from any other by following edges. A polyhedron is shape made out of polygons with exactly two meeting at every edge.

For example, classically a polygon needs to be "flat" meaning all of its vertices lie in a plane. However skew polygons can have vertices which lie in higher dimensional space. For example here's a 4-dimensional regular polygon:

Pentagonal-pentagrammic coil

Image by Plasmath see this page for liscensing

(We will come back to this particular polygon later)

The same can also be done with polyhedra. Instead of requiring that the vertices of a polyhedron lie strictly in 3D space with each face lying on a plane, you can have polyhedra whose vertices span 4 or greater dimensions, and whose faces are non-planar.

Lots of great work would be done with this definition. I'd especially like to point out the work of McMullen and Schulte. The have a paper classifying all the regular polyhedra in 3-space, which has been summarized in this excellent youtube video:

jan Misali, there are 48 regular polyhedra

This definition is the one I am using in this answer.

Now the challenge says:

Your task is to output the vertex coordinates of a regular dodecahedron. The size, orientation, and position of the dodecahedron are up to you, as long as it is regular.

So I just need to choose a regular dodecahedron. It turns out there are 28 distinct ways to realize the regular dodecahedron {5,3} in Euclidean space. The dodecahedron I chose is the its "Simplex realization". In general you can take any regular polyhedron with \$n\$ vertices and create an fully symmetric realization of it on a \$(n-1)\$-simplex. This is because all the symmetries of a polyhedron are permutations of its vertices. The symmetries of a simplex are all the permutations of its vertices. So when we place the vertices of a polyhedron on the vertices of a simplex every symmetry is possible. So this realization is always fully regular with maximum symmetry.

The dodecahedron has 20 vertices so that means the vertices of its simplex realization are the vertices of the 19-simplex. At first glance I've just made my problem much harder. The vertices of the 19-simplex centered at the origin are nasty, way worse than the vertices of the convex regular dodecahedron.

So here's where the second trick comes in. The vertices of a regular \$n\$-simplex are actually really simple if you express them in \$n+1\$ dimensions. If you place each vertex on an axis, all at the same distance from the origin, then permuting the axes is exactly the same as permuting the vertices. So this is fully regular, in fact its the same simplex its just lying on a weird hyperplane.

For example you can give the vertices of the triangle as:

$$ (1,0,0) \\ (0,1,0) \\ (0,0,1) \\ $$

This is a regular 2D triangle. This same trick comes up if you want to represent triangular (or hexagonal) coordinates. Instead of using 2D space and complicated square roots, you can represent them in 3D space as triplets of integers.

So returning to the problem at hand, the 19 simplex can be given in 20 dimensions as all permutations of \$(1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)\$. Its symmetries being all permutations of of the coordinate axes.

So in summary, I am giving the vertices for a 19-dimensional dodecahedron in 20 dimensional space.

I can't exactly render this in any way that is helpful. But its faces I can say its faces are the regular 4D pentagon shown earlier. If you want to try to imagine 12 of those in 20 dimensional space.

  • \$\begingroup\$ @LevelRiverSt I do think it is clear what the OP was imagining, since they even include a picture, but the text does say "as long as its regular" so I'll wait to see if the OP wants to rule on this. As for the second point, polychora are rank 4 polytopes. Convex polychora are 4-dimensional, but they can be other dimensions too (the cubic honeycomb is a 3d polychoron). Skews like this are still called polyhedra, regardless of the spanning dimension, since they only have 3 ranks of proper elements. \$\endgroup\$
    – Wheat Wizard
    Commented Jun 24, 2023 at 12:06
  • 2
    \$\begingroup\$ Clever, but the question says "a regular dodecahedron is one of the five platonic solids" so I think it's clear which dodecahedron OP wanted. Also according to wikipedia and wolfram, an n-dimensional shape is called a polytope, and a polyhedron is specifically 3 dimensional. en.wikipedia.org/wiki/Polytope mathworld.wolfram.com/Polyhedron.html \$\endgroup\$ Commented Jun 24, 2023 at 12:14
  • \$\begingroup\$ @LevelRiverSt If you disallow certain classes of polytopes rank and dimension are the same thing, but if you allow tessellations or skews this isn't true. In some cases dimension is used in place of rank, however the same source wikipedia is very clear that higher dimensional polyhedra are still called polyhedra in the relevant article: Regular skew polyhedron. \$\endgroup\$
    – Wheat Wizard
    Commented Jun 24, 2023 at 12:38
  • \$\begingroup\$ Looks like you answered my first comment while I was correcting/deleting it. I was aware of the Jan Misali video, and of the representation of for example the 4-simplex (3-dimensional tetrahedron) in 4 dimensions as all permutations of (0,0,0,1) which can be be moved into 3 dimensions by selecting the vertex (0,0,0,1) and changing its coordinates to (a,a,a,0) where a can take two different values (for this 3D example a=1 is one of them, and happens to be an integer.) By analogy the 20-simplex is a 19 dimensional object with a similarly convenient representation in 20 dimensions. \$\endgroup\$ Commented Jun 24, 2023 at 13:13
  • \$\begingroup\$ I must admit I'm struggling to visualize the embedded skew dodecahedron on this 19 dimensional object, and understand why it is rank 3. (I admit I don't have a clear understanding of rank - is this topological?) However, if we're bending the rules, I would note that the stellated dodecahedron and great dodecahedron also have 12 faces and simpler vertex sets (12 vertices in 3 dimensions, and identical to the icosahedron.) \$\endgroup\$ Commented Jun 24, 2023 at 13:17

Python 3, 86 bytes

for l in[[55]*3,[0,89,34]]*99:l+=(len(r)%11%-2|1)*l.pop(0),;r+=(*l,),

Try it online!

Outputs the golden-ratio vertices everyone is using, scaled up by 55, from the approximation of \$ \phi \approx 89/55\$ suggested by alephalpha.

The idea is to take the two vertices \$(1,1,1)\$ and \$(0,\phi,1/\phi)\$ and "randomly" negate entries and take cyclic permutations to reach all 20 vertices, then de-duplicate using sets. Each loop alternates between the two vertices, mutating it by moving the first entry to the back, and possibly negating that entry. Whether to negate is given by i%11%2 on the i'th loop, which happens to hit all 20 vertices in not too many loops. The index i is actually tracked by the length of the list l of vertices we've generated so far.

Python 3, 82 bytes

while k:k-175or(l:=[55]*3);l+=l.pop(0)*(-1)**k,;k>>=1;print(l)

Try it online!

To be golfed...


Prolog (SWI), 130 bytes

A+B:-A=B;A is-B.

Try it online!

Uses the approximation \$\phi \approx 89/55\$ then scaling the vertices by 55.

  • \$\begingroup\$ Welcome to Code Golf, and nice answer! \$\endgroup\$ Commented Jun 26, 2023 at 22:57

Nekomata, 16 bytes


Attempt This Online!

7Ƃ                  Push the list [1,1,1]
  89\55             Push the number 89/55
       :ŗÐ          Pair with its reciprocal ([89/55,55/89])
          ç         Prepend zero ([0,89/55,55/89])
           xŘ~      Non-deterministic rotation ([0,89/55,55/89],[89/55,55/89,0],[55/89,0,89/55])
              ?     Non-deterministic choice ([1,1,1],[0,89/55,55/89],[89/55,55/89,0],[55/89,0,89/55])
               ŋ    Optionally negate each element

Perl, 167 bytes

sub f{print"@_
"}sub g{$a=shift;map{$_[$_]*(!($a&1<<$_)*2-1)}0..~~@_-1}$p=.5+sqrt 5/4;f g $_,1,1,1 for 0..7;do{@v=((g $_,$p,1/$p,0)x2);f @v[$_..$_+2] for 0..2}for 0..3

Try it online!


Jelly,  18  17 bytes

...or 15 with repeats - remove µQ.


A niladic Link that yields a list of triples.

Try it online!


Produces the twenty triples as shown on Wikipedia:

$$(\pm 1, \pm 1, \pm 1)$$ $$(0, \pm \phi, \pm \phi^{-1})$$ $$(\pm \phi^{-1}, 0, \pm \phi)$$ $$(\pm \phi, \pm \phi^{-1}, 0)$$

Ø+ṗ3µØpİƬŻṙJ×€jµQ - Link: no arguments
Ø+                - [1, -1]
   3              - three
  ṗ               - Cartesian power -> (+/-1, +/-1, +/-1) "CubePoints"
    µ          µ  - monadic chain - f(CubePoints):
     Øp           -   phi
        Ƭ         -   collect up while distinct under:
       İ          -     inverse
         Ż        -   prefix with zero -> [0, phi, 1/phi]
           J      -   range of length {CubePoints} -> [1, 2, 3, 4, 5, 6, 7, 8]
          ṙ       -   rotate {[0, phi, 1/phi]} left by (vectorises) {that}
                      -> [[phi, 1/phi, 0], [1/phi, 0, phi], [0, phi, 1/phi], ...(8)]
             €    -   for each (rotation):
            ×     -     multiply by {CubePoints} (vectorises)
              j   -   join {that list of lists of triples} with {CubePoints}
                Q - deduplicate
  • \$\begingroup\$ I can't find a way to actually save a byte with it, but Ær2ị is a funny alternative to ØpİƬ. :) \$\endgroup\$
    – lynn
    Commented Jun 23, 2023 at 13:35
  • \$\begingroup\$ I like that that avoids the phi built-in as we have a form of the defining equation right there in our cube points! I was wondering if a set of roots might somehow make for less code in general before I wrote this code too, but I doubted that. \$\endgroup\$ Commented Jun 23, 2023 at 18:19

Charcoal, 53 44 bytes


Try it online! Link is to verbose version of code. Explanation: Uses the formula from this Math.SE answer.


Get the points [1/ϕ, 0, ϕ] and [1, 1, 1].


For each point, rotate it around the axis x=y=z, and also reflect the rotated point in the xy plane, and save and process any new points thus found.


Output the final dodecahedron.


Ruby, 55 bytes

20.times{|j|p ~0**j*(1.309-k=j/10),1.618**k*1i**j*=0.4}

Try it online!

Golfed version using decimal approximations instead of exact formulas (I can't use fractions as Ruby would interpret using integer arithmetic.) Dimensions are now half the ones given in the wolfram page, instead of double, to avoid j/10*4. The polar vertices are now listed before the equatorial vertices, to enable the distance from the z axis to be calculated as 1.618**k (1 or 1.618)

I also deleted the [] to save 2 bytes, although this impacts readability of the output.

Ruby, 85 63 bytes

20.times{|j|p [~0**j*z=5**0.5-1+j/10*4,[8/z,4].max*1i**j*=0.4]}

Try it online!

The coordinates given in the question are x,y,z with the dodecahedron's 5-fold rotational symmetry axis aligned with the z axis (It's actually a 10-fold axis for the rotate-and-flip operation.). This program outputs the same coordinates as the ones in the question, but in the format [z,x+yi] and scaled. First all the equatorial vertices are output, and then the polar vertices.

~0**j alternates the sign of the z coordinate as the x and y coordinates cycle through the 1/10th of a circle rotations. (-1**j would not work because unary minus has lower priority than raising to a power in Ruby.)

Exact coordinates in terms of the golden ratio are given at the wolfram page in formulas 1 and 2. The alternate coordinate system used in other answers is given a little below them on the same page, as well as in wikipedia. This code uses double the scale used in the Wolfram page, to avoid the division by 2 required to calculate the golden ratio. The footer in TIO link scales the coordinates given in the question and moves the z coordinate to the beginning for comparison. You still have to squint a bit because I've sorted the coordinates given in the question by z value, whereas the above code generates the vertices in an intercalated order with alternating sign of the z value.


Pyth, 24 bytes


Try it online!

Uses the same \$\varphi\$ based coordinates that everybody else is using, just multiplied by 10, that is, \$[\pm 10,\pm 10,\pm 10], [\pm 10\varphi, \pm \frac{10}{\varphi}, 0], [0, \pm 10\varphi, \pm \frac{10}{\varphi}], [\pm \frac{10}{\varphi}, 0, \pm 10\varphi]\$.

But there's a really neat simplification here, which is that after I had the integer coordinates, I could use them as the signs for the other coordinates, just adding the need to deduplicate at the end since \$0=-0\$.


    _BT                     # bifurcate 10 on negation (gives us [1,-1])
   ^   3                    # get all possible triplets
  K                         # assign this list to K
                   .n3      # phi
                 tB         # bifurcated on subtracting 1
                +     Z     # append 0 to the pair
             .<L       3    # map [0,1,2] to cyclic rotation on this list
           *K               # get the cartesian product of these rotations with K
        *VM                 # map over vectorized multiplication
 +K                         # add K to this list
{                           # deduplicate to eliminate repeat coordinates

Scala, 226 bytes

Golfed version. Try it online!

val p=Seq(-1,1)
val g=(sqrt(5)-1)/2     
((for{a<-p;b<-p;c<-p}yield Seq(a,b,c))++(for{p<-((for{a<-p;b<-p}yield Seq(a,b)).map{case Seq(a,b)=>Seq(a*g,b*(g+1))}.map(0.0+:_));i<-0 to 2}yield p.drop(i)++p.take(i))).foreach(println)

Ungolfed version. Try it online!

import scala.math._

object Main {
  def main(args: Array[String]): Unit = {
    val pair = List(-1, 1)
    val triplets = for {
      a <- pair
      b <- pair
      c <- pair
    } yield List(a, b, c)
    val pairs = for {
      a <- pair
      b <- pair
    } yield List(a, b)
    val goldenRatio = (sqrt(5) - 1) / 2
    val goldenRatioMultipliedPairs = pairs.map {
      case List(a, b) => List(a * goldenRatio, b * (goldenRatio + 1))
    val prependedPairs = goldenRatioMultipliedPairs.map(0.0 :: _)
    val rotatedPairs = for {
      pair <- prependedPairs
      i <- 0 to 2
    } yield pair.drop(i) ++ pair.take(i)
    val finalTriplets = triplets ++ rotatedPairs
  • 1
    \$\begingroup\$ 30 byte save: print("1,1,1;-1,1,1;1,-1,1;-1,-1,1;1,1,-1;-1,1,-1;1,-1,-1;-1,-1,-1;1x,0x,0;0x,0,1x;0,1x,0x;-1x,0x,0;0x,0,-1x;0,-1x,0x;1x,-0x,0;-0x,0,1x;0;1x,-0x;-1x,-0x,0;-0x,0,-1x;0,-1x,-0x".replace("x",".618")) :) \$\endgroup\$
    – lynn
    Commented Jun 23, 2023 at 13:50

Perl, 139 137 135 bytes

sub p{print"@_
"}sub g{($x)=@_;map{$_[$_]*(1-(4*$x>>$_&2))}1..3}p g$_,(55)x3 for 0..7;map{@v=(g$_,89,34,0)x2;p@v[$_..$_+2]for 0..2}0..3

try it online

  • \$\begingroup\$ Hi there, welcome to code golf! This is a very good first answer! I hope you enjoy your stay on this site. \$\endgroup\$
    – lyxal
    Commented Jun 24, 2023 at 12:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.