# Create a solar system

Intro

This is based on an actual problem I recently faced while making a computer game and I thought it would make for a nice round of .

There are seven main spectral classes of star which put out varying amounts of heat. The geology of planets around a star are greatly influenced by the amount of heat received from the star, which is a factor of spectral class and distance from the star. Hence Mercury is practically molten, Neptune frozen.

The galaxy in my game is procedurally generated and randomly selecting planet types for given stars turned out to be a real 'if statement hell'!

The challenge

Your method should select one planet from a list of planet types appropriate for the class of star, based on a minimum heat threshold, a maximum heat threshold and a random number. For simplicity this challenge will only use a class G star, just like our sun.

Inputs

An integer heat in the range 4 to 11 representing the amount of heat received by the planet from the star.

Variables

This table shows the possible planets based on heat. Your method should first narrow the available choices based on the heat min and heat max, heat should fall on or between the two. E.g. with a heat of 10 passed in the only choices would be Desert, Iron and Lava.

Planet type    Heat min   Heat max   Random Chance
Gas Giant         4          9            15
Ice               4          6            10
Ice Giant         4          6            10
Gaia class        5          7            10
Dense Atmosphere  7          9            10
Desert            7          10           25
Iron              7          10           14
Lava             10          11           6


Next, the probability of a planet (in the remaining choices) being chosen is its random chances divided by the sum of the random chances of all the choices.

In the above example, the probability of Iron being chosen is 14/(25+14+6).

Output

Return the planet type as a string.

Do the best you can to avoid logic arrowheads. Shortest code wins, points all round for creativity. Happy golfing!

• Should the "class" of "Gaia class" be capitalised like everything else? Feb 24, 2018 at 14:43
• @JonathanAllan it's lower case as it's not a proper noun Feb 24, 2018 at 15:06
• @Absinthe Then why is Dense Atmosphere uppercase? Feb 24, 2018 at 15:08
• ... have anyone said that? | Welcome to PPCG, and nice first challenge! Feb 24, 2018 at 15:24
• @EricDuminil aka an arrowhead anti-pattern, aka nested-if-statement-hell! wiki.c2.com/?ArrowAntiPattern Feb 25, 2018 at 13:44

# Jelly,  78  75 bytes

“'ĖøÆḳƙ’ḃ7ṣ6Ä+3r/ċ€×“½½½½©ÐÇı‘
“ŀỊẋ8ƒ³ẈRɼƈñqẋẏȧɱḌ<ṄỴḳ⁾ÆʋeẒĊ'@ƬØƓƝ}ḟ¬»Ỵx'ÇX


A monadic link accepting an integer (in [4,11]) which returns a list of characters.

Try it online!

### How?

Creates the heat ranges of the planets as a list of lists and counts the occurrences of the input heat in those lists to get a list of zeros and ones representing which planet types are possible, then multiplies by the likelihood numbers of the eight planet types to get the distribution. The distribution is used to repeat the planet type names, and finally, a uniform random choice is made.

“'ĖøÆḳƙ’ḃ7ṣ6+\+3r/ċ€×“½½½½©ÐÇı‘ - Link 1, getDistribution: integer
“'ĖøÆḳƙ’                        - base 250 integer = 39824688429662
ḃ7                      - to bijective-base 7 = [1,1,2,4,7,1,4,4,6,2,2,2,2,1,5,3,3]
ṣ6                    - split at sixes = [[1,1,2,4,7,1,4,4],[2,2,2,2,1,5,3,3]]
+\                  - reduce by addition = [[1,1,2,4,7,1,4,4],[3,3,4,6,8,6,7,7]]
+3                - add three = [[4,4,5,7,10,4,7,7],[6,6,7,9,11,9,10,10]]
r/              - reduce by inclusive range = [[4,5,6],[4,5,6],[5,6,7],[7,8,9],[10,11],[4,5,6,7,8,9],[7,8,9,10],[7,8,9,10]]
ċ€            - count (input) in €ach e.g. for 5: [1, 1, 1, 0,0, 1, 0, 0]
“½½½½©ÐÇı‘ - list of code-page indices        [10,10,10,10,6,15,14,25]
×           - multiply                         [10,10,10, 0,0,15, 0, 0]

“ ... »Ỵx'ÇX - Main link: integer
“ ... »      - compressed string = "Ice\nIce Giant\nGaia class\nDense Atmosphere\nLava\nGas Giant\nIron\nDesert"
Ỵ     - split at new lines = ["Ice","Ice Giant","Gaia class","Dense Atmosphere","Lava","Gas Giant","Iron","Desert"]
Ç  - call last link (1) as a monad e.g. for 5: [10,10,10,0,0,15,0,0]
'   - spawn:
x    -   times e.g. for 5: ["Ice","Ice","Ice","Ice","Ice","Ice","Ice","Ice","Ice","Ice","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant","Ice Giant"]
X - a random choice from that list

• Crazy! Well done. Feb 24, 2018 at 15:11
• @Absinthe You can simply upvote. Side note: On Code Golf we typically don't accept answers. Feb 24, 2018 at 15:12
• @user202729 I'll add votes in a day or two. I was looking over the GitHub page for Jelly trying to unravel this code. I believe Crazy! is most appropriate :) Feb 24, 2018 at 15:18
• @Absinthe yes, I believe a descriptive section is often a good thing to have even for non-esoteric language submissions :) Feb 24, 2018 at 17:29
• You people are truly insane. Feb 25, 2018 at 5:20

# R, 225223 183 bytes

Thanks to Giuseppe for clever refactoring to take it down to 188 bytes; the remaining five were shaved off by using less redundant number representations.

i=scan()-4
sample(c("Gas Giant","Ice","Ice Giant","Gaia class","Dense Atmosphere","Desert","Iron","Lava")[l<-c(0,0,0,1,3,3,3,6)<=i&c(5,2,2,3,5,6,6,7)>=i],1,,c(3,2,2,2,2,5,2.8,1.2)[l])


Try it online!

• That's a nice approach, I may have to think about removing my if statement maze if favour of this in C# :) Feb 24, 2018 at 18:23
• I suspect saving the logical index rather than using with,data.frame, and subset will be shorter. Feb 26, 2018 at 13:51
• 188 bytes Feb 26, 2018 at 15:13
• @Giuseppe, you can probably gain a few more bytes by using some of my tricks with planet data, but I think I'll also improve mine using your idea of separating the probabilities vector from the rest of the data. Feb 26, 2018 at 15:38

# JavaScript 212

Edit 6 bytes save thx Jonathan Allan

h=>[963,640,640,649,667,1628,924,437].map((z,i)=>(z/8&7)+4>h|z%8+6<h?0:t=r.push(...Array(z>>6).fill(i)),r=[])&&"Gas Giant,Ice,Ice Giant,Gaia class,Dense Atmosphere,Desert,Iron,Lava".split,[r[t*Math.random()|0]]


less golfed

h=>(
r = [],
// heat min,max and chance encoded in base 8 with offsets
// min range 4 to 10, with offset 4, 0 to 6
// max range 6 to 11, with offset 6, 0 to 5
[(4-4)*8 + 9-6 + 15*64,
(4-4)*8 + 6-6 + 10*64,
(4-4)*8 + 6-6 + 10*64,
(5-4)*8 + 7-6 + 10*64,
(7-4)*8 + 9-6 + 10*64,
(7-4)*8 + 10-6+ 25*64,
(7-4)*8 + 10-6+ 14*64,
(10-4)*8+ 11-6+  6*64]
.forEach( (z,i) => (
min = (z / 8 & 7) + 4,
max = z % 8 + 6,
chance = z >> 6,
min > h || max < h
? 0 // out of range
// add current position i repeated 'chance' times
// array size in t
: t = r.push(...Array(chance).fill(i))
),
pos = r[t * Math.random() | 0],
["Gas Giant", "Ice", "Ice Giant", "Gaia class", "Dense Atmosphere", "Desert", "Iron", "Lava"][pos]
)


Test

var F=
h=>[963,640,640,649,667,1628,924,437].map((z,i)=>(z/8&7)+4>h|z%8+6<h?0:t=r.push(...Array(z>>6).fill(i)),r=[])&&"Gas Giant,Ice,Ice Giant,Gaia class,Dense Atmosphere,Desert,Iron,Lava".split,[r[t*Math.random()|0]]

function test()
{
var heat=+H.value
var i,result,hashtable={},rep=1e5
for (i=0;i<rep;i++)
result = F(heat),
hashtable[result] = -~hashtable[result]

console.log('Input',heat)
for (i in hashtable)
{
console.log(i,(hashtable[i]/rep*100).toFixed(2),'%')
}
}
<input id=H type=number min=1 max =15 value=10>
<button onclick='test()'>Test</button>

• A couple of your base 16 numbers are 1 off (should be [3913, 2630, 2630, 2647, 2681, 6522, 3706, 1707]) Feb 24, 2018 at 18:55
• I think (but am not 100%) you can save 2 by replacing (z/16&15) with z/16&15. Regardless, you can save 6 bytes using a base 8 compression with offsets of three and six... use [971,648,648,657,675,1636,932,445] with z/8&7+3, z%8+6 and z>>6 :) Feb 24, 2018 at 19:13
• @JonathanAllan offsets! Great idea, thx Feb 24, 2018 at 19:51
• @JonathanAllan i need brackets for (z/8&7)+4 because & has lower priority - it would be 7/8&(7+4) Feb 24, 2018 at 20:09
• @Shaggy did you see the comment right above yours? (long story short: no) Feb 26, 2018 at 16:15

# Coconut, 214 195 bytes

t->choice..sum([[n]*g(p)*(g(a)<t<g(b))for*n,a,b,p in'Gas Giant3AF_Ice37A_Ice Giant37A_Gaia class48A_Dense Atmosphere6AA_Desert6BP_Iron6BE_Lava9C6'.split('_')],[])
from random import*