Crea un sistema solar


39

Introducción

Esto se basa en un problema real que enfrenté recientemente al hacer un juego de computadora y pensé que sería una buena ronda de de .

Hay siete clases espectrales principales de estrellas que emiten cantidades variables de calor. La geología de los planetas alrededor de una estrella está muy influenciada por la cantidad de calor recibido de la estrella, que es un factor de la clase espectral y la distancia de la estrella. Por lo tanto, Mercurio está prácticamente fundido, Neptuno congelado.

¡La galaxia en mi juego se genera de manera procesal y la selección aleatoria de tipos de planetas para estrellas dadas resultó ser un verdadero 'infierno de afirmación'!

El reto

Su método debe seleccionar un planeta de una lista de tipos de planetas apropiados para la clase de estrella, en función de un umbral de calor mínimo, un umbral de calor máximo y un número aleatorio. Para simplificar, este desafío solo utilizará una estrella de clase G, al igual que nuestro sol.

Entradas

Un número entero heaten el rango de 4 a 11 que representa la cantidad de calor recibido por el planeta desde la estrella.

Variables

Esta tabla muestra los posibles planetas basados ​​en heat. Su método primero debe reducir las opciones disponibles basadas en el calor mínimo y el calor máximo, heatdebe caer en o entre los dos. Por ejemplo, con un calor de 10 en las únicas opciones, sería Desierto, Hierro y 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

Luego, la probabilidad de que se elija un planeta (en las opciones restantes) es sus posibilidades aleatorias divididas por la suma de las posibilidades aleatorias de todas las opciones.

En el ejemplo anterior, la probabilidad de que se elija Hierro es 14/(25+14+6).

Salida

Devuelve el tipo de planeta como una cadena.

Haz lo mejor que puedas para evitar las puntas de flecha lógicas. El código más corto gana, apunta a la creatividad. ¡Feliz golf!


¿Debería capitalizarse la "clase" de "clase Gaia" como todo lo demás?
Jonathan Allan

@JonathanAllan es minúscula ya que no es un nombre propio
Absenta

1
@Absinthe Entonces, ¿por qué la tmosfera Densa A es mayúscula?
Erik the Outgolfer

17
... alguien ha dicho eso? El | ¡Bienvenido a PPCG, y buen primer desafío!
user202729

3
¡@EricDuminil, también conocido como un antipatrón de punta de flecha, también conocido como infierno anidado! wiki.c2.com/?ArrowAntiPattern
Absenta

Respuestas:


12

Gelatina , 78 bytes

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

Un enlace monádico que acepta un número entero (en [4,11] ) que devuelve una lista de caracteres.

Pruébalo en línea!

¿Cómo?

Crea los rangos de calor de los planetas como una lista de listas y cuenta las ocurrencias del calor de entrada en esas listas para obtener una lista de ceros y unos que representan qué tipos de planetas son posibles, luego se multiplica por los números de probabilidad de los ocho tipos de planetas para Obtenga la distribución. La distribución se utiliza para repetir los nombres de tipo de planeta, y finalmente se realiza una elección aleatoria 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

¡Loca! Bien hecho.
Absenta

@Absinthe Puedes simplemente votar. Nota al margen: en Code Golf generalmente no aceptamos respuestas.
user202729

2
@ user202729 Agregaré votos en un día o dos. Estaba buscando en la página de GitHub Jelly tratando de desentrañar este código. Yo creo loco! es lo más apropiado :)
Absenta

2
@Absinthe sí, creo que una sección descriptiva a menudo es algo bueno incluso para presentaciones de lenguaje no esotérico :)
Jonathan Allan

3
Ustedes son realmente locos.
Selvek

7

R , 225 223 183 bytes

Gracias a Giuseppe por su ingeniosa refactorización para reducirlo a 188 bytes; los cinco restantes se afeitaron usando representaciones 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])

Pruébalo en línea!


Ese es un buen enfoque, es posible que tenga que pensar en eliminar mi laberinto de declaraciones if a favor de esto en C # :)
Absenta

Sospecho salvar el índice lógico en lugar de utilizar with, data.framey subsetserá más corto.
Giuseppe


@Giuseppe, probablemente puedas ganar algunos bytes más usando algunos de mis trucos con los datos del planeta , pero creo que también mejoraré los míos usando tu idea de separar el vector de probabilidades del resto de los datos.
Kirill L.

4

JavaScript 212

Editar 6 bytes guardar gracias 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 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]
)

Prueba

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 par de sus 16 números base son 1 descuento (debería ser [3913, 2630, 2630, 2647, 2681, 6522, 3706, 1707])
Jonathan Allan

Creo (pero no estoy al 100%) que puede ahorrar 2 reemplazando (z/16&15)con z/16&15. De todos modos, puede guardar 6 bytes usando una compresión de base 8 con compensaciones de tres y seis ... usar [971,648,648,657,675,1636,932,445]con z/8&7+3, z%8+6y z>>6:)
Jonathan Allan

¡@JonathanAllan compensa! Gran idea, gracias
edc65

@ JonathanAllan Necesito paréntesis (z/8&7)+4porque &tiene menor prioridad, sería7/8&(7+4)
edc65

1
@ Shaggy, ¿viste el comentario justo encima del tuyo? (larga historia corta: no)
edc65

4

Coco , 214195 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)

Pruébalo en línea!

Un puerto de Python tendría 203 200 bytes de longitud:

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*

Pruébalo en línea!


1
Curiosamente, al momento de escribir, su puerto de Python supera a todas las demás soluciones de Python.
Kirill L.

4

De carbón , 115 111 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Editar: Guardado 4 bytes gracias a @ ASCII-only. Explicación:

≔I⁻N³θ

Resta 3 de la entrada para que pueda compararse con un solo dígito.

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

Divida la cadena 0715 0410 0410 1510 3710 3825 3814 696en espacios (los espacios parecen comprimirse mejor que las comas pero no probé ningún otro carácter) y repita cada porción.

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

Compare la entrada con el primer y el segundo dígito y, si está entre ellos, empuje el índice del bucle el número de veces dado a la lista vacía predefinida, llenándolo así.

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

Divida la lista de planetas en líneas nuevas (de nuevo, mejor que las comas por alguna razón) y seleccione el elemento correspondiente a un índice elegido al azar de la lista.


Buena esa. ¿Cómo el Random (u) factoriza las diferentes probabilidades para cada planeta? (No sé nada sobre el carbón).
Absenta

Está eligiendo un índice de una lista con la distribución correcta de los índices planetType debido al "empuje del índice de bucle el número dado de veces a la lista vacía predefinida, llenándolo así". luego usando el índice elegido para obtener el nombre de planetType.
Jonathan Allan

@JonathanAllan Lo tengo, gracias
Absenta

111 bytes , creo? En general, solo intente usar caracteres antes en la clase de caracteres, consulte la compresión n. ° 11. El pedido predeterminado guarda otro byte, pero eso es básicamente solo si solo tiene símbolos
solo ASCII

@ Solo ASCII Claro como el barro ... ¿por qué las líneas nuevas son mejores allí pero los espacios para la otra cadena?
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

Pruébalo en línea!

Inicialmente inspirado en esta solución por @rturnbull, sin embargo, dado que ambas presentaciones han evolucionado significativamente, ahora se trata esencialmente de una mezcla de ideas del autor original, @Giuseppe, que ha sido muy útil en los comentarios, y el mío. Aquí hay un resumen de los puntos clave que ayudaron a reducir la cuenta de bytes:

  • Codificación de datos del planeta como CSV Recopilación de nombres readLinespara evitar la gran cantidad de caracteres de comillas alrededor de las cadenas.

  • Ajustar los parámetros de calor para que podamos usar signos <y en >lugar de <=y >=.

  • Cambiar el formato de datos de calor de Heat min, Heat maxa Heat min, Heat Deltapara deshacerse de los números de dos dígitos.
    Reemplazado cambiando todos los números por -3

  • Dividiendo todas las probabilidades del planeta por 5, lo que también resulta en unos pocos dígitos menos.

  • Multiplicar el vector de probabilidades del planeta con el vector de booleanos (que indica si nuestra entrada satisface los requisitos de calor) para anular las probabilidades de planetas inadecuados.

Probablemente, se podrían obtener algunos bytes más aplicando algún tipo de compresión de datos.
Creo que ya no.


1
t=en lugar de text=guardará 3 bytes también.
Giuseppe


Sin embargo, una respuesta sólida, que se utiliza read.csvpara una sola columna, sugiere readLineseliminar las citas por completo, aunque debe establecer explícitamenten
Giuseppe

@Giuseppe, sin embargo, son 171 bytes, ya que también eliminó los paréntesis que eran necesarios para mantener la precedencia del operador, y su versión ofrece probabilidades incorrectas. Aún así, una sugerencia brillante!
Kirill L.

Oh, me preguntaba de dónde vendrían esos paréntesis ...
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 simple, bastante seguro de que se podría jugar más al golf. Todavía estoy buscando una mejor manera de representar el rango del planeta y los datos de probabilidad. Si estoy dentro del rango del tipo de planeta, lo agrega a la lista de acuerdo con la probabilidad, luego imprime uno al azar.

EDITAR: Con crédito a Jonathan Frech, rehice el bucle for para eliminar algunos bytes. Mejor forma de agregar elementos a la lista


3
Bienvenido a PPCG! No estoy seguro de cómo contó los bytes, pero solo obtengo 283. Menos si esa sangría es una pestaña en lugar de 4 bytes.
Martin Ender

1
¿No i in range(x[1], x[2])excluye el borde superior del calor, a diferencia de lo especificado en la especificación?
Graipher


1
¿Podría ser esto de alguna ayuda? 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 se disculpa, parece que los comentarios despojaron a algunos personajes.
MoustacheMoses

2

Octava con estadísticas El Paquete, 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}

El código define una función anónima que ingresa un número y genera una cadena.

Pruébalo en línea!

Explicación

El código

@(h)

define una función anónima con entrada h .

La cuerda

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

se divide en comas usando

strsplit(...,',')

El resultado es una matriz de celdas de cadenas, donde cada cadena es una clase de planeta.

El código

'IIIJLLLO'-70

define la cadena que se muestra y resta 70de los puntos de código de sus caracteres. Esto proporciona la matriz de valores mínimos de calor menos 1 , es decir, [3 3 3 4 6 6 6 9] .

Similar,

'PMMNPQQR'-70

produce la matriz de valores máximos de calor más 1 , es decir,[10 7 7 8 10 11 11 12] .

Las comparaciones

h>...&h<...

dar una matriz que contiene trueofalse indique qué clases de planetas son posibles.

Por otra parte,

'UPPPP_TL'-70

define la matriz de valores de azar, [15 10 10 10 10 25 14 6].

La operacion

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

es la multiplicación por elementos de las dos últimas matrices ( truey se falsecomportan como 0y 1respectivamente). Esto proporciona una matriz donde cada clase de planeta tiene su oportunidad aleatoria o0 si esa clase no es posible en función de la entrada. Esta matriz se utilizará como ponderaciones en el muestreo aleatorio.

La llamada a la función

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

selecciona una de las celdas de la matriz de cadenas de celdas (primer argumento de entrada), utilizando la matriz computada de pesos (cuarto argumento de entrada). Específicamente, la función randsamplenormaliza automáticamente los pesos de las probabilidades y luego realiza la selección aleatoria con esas probabilidades. El resultado es una matriz de celdas que contiene una cadena. El código

{1}

se utiliza para extraer esa cadena, que constituye la salida de la función.


2
Gran explicación, gracias. Gran puntaje también.
Absenta

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

Pruébalo en línea!


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]

Pruébalo en línea!


Si elimina uno de los calores mínimos y agrega uno a los calores máximos (eso daría en [Ice,4,5,11]lugar de [Ice,4,6,10], etc.), podrá usarlos en <lugar de <=y en >lugar de >=, ahorrando así 2 bytes. (sí, eso no es mucho ...)
Dada

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 el bucle ahora en una línea, sin retorno, menos bytes al tipo implícito

4 espacios eliminados (gracias Kevin )

Pruébalo en línea!


Nunca he programado Nim, pero creo que puedes jugar golf en cuatro espacios: uno en for n in[(; y tres a las 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Ωè

Pruébalo en línea!

Explicación

”Œï²°™Ä²° Gaia classêη•™Äµ‰Ÿ± Lava”
empuja la cuerda 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 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)])

La división hen máscaras de bits separadas y valores de probabilidad aleatorios (ver explicación) ahorra algunos bytes al eliminar una asignación hy simplificar elrange() comprensión en la lista.

Solución previa

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 una función anónima que toma un int y devuelve el tipo de planeta.

Para cada tipo de planeta, se calculó un valor de 13 bits. Los 8 bits superiores definen una máscara de bits de valores de calor válidos para ese tipo de planeta. Los 5 bits inferiores son la posibilidad aleatoria de ese tipo de planeta. Por ejemplo, "clase Gaia" es un tipo válido para valores de calor de 4 a 7, por lo que tiene una máscara de 0b00001111. Tiene una probabilidad aleatoria de 10, o 0b01010. Combinándolos resulta el valor de 13 bits 0b0000111101010para el tipo "clase Gaia". Los valores de 13 bits para cada tipo de planeta se concatenan para obtener el valor h(los 13 bits más bajos son para el tipo de planeta "Hielo"). (La respuesta más reciente no combina estos valores).

La comprensión de la lista itera sobre los valores de 13 bits para crear una lista de pesos, donde el peso es la posibilidad aleatoria si el tipo de planeta es una opción válida para el valor de calor dado, y cero en caso contrario. Para cada tipo de planeta, (h>>i&31)extrae la posibilidad aleatoria de ese tipo de planeta. (h>>i+n+1&1)evalúa a 1 si el tipo de planeta es una opción válida para el valor de calorn y evalúa a 0 de lo contrario.

La función de biblioteca random.choices(choices, weights)selecciona un elemento de la lista de opciones en función de la lista de pesos.


i+n+1puede ser i-~n. TIO
ovs

1

Rubí , 214 193 189 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}

Pruébalo en línea!


Lo siento, no obtengo el resultado, ¿sería el primer elemento de la lista?
Absenta

@Absinthe Agregué algunos encabezados, verifique nuevamente. Son todos los niveles de calor del 4 al 11 y un planeta generado aleatoriamente para cada uno
Asone Tuhid

Ah, lo entiendo, aunque idealmente solo debería haber una salida de cadena
Absenta

@Absinthe Tienes razón, ese era solo mi propio código de prueba, ahora puedes ingresar el valor de calor que deseas y devuelve 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)

(He agregado saltos de línea para una mejor impresión). La tarea dice "regresar", no "imprimir", por lo que fes una función que devuelve el nombre del planeta seleccionado al azar a la IOmónada,f :: Int -> IO String .

El maines main = do {f 10 >>= print}(los consejos de golf de Haskell dicen que no cuenta). Huellas dactilares

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

(ediciones: se eliminó &el caso base; se mudó main; se cambió a cuádruples y unzip, y se cambió a guardias de patrones y >>=siguiendo las sugerencias de Laikoni , ¡gracias !; implementó el enfoque de la solución Jelly en su lugar, repitiendo los nombres; el tipo explícito ya no es necesario ; otro consejo de Laikoni ahorra 3 bytes más; lo convirtió en una IOfunción; implementó el consejo de la sala de chat).

Pruébalo en línea!


¡Agradable! Para evitar inundar los comentarios, puede unirse a la sala de chat de Haskell Of Monads and Men para analizar su respuesta.
Laikoni

0

Java 8, 398 384 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 se puede jugar un poco más, pero la probabilidad en combinación con las cadenas no es muy fácil en Java.

Explicación:

Pruébalo en línea.

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

Mín. , 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

Comienza con calor en la pila, deja una cuerda en la pila. El mismo proceso general que la respuesta de Python 2.

Explicación

Tenga en cuenta que min es 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 (archivo CSV) + 1 (nombre de archivo) = 192 bytes

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

Pruébalo en línea! (esta es una versión ligeramente modificada que crea el archivo CSV temporal que se describe a continuación)

Importa un archivo CSV usando ipcsv(abreviatura Import-CSV) nombrado aen el directorio local que contiene lo siguiente:

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

Eso crea automáticamente una tabla hash iterable de cosas como las siguientes:

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

A continuación, utilizamos Where-Object( ?) para sacar las entradas en nuestro entero de entrada $zes -inel rango $_.mde $_.x(es decir, está en el rango de calor). Luego los bombeamos a un Foreach-Objectbucle ( %) que crea una serie de cadenas de nombres basadas en la posibilidad aleatoria de esos nombres. Por ejemplo, esto creará una serie de 15 "Gas Giant"cadenas si ese calor coincide. Luego colocamos los Get-Randomque extraerán la cadena apropiada con la ponderación adecuada.


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

Pruébalo en línea!


55
Las respuestas a la pregunta de código de golf deben mostrar un esfuerzo para jugar golf. Puede hacer esto mucho más corto simplemente eliminando espacios en blanco . El siguiente paso sería acortar los nombres de las variables a nombres de caracteres únicos.
ovs
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.