Skip to main content
47 of 60
added 14 characters in body
Martin Ender Mod
  • 198.2k
  • 14
  • 181
  • 311

Random Golf of the Day

Meta: I am running this as a little series of challenges revolving around the topic of randomness - in the form of a 9-hole golf course. I'm maintaining a leaderboard across all challenges in the series, and offer a large bounty to the person competing in all of them with the lowest overall score.

Just to be clear, despite the name, I won't be posting these once a day. Expect the next one in 6 to 8 weeks.

About the Series

This will be a series of 9 challenges. See the first instalment for more information about the series.

#1: Shuffle an Array

#2: Numbers from a Normal Distribution

#3: Integer Partitions

#4: The Bertrand Paradox

#5: Diamond Tilings

#6: Roll a d20

A very common die in table-top RPGs is the twenty-side die (an icosahedron, commonly d20). It is your task to roll such a die. However, if you were just returning a random number between 1 and 20, that would be a bit trivial. So your task is to return the values of all faces after the die has been rolled. In other words, you should generate a random net which still corresponds to the exact same die.

We'll use the following net for the d20 (which is the net used by Magic: the Gathering life counters). (We're using a triangle strip, instead of some more compact net, so that it can easily be represented as a list of integers.)

enter image description here

In such a net, the orange face corresponds to the top face, and its bottom edge is facing the player (we'll assume that there is always an edge facing the player, not a corner, such that there are three different nets for each each possible top face). The net will be represented with a simple integer list of the face values, traversing the net from the top to the bottom. So for the example above, it would simply be:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 

Another net, which has 1 on top and corresponds to the same die would be,

[1, 8, 9, 10, 2, 3, 4, 5, 6, 7, 17, 18, 19, 11, 12, 13, 14, 15, 16, 20] 

Or graphically (note that I didn't rotate the faces for simplicity):

enter image description here

The Challenge

Given an integer N, output N uniformly random d20 nets corresponding to the die described above. (That is, each of the 60 possible nets should have the same probability of being generated.)

Of course, due to the technical limitations of PRNGs, perfect uniformity will be impossible. For the purpose of assessing uniformity of your submission, the following operations will be regarded as yielding perfectly uniform distributions:

  • Obtaining a number from a PRNG (over any range), which is documented to be (approximately) uniform.
  • Mapping a uniform distribution over a larger set of numbers onto a smaller set via modulo or multiplication (or some other operation which distributes values evenly). The larger set has to contain at least 1024 times as many possible values as the smaller set.

Your program should be able to generate 100 nets in less than a second (so don't try generating random nets until one corresponds to the die given above).

You may write a program or function, taking input via STDIN (or closest alternative), command-line argument or function argument and outputting the result via STDOUT (or closest alternative), function return value or function (out) parameter.

Output may be in any convenient, unambiguous, flat list format.

This is code golf, so the shortest submission (in bytes) wins. And of course, the shortest submission per user will also enter into the overall leaderboard of the series.

Further ideas (still unordered):

  • Poisson disc sampling: This is a method to randomly distribute points across the plane densely while maintaining a minimum distance between points. I think this might be nice to golf. Further reading.
  • Generate a random chessboard: The submissions should randomly produce a believable chessboard. "Believable" here mostly affects pawns: they may not appear on the first row of their colour, there may be more pieces of other types if pawns are missing (due to conversion), and two pawns may only be in the same column if at least one of the opponent's pieces is missing. Submissions should be able to generate any valid board with finite probability, but it doesn't have to be uniform.
  • Generate a random arithmetic expression: This basically asks to create a tree of binary and unary operators, subject to some constraint - either on the structure of the tree (n nodes, say) or on the result of the arithmetic expression (generate a random expression that evaluates to a given n).
  • Generate a random hole-free polyomino (or orthogonal polygon) (of given size).
  • Vague idea: Generate points on a sphere with uniform distribution.
  • Vague idea: I'd like to include a challenge on random walks.
  • Vague idea: I'd like to include a challenge which has to generate a random number with a constraint based on its digits, but where you're not allowed to use strings or arrays (so you have to access the digits arithmetically).
  • Idea I'm not sure about: Generate a valid Unicode character as a set of UTF-8 bytes with uniform randomness.
  • Idea: Implement a (specific) PRNG.
  • Idea: Generate a random Brainfuck program (or other balanced string). Would probably need to require uniform distribution and deterministic runtime to be interesting.
Martin Ender
  • 198.2k
  • 14
  • 181
  • 311