Crie um sistema solar

39

Introdução

Isso se baseia em um problema real que recentemente enfrentei ao criar um jogo de computador e achei que seria uma boa rodada de .

Existem sete classes espectrais principais de estrelas que emitem quantidades variáveis ​​de calor. A geologia dos planetas ao redor de uma estrela é grandemente influenciada pela quantidade de calor recebido da estrela, que é um fator de classe espectral e distância da estrela. Portanto, Mercúrio é praticamente derretido, Netuno congelado.

A galáxia do meu jogo é gerada proceduralmente e a seleção aleatória de tipos de planeta para determinadas estrelas acabou sendo um verdadeiro 'inferno de afirmações'!

O desafio

Seu método deve selecionar um planeta a partir de uma lista de tipos de planeta apropriados para a classe de estrela, com base em um limite mínimo de calor, um limite máximo de calor e um número aleatório. Por simplicidade, esse desafio usará apenas uma estrela da classe G, assim como o nosso sol.

Entradas

Um número inteiro heatno intervalo de 4 a 11, representando a quantidade de calor recebido pelo planeta da estrela.

Variáveis

Esta tabela mostra os possíveis planetas com base em heat. Seu método deve primeiro restringir as opções disponíveis com base no calor mínimo e no calor máximo, heatdeve cair sobre ou entre os dois. Por exemplo, com um calor de 10 passado, as únicas opções seriam Deserto, Ferro 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

Em seguida, a probabilidade de um planeta (nas demais opções) ser escolhida são suas chances aleatórias divididas pela soma das chances aleatórias de todas as opções.

No exemplo acima, a probabilidade de ferro ser escolhido é 14/(25+14+6).

Saída

Retorne o tipo de planeta como uma string.

Faça o melhor que puder para evitar pontas de flechas lógicas. O código mais curto ganha, aponta para a criatividade. Feliz golfe!

Absinto
fonte
A "classe" da "classe Gaia" deve ser maiúscula como tudo o mais?
Jonathan Allan
@JonathanAllan é minúsculo, pois não é um substantivo próprio #
Absinthe
1
@Absinthe Então porque é densa A tmosphere maiúscula?
Erik the Outgolfer
17
... alguém disse isso? | Bem-vindo ao PPCG e bom primeiro desafio!
user202729
3
@EricDuminil, também conhecido como anti-padrão de ponta de flecha, também conhecido como inferno aninhado se! wiki.c2.com/?ArrowAntiPattern
Absinto

Respostas:

12

Geléia , 78 bytes

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

Um link monádico que aceita um número inteiro (em [4,11] ) que retorna uma lista de caracteres.

Experimente online!

Quão?

Cria os intervalos de calor dos planetas como uma lista de listas e conta as ocorrências do calor de entrada nessas listas para obter uma lista de zeros e aqueles que representam os tipos de planeta possíveis e, em seguida, multiplica pelos números de probabilidade dos oito tipos de planeta. obtenha a distribuição. A distribuição é usada para repetir os nomes dos tipos de planeta e, finalmente, uma escolha aleatória uniforme é feita.

“'ĖøÆḳƙ’ḃ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
Jonathan Allan
fonte
Louco! Bem feito.
Absinto
@ Absinto Você pode simplesmente votar. Nota lateral: No Code Golf, normalmente não aceitamos respostas.
user202729
2
@ user202729 Vou adicionar votos em um dia ou dois. Eu estava olhando a página do GitHub para Jelly tentando desvendar esse código. Eu acredito louco! é :) mais adequado
Absinthe
2
@Absinthe sim, eu acredito que uma parte descritiva é muitas vezes uma boa coisa para ter, mesmo para apresentações de linguagem não-esotéricos :)
Jonathan Allan
3
Vocês são verdadeiramente loucos.
Selvek
7

R , 225 223 183 bytes

Agradeço a Giuseppe pela refatoração inteligente para reduzi-lo a 188 bytes; os cinco restantes foram eliminados usando representações numéricas menos redundantes.

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

Experimente online!

rturnbull
fonte
Essa é uma abordagem agradável, eu pode ter que pensar sobre como remover o meu caso labirinto declaração se favorável a esta em C # :)
Absinthe
Eu suspeito salvando o índice lógico ao invés de usar with, data.framee subsetserá mais curto.
Giuseppe
2
188 bytes
Giuseppe
@ Giuseppe, você provavelmente pode ganhar mais alguns bytes usando alguns dos meus truques com dados do planeta , mas acho que também melhorarei o meu usando sua ideia de separar o vetor de probabilidades do restante dos dados.
26418 Kirill L.
4

JavaScript 212

Editar 6 bytes salvar 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]]

menos golfe

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

Teste

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>

edc65
fonte
Um par de sua base de 16 números são 1 fora (deve ser [3913, 2630, 2630, 2647, 2681, 6522, 3706, 1707])
Jonathan Allan
Eu acho (mas não sou 100%) que você pode salvar 2 substituindo (z/16&15)por z/16&15. Independentemente disso, você pode salvar 6 bytes usando uma compressão base 8 com deslocamentos de três e seis ... uso [971,648,648,657,675,1636,932,445]com z/8&7+3, z%8+6e z>>6:)
Jonathan Allan
@JonathanAllan offsets!
Boa
@JonathanAllan eu preciso suportes para (z/8&7)+4porque &tem prioridade menor - seria7/8&(7+4)
edc65
1
@ Shaygy, você viu o comentário logo acima do seu? (longa história curta: não)
edc65 26/02
4

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

Experimente online!

Uma porta Python teria 203 200 bytes de comprimento:

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*

Experimente online!

ovs
fonte
1
Curiosamente, no momento da redação deste artigo, sua porta Python supera todas as outras soluções Python!
26418 Kirill L.
4

Carvão , 115 111 bytes

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

Experimente online! Link é a versão detalhada do código. Editar: salvou 4 bytes graças a @ ASCII-only. Explicação:

≔I⁻N³θ

Subtraia 3 da entrada para que possa ser comparado com dígitos únicos.

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

Divida a string 0715 0410 0410 1510 3710 3825 3814 696em espaços (os espaços parecem compactados melhor que vírgulas, mas eu não tentei nenhum outro caractere) e faça um loop sobre cada parte.

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

Compare a entrada com o primeiro e o segundo dígitos e, se estiver entre, pressione o índice do loop o número de vezes especificado para a lista vazia predefinida, preenchendo-a.

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

Divida a lista de planetas em novas linhas (novamente, melhor do que vírgulas por algum motivo) e selecione o elemento correspondente a um índice escolhido aleatoriamente na lista.

Neil
fonte
Agradável. Como o Random (u) fator nas diferentes probabilidades para cada planeta? (Não sei nada sobre carvão vegetal).
Absinto
Ele está escolhendo um índice de uma lista com a distribuição correta dos índices planetType devido ao "enviar o índice do loop o número de vezes especificado para a lista vazia predefinida, preenchendo-o". depois, use o índice escolhido para obter o nome de planetType.
Jonathan Allan
@JonathanAllan Entendi, obrigado #
Absinthe
111 bytes , eu acho? Em geral, apenas tente usar caracteres anteriores na classe de caracteres, consulte a compressão nº 11. Ordem padrão salva outro byte, mas isso é basicamente somente se você tiver apenas símbolos
ASCII-only
@ Somente ASCII Claro como lama ... por que as linhas novas são melhores lá, mas há espaços para a outra string?
Neil
3

R , 196 193 190 175 171 bytes

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

Experimente online!

Inicialmente inspirado por esta solução por @rturnbull, no entanto, como as duas apresentações evoluíram significativamente, agora isso é essencialmente uma mistura de idéias do autor original, @Giuseppe, que tem sido muito útil nos comentários e no meu. Aqui está um resumo dos pontos principais que ajudaram a diminuir a contagem de bytes:

  • Codificando dados do planeta como CSV Coletando nomes com readLinespara evitar o grande número de caracteres de cotação em torno de cadeias.

  • Ajustando os parâmetros de calor para que pudéssemos usar sinais <e >sinais em vez de <=e >=.

  • Alterando o formato dos dados de aquecimento de Heat min, Heat maxpara Heat min, Heat Deltapara se livrar dos números de dois dígitos.
    Substituído pela mudança de todos os números por -3

  • Dividir todas as probabilidades do planeta por 5, o que também resulta em alguns dígitos a menos.

  • Multiplicar o vetor de probabilidades do planeta pelo vetor de booleanos (indicando se nossa entrada atende aos requisitos de calor) para anular as probabilidades de planetas inadequados.

Provavelmente, mais alguns bytes poderiam ser obtidos com a aplicação de algum tipo de compactação de dados.
Eu acho que não mais.

Kirill L.
fonte
1
t=em vez de, text=também salvará 3 bytes.
Giuseppe
1
169 bytes
Giuseppe
resposta sólida, porém, usando read.csvuma única coluna sugeriu readLinespara se livrar das citações inteiramente, embora você tem que definir explicitamenten
Giuseppe
@ Giuseppe, são 171 bytes, pois você também removeu os parênteses necessários para manter a precedência do operador, e sua versão fornece probabilidades incorretas. Ainda assim, uma sugestão brilhante!
Kirill L.
Oh eu me perguntava onde esses parênteses tinha vindo ....
Giuseppe
3

Python, 282 bytes , 261 bytes:

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)

Bastante simples - quase certo de que poderia jogar mais - Ainda está procurando uma maneira melhor de representar a faixa do planeta e os dados de probabilidade. Se i estiver no intervalo do tipo de planeta, anexa-o à lista de acordo com a probabilidade e imprime aleatoriamente um.

EDIT: Com crédito para Jonathan Frech - refiz o loop for para eliminar alguns bytes. Melhor maneira de anexar itens à lista

Chromane
fonte
3
Bem-vindo ao PPCG! Não sei como você contou os bytes, mas estou recebendo apenas 283. Menos se esse recuo for uma guia em vez de 4 bytes.
Martin Ender
1
Isso não i in range(x[1], x[2])exclui a borda superior do calor, ao contrário da especificação?
Graipher
1
270 bytes .
Jonathan Frech
1
Isso poderia ser de alguma ajuda? 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)]
BigodeMoses
1
@ Chromane Desculpas, parece que os comentários retiraram alguns caracteres.
BigodeMoses
2

Oitava com pacote de estatísticas, 178 176 174 158 bytes

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

O código define uma função anônima que insere um número e gera uma string.

Experimente online!

Explicação

O código

@(h)

define uma função anônima com entrada h.

A corda

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

é dividido em vírgulas usando

strsplit(...,',')

O resultado é uma matriz de células de cadeias, onde cada cadeia é uma classe de planeta.

O código

'IIIJLLLO'-70

define a string mostrada e subtrai 70os pontos de código de seus caracteres. Isso fornece a matriz de valores mínimos de calor menos 1 , ou seja [3 3 3 4 6 6 6 9],.

Similarmente,

'PMMNPQQR'-70

produz a matriz de valores máximos de calor mais 1 , ou seja [10 7 7 8 10 11 11 12],.

As comparações

h>...&h<...

dar uma matriz contendo true ou falseindicando quais classes de planeta são possíveis.

Por outro lado,

'UPPPP_TL'-70

define a matriz de valores de chance aleatórios, [15 10 10 10 10 25 14 6] ,.

A operação

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

é a multiplicação por elementos dos dois últimos arrays ( truee falsese comporta como 0e 1respectivamente). Isso fornece uma matriz em que cada classe de planeta tem sua chance aleatória ou0 se essa classe não é possível com base na entrada. Essa matriz será usada como pesos na amostragem aleatória

A chamada de função

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

seleciona uma das células da matriz de células (primeiro argumento de entrada), usando a matriz calculada de pesos (quarto argumento de entrada). Especificamente, a função randsamplenormaliza automaticamente os pesos para probabilidades e, em seguida, faz a seleção aleatória com essas probabilidades. O resultado é uma matriz de células que contém uma sequência. O código

{1}

é usado para extrair essa sequência, que constitui a saída da função.

Luis Mendo
fonte
2
Ótima explicação, obrigado. Ótima pontuação também.
Absinto
2

Python 3 , 263 bytes

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

Experimente online!

MooseOnTheRocks
fonte
1

Perl 5 ( -p), 230 bytes

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

Experimente online!

Xcali
fonte
Se você remover um dos min heats e adicionar um aos max heats (que daria em [Ice,4,5,11]vez de [Ice,4,6,10]etc), poderá usar em <vez de <=e em >vez de >=, economizando 2 bytes. (sim, isso não é muito ...)
Dadá
1

Nim , 314 298 294 bytes

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

Para loop agora em uma linha, sem retorno, menos bytes para o tipo implícito

4 espaços removidos (obrigado Kevin )

Experimente online!

Panda0nEarth
fonte
Eu nunca programei Nim, mas acho que você pode jogar golfe em quatro espaços: um em for n in[(; e três em if h>=n[1]and h<=n[2].
Kevin Cruijssen
1

05AB1E , 78 76 bytes

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

Experimente online!

Explicação

”Œï²°™Ä²° Gaia classêη•™Äµ‰Ÿ± Lava”
empurra a 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
Emigna
fonte
1

Python 3, 199 194 bytes

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

Dividir hem máscaras de bits separadas e valores de chance aleatórios (consulte a explicação) economiza alguns bytes, eliminando uma atribuição he simplificando a range()compreensão na lista.

Solução anterior

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

Define uma função anônima que recebe um int e retorna o tipo de planeta.

Para cada tipo de planeta, um valor de 13 bits foi calculado. Os 8 bits superiores definem uma máscara de bit de valores de calor válidos para esse tipo de planeta. Os 5 bits inferiores são a chance aleatória desse tipo de planeta. Por exemplo, "classe Gaia" é um tipo válido para os valores de calor 4 a 7, portanto, possui uma máscara de 0b00001111. Tem uma chance aleatória de 10 ou 0b01010. Combiná-los resulta no valor de 13 bits 0b0000111101010para o tipo "classe Gaia". Os valores de 13 bits para cada tipo de planeta são concatenados para obter o valor parah (os 13 bits mais baixos são para o tipo de planeta "Ice"). (A resposta mais recente não combina esses valores).

A compreensão da lista itera sobre os valores de 13 bits para criar uma lista de pesos, onde o peso é a chance aleatória se o tipo de planeta for uma opção válida para o valor de calor fornecido e, caso contrário, zero. Para cada tipo de planeta, (h>>i&31)extrai a chance aleatória desse tipo de planeta. (h>>i+n+1&1)avalia para 1 se o tipo de planeta é uma opção válida para o valor do calor ne avalia para 0 caso contrário.

A função de biblioteca random.choices(choices, weights)seleciona um item da lista de opções com base na lista de pesos.

RootTwo
fonte
i+n+1pode ser i-~n. TIO
ovs 27/02
1

Ruby , 214193 bytes

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

Experimente online!

Asone Tuhid
fonte
Desculpe, mas não recebo a saída. Seria o primeiro item da lista?
Absinto
@ Absinthe eu adicionei alguns títulos, verifique novamente. São todos os níveis de calor de 4 a 11 e um planeta gerado aleatoriamente para cada um
Asone Tuhid
Ah, entendi obrigado, embora, idealmente, deva haver apenas uma saída de cadeia de caracteres
Absinthe
@Absinthe Você está certo, que era apenas o meu próprio código de teste, agora você pode introduzir o valor de calor que você quer e ele retorna 1 resultado
asone Tuhid
1

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

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)

(Adicionei quebras de linha para obter uma impressão melhor). A tarefa diz "retornar", não "imprimir", assim fcomo uma função que retorna o nome do planeta selecionado aleatoriamente na IOmônada f :: Int -> IO String,.

O mainé main = do {f 10 >>= print}( dicas de golfe Haskell diz que não conta). Impressões

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

(edições: &caso base removido ; movido mainpara fora; alterado para quádruplos e unzip, e mudou para guardas de padrões e >>=seguindo as sugestões de Laikoni , obrigado!; implementou a abordagem da solução Jelly , repetindo os nomes; o tipo explícito não é mais necessário ; outro conselho de Laikoni economiza mais 3 bytes; transformou-o em uma IOfunção; conselho implementado da sala de bate-papo).

Experimente online!

Will Ness
fonte
Agradável! Para evitar inundar os comentários, você pode entrar na sala de bate-papo Haskell Of Monads and Men para discutir melhor sua resposta.
Laikoni
0

Java 8, 398384 bytes

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

Definitivamente, pode ser jogado um pouco mais, mas a probabilidade em combinação com o Strings não é muito fácil em Java.

Explicação:

Experimente 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)
Kevin Cruijssen
fonte
0

Mínimo , 280 277 bytes

: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

Começa com o calor na pilha, deixa um barbante na pilha. O mesmo processo geral da resposta do Python 2.

Explicação

Observe que 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
Panda0nEarth
fonte
0

PowerShell, 56 + 135 (arquivo CSV) + 1 (nome do arquivo) = 192 bytes

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

Experimente online! (esta é uma versão ligeiramente modificada que cria o arquivo CSV temporário descrito abaixo)

Importa um arquivo CSV usando ipcsv(abreviação de Import-CSV) nomeado ano diretório local que contém o seguinte:

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

Isso cria automaticamente uma hashtable iterável de coisas como as seguintes:

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

Em seguida, usamos Where-Object( ?) para retirar as entradas onde o nosso inteiro de entrada $zé -ina gama $_.mde $_.x(ou seja, é na faixa de calor). Em seguida, os bombeamos para um Foreach-Objectloop ( %) que cria uma matriz de cadeias de nomes com base na chance aleatória desses nomes. Por exemplo, isso criará uma matriz de 15 "Gas Giant"seqüências de caracteres se esse calor corresponder. Em seguida, colocamos as Get-Randomque puxam a corda apropriada com a ponderação apropriada.

AdmBorkBork
fonte
-1

PHP , 1236 bytes

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

Experimente online!

Agnius Vasiliauskas
fonte
5
As respostas à questão do código-golfe precisam mostrar esforço para jogá-las. Você pode obter isso muito mais curto removendo o espaço em branco . O próximo passo seria reduzir nomes de variáveis ​​para nomes de caracteres únicos.
ovs 25/02