Créer un système solaire


39

Intro

Ceci est basé sur un problème auquel j'ai récemment fait face lors de la création d'un jeu d'ordinateur et je pensais que cela ferait une belle partie de .

Il y a sept classes spectrales principales d'étoiles qui émettent des quantités variables de chaleur. La géologie des planètes autour d'une étoile est grandement influencée par la quantité de chaleur reçue par l'étoile, qui est un facteur de classe spectrale et de distance par rapport à l'étoile. Par conséquent, le mercure est pratiquement fondu, Neptune est gelé.

La galaxie dans mon jeu est générée procéduralement et la sélection aléatoire de types de planètes pour des étoiles données s’est avérée être un véritable "énoncé si l’enfer"!

Le défi

Votre méthode doit sélectionner une planète dans une liste de types de planète correspondant à la classe d'étoiles, en fonction d'un seuil de chaleur minimum, d'un seuil de chaleur maximum et d'un nombre aléatoire. Pour des raisons de simplicité, ce défi n’utilisera qu’une étoile de classe G, tout comme notre soleil.

Contributions

Un entier heatcompris entre 4 et 11 représentant la quantité de chaleur reçue par la planète par l'étoile.

Variables

Ce tableau montre les planètes possibles basées sur heat. Votre méthode doit d’abord limiter les choix disponibles en fonction de la chaleur min et de la chaleur max heat. Par exemple, avec une chaleur de 10, les seuls choix possibles sont Desert, Iron et 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

Ensuite, la probabilité qu'une planète (dans les choix restants) soit choisie est ses chances aléatoires divisées par la somme des chances aléatoires de tous les choix.

Dans l'exemple ci-dessus, la probabilité que le fer soit choisi est 14/(25+14+6).

Sortie

Renvoie le type de planète sous forme de chaîne.

Faites de votre mieux pour éviter les pointes de flèche logiques. Le code le plus court gagne, tout en points pour la créativité. Bon golf!


La "classe" de "classe Gaia" doit-elle être mise en majuscule comme tout le reste?
Jonathan Allan

@ JonathanAllan c'est une minuscule car ce n'est pas un nom propre
Absinthe

1
@Absinthe Alors pourquoi Dense A tmosphere est-il en majuscule?
Erik the Outgolfer

17
... Quelqu'un a dit ça? | Bienvenue sur PPCG, et bon premier défi!
user202729

3
@EricDuminil aka un anti-motif de flèche, aka imbriqué si déclaration-enfer! wiki.c2.com/?ArrowAntiPattern
Absinthe

Réponses:


12

Gelée , 78 octets

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

Un lien monadique acceptant un entier (en [4,11] ) qui renvoie une liste de caractères.

Essayez-le en ligne!

Comment?

Crée les plages de chaleur des planètes sous forme de liste de listes et compte les occurrences de la chaleur en entrée dans ces listes pour obtenir une liste de zéros et de noms représentant les types de planète possibles, puis multiplie par les nombres de vraisemblance des huit types de planète. obtenir la distribution. La distribution est utilisée pour répéter les noms de type de planète, et finalement un choix aléatoire uniforme est effectué.

“'ĖøÆḳƙ’ḃ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]]
             \                  - cumulative reduce with:
            +                   -   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]]
                 /              - reduce with:
                r               -   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]

“ ... »ỴW€ẋ"ÇẎ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"]
        W€      - wrap €ach in a list
            Ç   - call last link (1) as a monad e.g. for 5: [10,10,10,0,0,15,0,0]
           "    - zip with:
          ẋ     -   repeat 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"],["Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class"],["Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant"]]
             Ẏ  - tighten               ["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","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gaia class","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant","Gas Giant"]
              X - a random choice from that list

Fou! Bien joué.
Absinthe le

@Absinthe Vous pouvez simplement voter par la suite. Note latérale: Sur Code Golf, nous n'acceptons généralement pas les réponses.
user202729

2
@ user202729 Je vais ajouter des votes dans un jour ou deux. Je cherchais sur la page GitHub Jelly essayant de démêler ce code. Je crois fou! est le plus approprié :)
Absinthe

2
@Absinthe oui, je pense qu'une section descriptive est souvent une bonne chose à avoir même pour les soumissions en langage non ésotérique :)
Jonathan Allan

3
Vous êtes vraiment fou.
Selvek

7

R , 225 223 183 octets

Merci à Giuseppe pour son refactoring astucieux pour le réduire à 188 octets; les cinq autres ont été rasés en utilisant des représentations de nombre moins redondantes.

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])

Essayez-le en ligne!


C'est une bonne approche, je devrais peut-être penser à supprimer mon labyrinthe de déclarations if si je suis favorable à cela en C # :)
Absinthe

Je soupçonne enregistrement de l'index logique plutôt que d' utiliser with, data.frameet subsetsera plus courte.
Giuseppe


@ Giuseppe, vous pouvez probablement gagner quelques octets supplémentaires en utilisant certaines de mes astuces avec les données de la planète , mais je pense que je vais aussi améliorer le mien en utilisant votre idée de séparer le vecteur de probabilités du reste des données.
Kirill L.

4

JavaScript 212

Éditer 6 octets sauver 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]]

moins golfé

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]
)

Tester

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>


Un couple de vos 16 chiffres de base est 1 (devrait être [3913, 2630, 2630, 2647, 2681, 6522, 3706, 1707])
Jonathan Allan

Je pense (mais je ne suis pas à 100%) que vous pouvez économiser 2 en les remplaçant (z/16&15)par z/16&15. Quoi qu'il en soit, vous pouvez économiser 6 octets en utilisant une compression en base 8 avec des décalages de trois et six ... utilisez [971,648,648,657,675,1636,932,445]avec z/8&7+3, z%8+6et z>>6:)
Jonathan Allan

@ JonathanAllan offsets! Excellente idée,
merci

@JonathanAllan, j'ai besoin de crochets, (z/8&7)+4car &sa priorité est moindre - ce serait7/8&(7+4)
edc65

1
@Shaggy avez-vous vu le commentaire juste au-dessus du vôtre? (longue histoire courte: non)
edc65

4

Noix de coco , 214 195 octets

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*
g=int$(?,36)

Essayez-le en ligne!

Un port Python aurait une longueur de 203 200 octets:

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

Essayez-le en ligne!


1
Fait intéressant, au moment de la rédaction de cet article, votre port Python surpasse toutes les autres solutions Python!
Kirill L.

4

Charbon de bois , 115 111 octets

≔I⁻N³θF⁸«≔§⪪”↷&∧⬤.YLφκ¦(⁼;σ≕]✂↙ζC” ιη¿›θη¿‹θ§η¹FI✂η²⊞υ黧⪪”↓(″1↨▷]U,&ζ^iI″RSY≡´⍘'#﹪υVw5Vu>D<U5r6⁰Q▷Z◨⌕⁸ΣεCZ”¶‽υ

Essayez-le en ligne! Le lien est vers la version verbeuse du code. Edit: 4 octets enregistrés grâce à @ ASCII uniquement. Explication:

≔I⁻N³θ

Soustrayez 3 de l'entrée pour pouvoir la comparer à un chiffre.

F⁸«≔§⪪”↷&∧⬤.YLφκ¦(⁼;σ≕]✂↙ζC” ιη

Fractionnez la chaîne 0715 0410 0410 1510 3710 3825 3814 696sur les espaces (les espaces semblent se compresser mieux que les virgules mais je n'ai pas essayé d'autres caractères) et passez en boucle sur chaque partie.

¿›θη¿‹θ§η¹FI✂η²⊞υι»

Comparez l'entrée avec les premier et deuxième chiffres et si c'est entre, poussez l'index de la boucle le nombre de fois donné dans la liste vide prédéfinie, remplissant ainsi celle-ci.

§⪪”↓(″1↨▷]U,&ζ^iI″RSY≡´⍘'#﹪υVw5Vu>D<U5r6⁰Q▷Z◨⌕⁸ΣεCZ”¶‽υ

Fractionner la liste des planètes sur les nouvelles lignes (encore une fois, mieux que des virgules pour une raison quelconque) et sélectionner l'élément correspondant à un index choisi aléatoirement dans la liste.


Joli. Comment le hasard (u) prend-il en compte les différentes probabilités pour chaque planète? (Je ne sais rien sur le charbon de bois).
Absinthe

Il choisit un index dans une liste avec la distribution correcte des index planetType en raison de la "transmission de l'index de boucle le nombre donné de fois à la liste vide prédéfinie, le remplissant ainsi". puis en utilisant l'index choisi pour obtenir le nom de planetType.
Jonathan Allan

@JonathanAllan Got, merci
Absinthe

111 octets , je pense? En général, essayez d'utiliser des caractères plus tôt dans la classe de caractères, voir la compression n ° 11. L'ordre par défaut enregistre un autre octet, mais c'est en gros uniquement si vous ne disposez que de symboles
ASCII uniquement

@ ASCII-only Effacer comme de la boue ... pourquoi les nouvelles lignes sont-elles meilleures ici, mais des espaces pour l'autre chaîne?
Neil

3

R , 196 193 190 175 171 octets

sample(readLines(,8),1,,c(3,2,2,2,2,5,2.8,1.2)*((x=scan()-3)>c(0,0,0,1,3,3,3,6)&x<c(7,4,4,5,7,8,8,9)))
Gas Giant
Ice
Ice Giant
Gaia class
Dense Atmosphere
Desert
Iron
Lava

Essayez-le en ligne!

Initialement inspirée par cette solution de @rturnbull, cependant, les deux soumissions ayant considérablement évolué, il s’agit maintenant essentiellement d’un mélange d’idées de l’auteur original, @Giuseppe, qui a été très utile dans les commentaires, et du mien. Voici un résumé des points clés qui ont contribué à réduire le compte d'octets:

  • Codage des données de la planète au format CSV Collecte de noms avec readLinespour éviter le grand nombre de caractères de citation autour des chaînes.

  • Ajuster les paramètres de chaleur afin que nous puissions utiliser <et >signes à la place de <=et >=.

  • Changer le format de données de chaleur de Heat min, Heat maxà Heat min, Heat Deltapour supprimer les nombres à deux chiffres.
    Remplacé en décalant tous les nombres de -3

  • Diviser toutes les probabilités de planète par 5, ce qui donne également quelques chiffres en moins.

  • Multiplier le vecteur de probabilités de planète par le vecteur de Booléens (indiquant si notre entrée satisfait aux exigences de chaleur) pour annuler les probabilités de planètes inappropriées.

Il serait probablement possible d’obtenir quelques octets supplémentaires en appliquant une sorte de compression de données.
Je pense, pas plus.


1
t=au lieu de text=sauver 3 octets ainsi.
Giuseppe


réponse solide, cependant, en utilisant read.csvpour une seule colonne suggéré readLinesde se débarrasser des guillemets entièrement, même si vous devez définir explicitementn
Giuseppe

@Giuseppe, il s’agit toutefois de 171 octets, car vous avez également supprimé les parenthèses nécessaires au maintien de la priorité des opérateurs, et votre version donne des probabilités erronées. Pourtant, une suggestion brillante!
Kirill L.

Oh, je me suis demandé d'où venaient ces parenthèses ...
Giuseppe

3

Python, 282 octets , 261 octets:

from random import*
i,p,l=input(),[('Gas Giant',3,11,15),("Ice",3,7,10),("Ice Giant",3,7,10),("Gaia Class",4,8,10),("Dense Atmosphere",6,10,10),("Desert",6,11,25),("Iron",6,11,14),("Lava",9,12,6)],[]
for x in p:exec"l+=x[0],;"*(x[1]<i<x[2])*x[3]
print choice(l)

Assez simple - assez sûr que cela pourrait être plus joué - Toujours à la recherche d'un meilleur moyen de représenter la plage de la planète et les données de probabilité. Si i est à portée du type de planète, l'ajoute à la liste en fonction de la probabilité, puis en affiche une au hasard.

EDIT: Avec le crédit à Jonathan Frech - a refait la boucle pour supprimer quelques octets. Meilleure façon d’ajouter des éléments à la liste


3
Bienvenue chez PPCG! Vous ne savez pas comment vous avez compté les octets, mais je ne reçois que 283. Moins si le retrait est un onglet au lieu de 4 octets.
Martin Ender

1
Cela i in range(x[1], x[2])n’exclut- il pas le bord supérieur de la chaleur, contrairement à ce que spécifie le cahier des charges?
Graipher


1
Cela pourrait-il être une aide? p,d="Gas Giant,Ice,Ice Giant,Gaia class,Dense Atmosphere,Desert,Iron,Lava".split(","),[ord(i)-10 for i in"#"] d=[[p[x//3]]+d[x:x+3]for x in range(0,len(d),3)]
MoustacheMoses

1
@Chromane Excuses, il semble que les commentaires aient dépouillé certains personnages.
MoustacheMoses

2

Octave avec paquet statistique, 178 176 174 158 octets

@(h)randsample(strsplit('Gas Giant,Ice,Ice Giant,Gaia class,Dense Atmosphere,Desert,Iron,Lava',','),1,1,('UPPPP_TL'-70).*(h>'IIIJLLLO'-70&h<'PMMNPQQR'-70)){1}

Le code définit une fonction anonyme qui entre un nombre et génère une chaîne.

Essayez-le en ligne!

Explication

Le code

@(h)

définit une fonction anonyme avec entrée h.

La ficelle

'Gas Giant,Ice,Ice Giant,Gaia class,Dense Atmosphere,Desert,Iron,Lava'

est divisé en virgules avec

strsplit(...,',')

Le résultat est un tableau de cellules de chaînes, chaque chaîne étant une classe planète.

Le code

'IIIJLLLO'-70

définit la chaîne montrée et soustrait 70des points de code de ses caractères. Cela donne l’ensemble des valeurs de chaleur minimales moins 1 , c’est-à-dire [3 3 3 4 6 6 6 9] .

De même,

'PMMNPQQR'-70

produit la matrice de valeurs de chaleur maximales plus 1 , c'est-à-dire[10 7 7 8 10 11 11 12] .

Les comparaisons

h>...&h<...

donner un tableau contenant trueoufalse indiquant quelles classes de planètes sont possibles.

D'autre part,

'UPPPP_TL'-70

définit le tableau de valeurs de probabilité aléatoire [15 10 10 10 10 25 14 6].

L'opération

(...).*(...)

est la multiplication élément par élément des deux derniers tableaux ( trueet falsese comporte comme 0et 1respectivement). Cela donne un tableau dans lequel chaque classe de planète a sa chance aléatoire ou 0si cette classe n'est pas possible sur la base de l'entrée. Ce tableau sera utilisé comme poids dans l'échantillonnage aléatoire

L'appel de fonction

randsample(...,1,1,...)

sélectionne l'une des cellules du tableau de cellules de la cellule (premier argument d'entrée), en utilisant le tableau de poids calculé (quatrième argument d'entrée). Plus précisément, la fonction randsamplenormalise automatiquement les poids en fonction des probabilités, puis effectue la sélection aléatoire avec ces probabilités. Le résultat est un tableau de cellules contenant une chaîne. Le code

{1}

est utilisé pour extraire cette chaîne, qui constitue la sortie de la fonction.


2
Grande explication, merci. Excellent score aussi.
Absinthe

2

Python 3 , 263 octets

from random import*
P=lambda h:"Gas Giant|Ice|Ice Giant|Gaia class|Dense Atmosphere|Desert|Iron|Lava".split("|")[choices(*list(zip(*filter(lambda x:h in range(*x[2:]),zip(*[[int(x,32)for x in"0f4a1a472a473a584a7a5p7b6e7b76ac"][a::4]for a in(0,1,2,3)]))))[:2])[0]]

Essayez-le en ligne!


1

Perl 5 ( -p), 230 octets

@a=(['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]);//;map{push@b,($$_[0])x($$_[3]*($$_[1]<=$'&&$'<=$$_[2]))}@a;$_=$b[rand@b]

Essayez-le en ligne!


Si vous en supprimez une au minimum et que vous en ajoutez un au maximum (cela donnerait à la [Ice,4,5,11]place de [Ice,4,6,10], etc.), vous pourrez alors utiliser <au lieu de <=et >au lieu de >=, économisant ainsi 2 octets. (oui, ce n'est pas beaucoup ...)
Dada

1

Nim , 314 298 294 octets

import random,sequtils
proc c(h:int)=
 var a= @[""]
 a.del 0
 for n in[("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)]:(if h>=n[1]and h<=n[2]:a.add repeat(n[0],n[3]))
 echo random a

Pour la boucle maintenant dans une ligne, pas de retour, moins d'octets pour le type implicite

4 espaces supprimés (merci Kevin )

Essayez-le en ligne!


Je n'ai jamais programmé Nim, mais je pense que vous pouvez jouer au golf quatre espaces: un à for n in[(; et trois à if h>=n[1]and h<=n[2].
Kevin Cruijssen

1

05AB1E , 78 octets 76

”Œï²°™Ä²° Gaia classêη•™Äµ‰Ÿ± Lava”#8äðýā<•ŒEŽuS,•2ôו9èÁnÇ∞Λ•SÌ2ôεŸIå}ÏSΩè

Essayez-le en ligne!

Explication

”Œï²°™Ä²° Gaia classêη•™Äµ‰Ÿ± Lava”
pousse la ficelle Gas Giant Ice Giant Gaia class Dense Atmosphere Ice Desert Iron Lava

#                                          # split on spaces
 8ä                                        # divide into 8 parts
   ðý                                      # join each by spaces
     ā<                                    # push the range [0 ... 7]
       •ŒEŽuS,•                            # push 151010101025146
               2ô                          # split into pieces of 2
                                           # results in [15, 10, 10, 10, 10, 25, 14, 6]
                 ×                         # repeat each number in the range by these amounts
                                           # results in ['000000000000000', '1111111111', '2222222222', '3333333333', '4444444444', '5555555555555555555555555', '66666666666666', '777777']
                  •9èÁnÇ∞Λ•                # push 2724355724585889
                           S               # split to list of digits
                            Ì              # decrement each twice
                                           # results in [4,9,4,6,5,7,7,9,4,6,7,10,7,10,10,11]
                             2ô            # split into pieces of 2
                                           # results in [[4, 9], [4, 6], [5, 7], [7, 9], [4, 6], [7, 10], [7, 10], [10, 11]]
                               εŸIå}       # apply to each pair
                                Ÿ          # range [a ... b]
                                 Iå        # check if input is contained in the range
                                           # ex, for input 10: [0, 0, 0, 0, 0, 1, 1, 1]
                                    Ï      # keep only the indices which are true
                                           # ex, for input 10: ['5555555555555555555555555', '66666666666666', '777777']
                                     S     # split to list of digits
                                      Ω    # pick one at random
                                       è   # index into the list of strings with this

1

Python 3, 199 194 octets

from random import*
lambda n:choices("Ice|Ice Giant|Gas Giant|Gaia class|Dense Atmosphere|Desert|Iron|Lava".split('|'),[(0x33b2a53d4a>>5*i&31)*(0xc07878380e3f0707>>8*i+n-4&1)for i in range(8)])

Le fractionnement hen masques de bits séparés et en valeurs aléatoires (voir explication) économise quelques octets en éliminant une affectation àh et en simplifiant la range()compréhension dans la liste.

Solution précédente

from random import*
h=0xc033c39e3270a0e51fbc1d40ea
lambda n:choices("Ice|Ice Giant|Gas Giant|Gaia class|Dense Atmosphere|Desert|Iron|Lava".split('|'),[(h>>i&31)*(h>>i+n+1&1)for i in range(0,104,13)])

Définit une fonction anonyme qui prend un int et renvoie le type de planète.

Pour chaque type de planète, une valeur de 13 bits a été calculée. Les 8 bits supérieurs définissent un masque de bits des valeurs de chaleur valides pour ce type de planète. Les 5 derniers bits représentent le hasard pour ce type de planète. Par exemple, "Classe Gaia" est un type valide pour les valeurs de chaleur 4 à 7, de sorte qu'il possède un masque de 0b00001111. Il a une chance aléatoire de 10, ou 0b01010. En les combinant, on obtient la valeur 13 bits 0b0000111101010du type "classe Gaia". Les valeurs de 13 bits pour chaque type de planète sont concaténées pour obtenir la valeur h(les 13 bits les plus bas correspondent au type de planète "Ice"). (La réponse la plus récente ne combine pas ces valeurs).

La compréhension de la liste itère sur les valeurs 13 bits pour créer une liste de poids, poids étant le hasard si le type de planète est un choix valide pour la valeur de chaleur donnée et zéro dans le cas contraire. Pour chaque type de planète, (h>>i&31)extrait le hasard de ce type de planète. (h>>i+n+1&1)évalue à 1 si le type de planète est un choix valide pour la valeur de chaleur net évalue à 0 sinon.

La fonction de bibliothèque random.choices(choices, weights)sélectionne un élément dans la liste de choix en fonction de la liste des poids.


i+n+1peut être i-~n. TIO
ovs

1

Ruby , 214 193 189 octets

->h{'Gas Giant,Desert,Iron,Lava,Ice,Ice Giant,Gaia class,Dense Atmosphere'.split(?,).zip(31006330.digits,75449887.digits,[15,25,14,6]).flat_map{|n,m,x,r|m<h-3&&x>h-3?[n]*(r||10):[]}.sample}

Essayez-le en ligne!


Désolé, je ne reçois pas le résultat. S'agirait-il du premier élément de la liste?
Absinthe le

@Absinthe j'ai ajouté quelques titres, vérifiez à nouveau. C'est tous les niveaux de chaleur de 4 à 11 et une planète générée au hasard pour chaque
Asone Tuhid

Ah, je comprends, mais idéalement il devrait y avoir une seule sortie de chaîne
Absinthe

@Absinthe Vous avez raison, c'était juste mon propre code de test. Vous pouvez maintenant entrer la valeur calorifique que vous souhaitez et il renvoie 1 résultat
Asone Tuhid

1

Haskell , 377 364 358 318 312 270 265 262 256 251 octets

import System.Random
f h|x<-[n|(n,(a,b,c))<-zip(lines"Gas Giant\nIce\nIce Giant\nGaia class\nDense Atmosphere\n
Desert\nIron\nLava")$zip3[4,4,4,5,7,7,7,10][9,6,6,7,9,10,10,11][15,10,10,10,10,25,14,6],h<=
b,h>=a,_<-[1..c]]=(x!!)<$>randomRIO(0,length x-1)

(J'ai ajouté des sauts de ligne pour une meilleure impression). La tâche dit "return", pas "print", donc fc'est une fonction qui renvoie le nom de planète sélectionné au hasard dans la IOmonade,f :: Int -> IO String .

Le mainest main = do {f 10 >>= print}( conseils de golf Haskell dit qu'il ne compte pas). Impressions

"Iron"     -- or "Desert", or "Lava"

(modifications: enlevé &le cas de base de », déplacé mainsur, changé en quadruplets et unzip, et sont passés à des gardes de motifs et >>=suivant les suggestions de Laikoni , grâce !; a mis en œuvre l'approche de la solution gelée au lieu, répéter les noms, le type explicite n'est plus nécessaire , un autre conseil par Laikoni enregistre 3 octets de plus, fait une IOfonction, mis en œuvre des conseils de la salle de chat).

Essayez-le en ligne!


Agréable! Pour éviter d’inonder les commentaires, vous pouvez rejoindre le salon de discussion Haskell Of Monads and Men pour discuter plus en détail de votre réponse.
Laikoni

0

Java 8, 398 384 octets

n->{String r="",a[];for(String x:"456789~Gas Giant~15;456~Ice~10;456~Ice Giant~10;567~Gaia class~10;789~Dense Atmosphere~10;78910~Desert~25;78910~Iron~14;1011~Lava~6".split(";"))if(x.split("~")[0].contains(n))r+=x+";";long t=0,u=0;for(String x:(a=r.split(";")))t+=new Long(x.split("~")[2]);t*=Math.random();for(String x:a)if((u+=new Long((a=x.split("~"))[2]))>t)return a[1];return"";}

On peut certainement jouer un peu plus, mais la probabilité en combinaison avec Strings n’est pas très facile en Java.

Explication:

Essayez-le en ligne.

n->{                // Method with String as both parameter and return-type
  String r="",      //  Temp-String, starting empty
         a[];       //  Temp String-array
  for(String x:"456789~Gas Giant~15;456~Ice~10;456~Ice Giant~10;567~Gaia class~10;789~Dense Atmosphere~10;78910~Desert~25;78910~Iron~14;1011~Lava~6".split(";"))
                    //  Loop over the String-parts in the format "heats~type~probability"
    if(x.split("~")[0].contains(n))
                    //   If the heats contains the input
      r+=x+";";     //    Append this entire String-part to the temp-String `r`
  long t=0,u=0;     //  Temp numbers, both starting empty
  for(String x:(a=r.split(";")))
                    //  Loop over the temp-String parts:
    t+=new Long(x.split("~")[2]);
                    //   Sum their probabilities
  t*=Math.random(); //  Get a random number in the range [0,sum_of_probabilities)
  for(String x:a)   //  Loop over the temp-String parts again
    if((u+=new Long((a=x.split("~"))[2]))>t)
                    //   The moment the current probability-sum is > the random number
      return a[1];  //    Return the Type of planet
  return"";}        //  Mandatory return we won't encounter (which returns nothing)

0

Min , 280 277 octets

:a ' =b (("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)) (=n (a n 1 get >= a n 2 get <= and) ((n 0 get b append #b) n 3 get times) when) foreach b b size random get

Commence avec de la chaleur sur la pile, laisse une chaîne sur la pile. Même processus général que la réponse Python 2.

Explication

Notez que min est concaténatif

:a ' =b                               ;Set the value on the stack (heat) to a, set empty quot to b
(("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)) ;Data to be iterated over
(=n                                   ;  set n to current item
 (a n 1 get >= a n 2 get <= and)      ;    check if n is between the min (2nd elment of n) and max (3rd element of n) heat
 (
  (n 0 get b append #b) n 3 get times ;      insert the name(1st element of n) into the quot of names (b) a number of times corresponding to the 4th element of n
 ) when                               ;    when the previous check is true
) foreach                             ;  for every quot in previous data
b b size random get                   ;choose a random element from the list of names

0

PowerShell, 56 + 135 (fichier CSV) + 1 (nom du fichier) = 192 octets

param($z)ipcsv a|?{$z-in$_.m..$_.x}|%{,$_.p*$_.r}|Random

Essayez-le en ligne! (Il s'agit d'une version légèrement modifiée qui crée le fichier CSV temporaire décrit ci-dessous.)

Importe un fichier CSV en utilisant ipcsv(en abrégé Import-CSV) nommé adans le répertoire local qui contient les éléments suivants:

P,m,x,r
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

Cela crée automatiquement une hashtable itérable de choses comme:

@{P=Gas Giant; m=4; x=9; r=15}
@{P=Ice; m=4; x=6; r=10}
...

Nous utilisons ensuite Where-Object( ?) pour extraire les entrées où notre entier d’entrée $zest -inla plage $_.mde $_.x(c’est- à -dire qu’il se situe dans la plage de chaleur). Nous pompons ensuite ces éléments dans une Foreach-Objectboucle ( %) qui crée un tableau de chaînes de noms basé sur la chance aléatoire de ces noms. Par exemple, cela créera un tableau de 15 "Gas Giant"chaînes si cette chaleur correspond. Nous mettons ensuite ceux dans Get-Randomlesquels tirera la chaîne appropriée avec la pondération appropriée.


-1

PHP , 1236 octets

<?php
$heat = (int)fgets(STDIN);
$planets =
    [
        'Gas Giant' =>        ['heat_min' => 4, 'heat_max' => 9, 'selection_chance' => 15],
        'Ice' =>              ['heat_min' => 4, 'heat_max' => 6, 'selection_chance' => 10],
        'Ice Giant' =>        ['heat_min' => 4, 'heat_max' => 6, 'selection_chance' => 10],
        'Gaia class' =>       ['heat_min' => 5, 'heat_max' => 7, 'selection_chance' => 10],
        'Dense Atmosphere' => ['heat_min' => 7, 'heat_max' => 9, 'selection_chance' => 10],
        'Desert' =>           ['heat_min' => 7, 'heat_max' => 10, 'selection_chance' => 25],
        'Iron' =>             ['heat_min' => 7, 'heat_max' => 10, 'selection_chance' => 14],
        'Lava' =>             ['heat_min' => 10, 'heat_max' => 11, 'selection_chance' => 6],
    ];
foreach ($planets as $planet) {
    $chance_sum += ($heat >= $planet['heat_min'] && $heat <= $planet['heat_max']) * $planet['selection_chance'];
}
while (true) {
    foreach ($planets as $name => $planet) {
        $prob = 100 * ($heat >= $planet['heat_min'] && $heat <= $planet['heat_max']) * $planet['selection_chance'] / $chance_sum;
        if (rand(0, 100) < $prob) {
            echo $name."\n";
            exit;
        }
    }
}
?>

Essayez-le en ligne!


5
Les réponses à la question code-golf doivent montrer l’effort de golfeur. Vous pouvez raccourcir ce délai en supprimant simplement les espaces . La prochaine étape consisterait à raccourcir les noms de variables en noms à un seul caractère.
ovs
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.