Crea un sistema solare


39

Intro

Questo si basa su un problema reale che ho riscontrato di recente durante la realizzazione di un gioco per computer e ho pensato che sarebbe stato un bel giro di .

Esistono sette principali classi spettrali di stelle che emettono quantità variabili di calore. La geologia dei pianeti attorno a una stella è fortemente influenzata dalla quantità di calore ricevuto dalla stella, che è un fattore di classe spettrale e distanza dalla stella. Quindi il mercurio è praticamente fuso, congelato Nettuno.

La galassia nel mio gioco è generata proceduralmente e la selezione casuale dei tipi di pianeta per determinate stelle si è rivelata un vero e proprio "inferno di dichiarazione"!

La sfida

Il tuo metodo dovrebbe selezionare un pianeta da un elenco di tipi di pianeta appropriati per la classe di stelle, in base a una soglia minima di calore, una soglia massima di calore e un numero casuale. Per semplicità questa sfida utilizzerà solo una stella di classe G, proprio come il nostro sole.

ingressi

Un numero intero heatcompreso tra 4 e 11 che rappresenta la quantità di calore ricevuta dal pianeta dalla stella.

variabili

Questa tabella mostra i possibili pianeti basati su heat. Il tuo metodo dovrebbe prima restringere le scelte disponibili in base al minimo di riscaldamento e al massimo di calore, heatdovrebbe cadere su o tra i due. Ad esempio, con un calore di 10 passati nelle uniche scelte sarebbero Desert, Iron e 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

Successivamente, la probabilità che un pianeta (nelle restanti scelte) venga scelto sono le sue possibilità casuali divise per la somma delle probabilità casuali di tutte le scelte.

Nell'esempio sopra, la probabilità di scegliere il ferro è 14/(25+14+6).

Produzione

Restituisce il tipo di pianeta come stringa.

Fai del tuo meglio per evitare punte di freccia logiche. Il codice più corto vince, punti a tutto tondo per la creatività. Buon golf!


La "classe" di "classe Gaia" dovrebbe essere capitalizzata come tutto il resto?
Jonathan Allan,

@JonathanAllan è in minuscolo in quanto non è un nome proprio
Assenzio

1
@Absinthe Allora perché è denso Un tmosphere maiuscolo?
Erik the Outgolfer,

17
... qualcuno l'ha detto? | Benvenuto in PPCG e bella prima sfida!
user202729,

3
@EricDuminil aka un anti-pattern a punta di freccia, noto anche come inferno nidificato-if-if! wiki.c2.com/?ArrowAntiPattern
Assenzio

Risposte:


12

Gelatina , 78 byte

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

Un collegamento monadico che accetta un numero intero (in [4,11] ) che restituisce un elenco di caratteri.

Provalo online!

Come?

Crea gli intervalli di calore dei pianeti come un elenco di elenchi e conta le occorrenze del calore in ingresso in quegli elenchi per ottenere un elenco di zeri e di quelli che rappresentano i tipi di pianeta possibili, quindi si moltiplica per i numeri di probabilità degli otto tipi di pianeta per ottenere la distribuzione. La distribuzione viene utilizzata per ripetere i nomi dei tipi di pianeta e infine viene fatta una scelta casuale uniforme.

“'ĖøÆḳƙ’ḃ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

Pazzo! Molto bene.
Assenzio

@Absinthe Puoi semplicemente votare. Nota a margine: su Code Golf in genere non accettiamo risposte.
user202729

2
@ user202729 Aggiungerò i voti tra un giorno o due. Stavo guardando la pagina GitHub per Jelly che cercava di svelare questo codice. Credo pazzo! è il più appropriato :)
Assenzio

2
@Absinthe sì, credo che una sezione descrittiva sia spesso una buona cosa anche per le presentazioni in lingua non esoterica :)
Jonathan Allan,

3
Siete davvero pazzi.
Selvek,

7

R , 225 223 183 byte

Grazie a Giuseppe per il refactoring intelligente per portarlo fino a 188 byte; i restanti cinque sono stati rasati utilizzando rappresentazioni numeriche meno ridondanti.

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

Provalo online!


Questo è un approccio gradevole, potrei dover pensare a rimuovere il mio labirinto if statement se favorisco questo in C # :)
Assenzio

Ho il sospetto che il salvataggio l'indice logica piuttosto che usare with, data.framee subsetsarà più breve.
Giuseppe,


@Giuseppe, probabilmente puoi guadagnare qualche byte in più usando alcuni dei miei trucchi con i dati del pianeta , ma penso che migliorerò anche i miei usando la tua idea di separare il vettore delle probabilità dal resto dei dati.
Kirill L.,

4

JavaScript 212

Modifica 6 byte salva grazie a 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]]

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

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>


Un paio dei tuoi 16 numeri di base sono 1 di sconto (dovrebbe essere [3913, 2630, 2630, 2647, 2681, 6522, 3706, 1707])
Jonathan Allan

Penso che (ma non sono al 100%) puoi salvarne 2 sostituendoli (z/16&15)con z/16&15. Indipendentemente da ciò, è possibile risparmiare 6 byte utilizzando una compressione base 8 con offset di tre e sei ... l'uso [971,648,648,657,675,1636,932,445]con z/8&7+3, z%8+6e z>>6:)
Jonathan Allan

Offset @JonathanAllan! Ottima idea, grazie
edc65

@JonathanAllan ho bisogno di parentesi (z/8&7)+4perché &ha una priorità più bassa - sarebbe7/8&(7+4)
edc65

1
@Shaggy hai visto il commento proprio sopra il tuo? (per
farla

4

Cocco , 214 195 byte

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)

Provalo online!

Una porta Python sarebbe lunga 203 200 byte:

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*

Provalo online!


1
È interessante notare che, al momento della scrittura, la tua porta Python batte tutte le altre soluzioni Python!
Kirill L.,

4

Carbone , 115 111 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Modifica: salvato 4 byte grazie solo a @ ASCII. Spiegazione:

≔I⁻N³θ

Sottrai 3 dall'input in modo che possa essere confrontato con singole cifre.

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

Dividi la stringa 0715 0410 0410 1510 3710 3825 3814 696sugli spazi (gli spazi sembrano comprimersi meglio delle virgole ma non ho provato nessun altro personaggio) e passa su ogni porzione.

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

Confrontare l'input con la prima e la seconda cifra e, se presente, premere l'indice del ciclo per un determinato numero di volte nell'elenco vuoto predefinito, popolandolo.

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

Dividi l'elenco dei pianeti su newline (di nuovo, meglio delle virgole per qualche motivo) e seleziona l'elemento corrispondente a un indice scelto casualmente dall'elenco.


Ben fatto. In che modo il fattore casuale (u) tiene conto delle diverse probabilità per ciascun pianeta? (Non so nulla del carbone).
Assenzio

Sta scegliendo un indice da un elenco con la corretta distribuzione degli indici planetType grazie al "push the loop index il dato numero di volte all'elenco vuoto predefinito, popolandolo così". quindi utilizzando l'indice scelto per ottenere il nome planetType.
Jonathan Allan,

@JonathanAllan Capito, grazie
Assenzio

111 byte , penso? In generale, prova a utilizzare i caratteri in precedenza nella classe di caratteri, vedi la compressione n. 11. L'ordine predefinito salva un altro byte, ma in pratica è solo se si hanno solo simboli
solo ASCII il

@ ASCII-Clear Clear as mud ... perché le newline sono migliori lì, ma gli spazi per l'altra stringa?
Neil,

3

R , 196 193 190 175 171 byte

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

Provalo online!

Inizialmente ispirato da questa soluzione di @rturnbull, tuttavia, poiché entrambe le osservazioni si sono evolute in modo significativo, questo è essenzialmente un mix di idee dell'autore originale, @Giuseppe, che è stato molto utile nei commenti e nel mio. Ecco un riepilogo dei punti chiave che hanno contribuito a ridurre il conteggio dei byte:

  • Codifica dei dati del pianeta come CSV Raccolta di nomi con readLinesper evitare il gran numero di caratteri di virgolette attorno alle stringhe.

  • Ottimizzare i parametri di calore in modo che potessimo usare <e >segni al posto di <=e >=.

  • Modifica del formato dei dati di riscaldamento da Heat min, Heat maxa Heat min, Heat Deltaper eliminare i numeri a doppia cifra.
    Sostituito spostando tutti i numeri di -3

  • Dividendo tutte le probabilità del pianeta per 5, il che si traduce anche in poche cifre in meno.

  • Moltiplicare il vettore delle probabilità del pianeta con il vettore dei booleani (indicando se il nostro input soddisfa i requisiti di calore) per annullare le probabilità dei pianeti non idonei.

Probabilmente, è possibile ottenere qualche byte in più applicando una sorta di compressione dei dati.
Penso non più.


1
t=invece di text=salverà anche 3 byte.
Giuseppe,


risposta solida, però, usando read.csvper una singola colonna suggerito readLinesdi eliminare completamente le virgolette, anche se è necessario impostare esplicitamenten
Giuseppe

@Giuseppe, però, sono 171 byte, poiché hai rimosso anche le parentesi necessarie per mantenere la precedenza dell'operatore e la tua versione offre probabilità errate. Comunque, un suggerimento geniale!
Kirill L.,

Oh, mi chiedevo da dove provenissero quelle parentesi ...
Giuseppe,

3

Python, 282 byte , 261 byte:

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)

Abbastanza semplice - abbastanza sicuro che potrebbe essere giocato a golf di più - Ancora alla ricerca di un modo migliore per rappresentare la gamma del pianeta e i dati di probabilità. Se sono nel raggio del tipo di pianeta, lo accludo all'elenco in base alla probabilità, quindi ne stampa uno a caso.

EDIT: Con il merito a Jonathan Frech - ha ripetuto il ciclo for per eliminare alcuni byte. Modo migliore di aggiungere elementi all'elenco


3
Benvenuti in PPCG! Non sono sicuro di come hai contato i byte, ma sto ottenendo solo 283. Meno se quell'indentazione è una scheda anziché 4 byte.
Martin Ender,

1
Non i in range(x[1], x[2])esclude il bordo superiore del calore, a differenza delle specifiche?
Graipher


1
Potrebbe essere di aiuto? 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)]
Moustache: il

1
@Chromane Mi scuso sembra che i commenti abbiano messo a nudo alcuni personaggi.
Moustache:

2

Ottava con pacchetto statistico, 178 176 174 158 byte

@(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}

Il codice definisce una funzione anonima che immette un numero e genera una stringa.

Provalo online!

Spiegazione

Il codice

@(h)

definisce una funzione anonima con input h.

La stringa

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

viene diviso in virgole utilizzando

strsplit(...,',')

Il risultato è una matrice di celle di stringhe, in cui ogni stringa è una classe planetaria.

Il codice

'IIIJLLLO'-70

definisce la stringa mostrata e sottrae 70dai punti di codice dei suoi caratteri. Questo fornisce l'array di valori minimi di calore meno 1 , cioè [3 3 3 4 6 6 6 9].

Allo stesso modo,

'PMMNPQQR'-70

produce la matrice dei valori massimi di calore più 1 , ovvero [10 7 7 8 10 11 11 12].

I confronti

h>...&h<...

dare una matrice contenente true o falseindicando quali classi planetarie sono possibili.

D'altro canto,

'UPPPP_TL'-70

definisce la matrice di valori casuali di probabilità, [15 10 10 10 10 25 14 6] .

L'operazione

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

è la moltiplicazione in termini di elementi di questi ultimi due array ( truee si falsecomportano come 0e 1rispettivamente). Questo dà una matrice in cui ogni classe di pianeta ha la sua possibilità casuale o0 se tale classe non è possibile in base all'input. Questo array verrà utilizzato come pesi nel campionamento casuale

La chiamata di funzione

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

seleziona una delle celle dall'array di celle delle stringhe (primo argomento di input), utilizzando l'array di pesi calcolato (quarto argomento di input). In particolare, la funzione randsamplenormalizza automaticamente i pesi in base alle probabilità, quindi esegue la selezione casuale con tali probabilità. Il risultato è un array di celle contenente una stringa. Il codice

{1}

viene utilizzato per estrarre quella stringa, che costituisce l'output della funzione.


2
Ottima spiegazione, grazie. Ottimo anche il punteggio.
Assenzio

2

Python 3 , 263 byte

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

Provalo online!


1

Perl 5 ( -p), 230 byte

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

Provalo online!


Se ne rimuovi uno per i heats min e ne aggiungi uno per i heats max (che darebbe [Ice,4,5,11]invece di [Ice,4,6,10], ecc.) Allora sarai in grado di usare al <posto di <=e >invece di >=, risparmiando così 2 byte. (sì, non è molto ...)
Dada,

1

Nim , 314 298 294 byte

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

Per loop ora in una riga, nessun ritorno, meno byte al tipo implicito

4 spazi rimossi (grazie Kevin )

Provalo online!


Non ho mai programmato Nim, ma penso che tu possa giocare a golf quattro spazi: uno a for n in[(; e tre a if h>=n[1]and h<=n[2].
Kevin Cruijssen,

1

05AB1E , 78 76 byte

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

Provalo online!

Spiegazione

”Œï²°™Ä²° Gaia classêη•™Äµ‰Ÿ± Lava”
spinge la corda 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 byte

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

La suddivisione hin maschere di bit separate e valori casuali di probabilità (vedere la spiegazione) consente di risparmiare qualche byte eliminando un'assegnazione he semplificando ilrange() comprensione nell'elenco.

Soluzione precedente

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

Definisce una funzione anonima che accetta un int e restituisce il tipo di pianeta.

Per ogni tipo di pianeta, è stato calcolato un valore di 13 bit. I primi 8 bit definiscono una maschera di bit con valori di calore validi per quel tipo di pianeta. I 5 bit inferiori sono la possibilità casuale per quel tipo di pianeta. Ad esempio, "Classe Gaia" è un tipo valido per i valori di calore da 4 a 7, quindi ha una maschera di 0b00001111. Ha una probabilità casuale di 10, o 0b01010. Combinandoli si ottiene il valore a 13 bit 0b0000111101010per il tipo "Classe Gaia". I valori di 13 bit per ciascun tipo di pianeta sono concatenati per ottenere il valore perh (i 13 bit più bassi sono per il tipo di pianeta "Ghiaccio"). (La risposta più recente non combina questi valori).

La comprensione dell'elenco scorre sui valori a 13 bit per creare un elenco di pesi, in cui il peso è la possibilità casuale se il tipo di pianeta è una scelta valida per il valore di calore dato e zero in caso contrario. Per ogni tipo di pianeta, (h>>i&31)estrae la possibilità casuale per quel tipo di pianeta. (h>>i+n+1&1)valuta 1 se il tipo di pianeta è una scelta valida per il valore di calore ne valuta altrimenti 0.

La funzione di libreria random.choices(choices, weights)seleziona un elemento dall'elenco di scelte in base all'elenco dei pesi.


i+n+1può essere i-~n. TIO
Ovs

1

Rubino , 214 193 189 byte

->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}

Provalo online!


Spiacenti, non ho l'output, sarebbe il primo elemento nell'elenco?
Assenzio

@Absinthe ho aggiunto alcuni titoli, ricontrolla. Sono tutti i livelli di calore da 4 a 11 e un pianeta generato casualmente per ciascuno
Asone Tuhid,

Ah, lo capisco grazie, anche se idealmente dovrebbe esserci un solo output di stringa
Assenzio

@Absinthe Hai ragione, quello era solo il mio codice di prova, ora puoi inserire il valore di calore che desideri e restituisce 1 risultato
Asone Tuhid

1

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

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)

(Ho aggiunto interruzioni di riga per una stampa più gradevole). Il compito dice "ritorno", non "stampa", quindi fè una funzione che restituisce il nome pianeta scelto a caso nella IOMonade, f :: Int -> IO String.

Il mainè main = do {f 10 >>= print}( Haskell Golfing punte dice che non conta). stampe

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

(modifica: &caso base rimosso ; spostato mainfuori; cambiato in quadrupli e unzip, e passato alle protezioni dei motivi e >>=seguendo i suggerimenti di Laikoni , grazie !; ha invece implementato l'approccio dalla soluzione Jelly , ripetendo i nomi; il tipo esplicito non è più necessario ; un altro consiglio di Laikoni salva altri 3 byte; lo rende una IOfunzione; implementato un consiglio dalla chat room).

Provalo online!


Bello! Per evitare di inondare i commenti, puoi unirti alla chat room di Monads and Men di Haskell per discutere ulteriormente la tua risposta.
Laikoni,

0

Java 8, 398 384 byte

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"";}

Può sicuramente essere giocato a golf ancora un po ', ma la probabilità in combinazione con le stringhe non è molto facile in Java.

Spiegazione:

Provalo online.

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 byte

: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

Inizia con il calore in pila, lascia una stringa in pila. Stesso processo generale della risposta Python 2.

Spiegazione

Si noti che min è concatenativo

: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 (file CSV) + 1 (nome file) = 192 byte

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

Provalo online! (questa è una versione leggermente modificata che crea il file CSV temporaneo descritto di seguito)

Importa un file CSV utilizzando ipcsv(abbreviazione di Import-CSV) indicato anella directory locale che contiene quanto segue:

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

Ciò crea automaticamente un hashtable iterabile di cose come le seguenti:

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

Abbiamo quindi utilizzare Where-Object( ?) per estrarre le voci dove il nostro intero ingresso $zè -innell'intervallo $_.mdi $_.x(cioè, è in grado termico). Quindi li pompiamo in un Foreach-Objectloop ( %) che crea una matrice di stringhe di nomi in base alla probabilità casuale di quei nomi. Ad esempio, questo creerà una serie di 15 "Gas Giant"stringhe se quel calore corrisponde. Inseriamo quindi quelli in Get-Randomcui estrarranno la stringa appropriata con la ponderazione appropriata.


-1

PHP , 1236 byte

<?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;
        }
    }
}
?>

Provalo online!


5
Le risposte alla domanda di code-golf devono mostrare sforzo nel golfarle. Puoi ridurlo molto semplicemente rimuovendo gli spazi bianchi . Il prossimo passo sarebbe abbreviare i nomi delle variabili in nomi di singoli caratteri.
Ovs,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.