Создать солнечную систему


39

вступление

Это основано на реальной проблеме, с которой я недавно столкнулся, создавая компьютерную игру, и я подумал, что это принесет хороший раунд .

Существует семь основных спектральных классов звезд, которые выделяют различное количество тепла. На геологию планет вокруг звезды большое влияние оказывает количество тепла, получаемого от звезды, которое является фактором спектрального класса и расстояния от звезды. Следовательно, Меркурий практически расплавлен, Нептун заморожен.

Галактика в моей игре сгенерирована процедурно, и случайный выбор типов планет для данных звезд оказался настоящим «заявлением ада»!

Соревнование

Ваш метод должен выбрать одну планету из списка типов планет, соответствующих классу звезды, на основе минимального теплового порога, максимального теплового порога и случайного числа. Для простоты эта задача будет использовать только звезду класса G, как наше Солнце.

входные

Целое число heatв диапазоне от 4 до 11, представляющее количество тепла, получаемого планетой от звезды.

переменные

Эта таблица показывает возможные планеты на основе heat. Ваш метод должен сначала сузить доступные варианты выбора, исходя из минимума нагрева и максимума нагрева, которые heatдолжны приходиться на или между ними. Например, с теплом 10, переданным в единственном выборе будут Пустыня, Железо и Лава.

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

Далее, вероятность выбора планеты (в оставшихся вариантах) - это ее случайные шансы, деленные на сумму случайных шансов всех вариантов.

В приведенном выше примере вероятность выбора железа равна 14/(25+14+6).

Выход

Вернуть тип планеты в виде строки.

Делайте все возможное, чтобы избежать логических стрелок. Самый короткий код побеждает, очки за творческий подход. Удачного игры в гольф!


Должен ли «класс» «класса Гайи» быть прописным, как и все остальное?
Джонатан Аллан

@JonathanAllan это строчные буквы, поскольку это не собственно существительное
Абсент

1
@Absinthe Тогда почему Dense A в верхнем регистре с атмосферой?
Эрик Outgolfer

17
... кто-нибудь говорил это? | Добро пожаловать в PPCG и приятного первого испытания!
user202729

3
@EricDuminil ака анти-паттерн стрелка, ака вложенный-если-утверждение-ад! wiki.c2.com/?ArrowAntiPattern
Абсент

Ответы:


12

Желе , 78 байт

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

Монадическая ссылка, принимающая целое число (в [4,11] ), которое возвращает список символов.

Попробуйте онлайн!

Как?

Создает диапазоны температур планет в виде списка списков и подсчитывает вхождения входной теплоты в этих списках, чтобы получить список нулей и единиц, представляющих возможные типы планет, затем умножается на числа вероятностей восьми типов планет для получить распределение. Распределение используется для повторения имен типов планет, и, наконец, делается равномерный случайный выбор.

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

Псих! Отлично сработано.
Абсент

@Absinthe Вы можете просто поднять голос. Примечание: на Code Golf мы обычно не принимаем ответы.
user202729

2
@ user202729 Я добавлю голоса через день или два. Я просматривал страницу GitHub для Jelly, пытаясь разгадать этот код. Я верю Сумасшедшему! является наиболее подходящим :)
Абсент

2
@ Абсент да, я полагаю, что описательный раздел часто полезен даже для неэзотерических языковых представлений :)
Джонатан Аллан

3
Вы, люди, действительно безумны.
Сельвек,

7

R , 225 223 183 байт

Спасибо Джузеппе за умный рефакторинг для уменьшения его до 188 байт; остальные пять были выбриты с использованием менее избыточных числовых представлений.

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

Попробуйте онлайн!


Это хороший подход, мне, возможно, придется подумать об удалении лабиринта if if if в пользу этого в C # :)
Absinthe

Я подозреваю , что сохранение логического индекса , а не использовать with, data.frameи subsetбудет короче.
Джузеппе


@Giuseppe, вы, вероятно, можете получить еще несколько байтов, используя некоторые из моих приемов с данными о планетах , но я думаю, что я также улучшу мой, используя вашу идею отделения вектора вероятностей от остальных данных.
Кирилл Л.

4

JavaScript 212

Редактировать 6 байтов, за исключением Джонатана Аллана

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

меньше гольфа

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

Тест

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>


Пара из ваших 16 базовых чисел - 1 (должно быть [3913, 2630, 2630, 2647, 2681, 6522, 3706, 1707])
Джонатан Аллан

Я думаю (но не на 100%) вы можете сохранить 2, заменив (z/16&15)на z/16&15. Несмотря на это, вы можете сохранить 6 байтов, используя сжатие base 8 со смещением три и шесть ... используйте [971,648,648,657,675,1636,932,445]с z/8&7+3, z%8+6и z>>6:)
Джонатан Аллан

@JonathanAllan компенсирует! Отличная идея,
спасибо

@JonathanAllan мне нужны скобки, (z/8&7)+4потому что &имеет более низкий приоритет - это будет7/8&(7+4)
edc65

1
@ Шагги, ты видел комментарий прямо над твоим? (короткая история: нет)
edc65

4

Кокос , 214 195 байт

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)

Попробуйте онлайн!

Порт Python будет иметь длину 203 200 байт:

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*

Попробуйте онлайн!


1
Интересно, что на момент написания ваш порт Python превосходил все остальные решения Python!
Кирилл Л.

4

Древесный уголь , 115 111 байт

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

Попробуйте онлайн! Ссылка на подробную версию кода. Редактировать: 4 байта сохранены благодаря @ ASCII-only. Объяснение:

≔I⁻N³θ

Вычтите 3 из входных данных, чтобы их можно было сравнить с однозначными числами.

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

Разбейте строку 0715 0410 0410 1510 3710 3825 3814 696на пробелы (пробелы, кажется, сжимают лучше, чем запятые, но я не пробовал другие символы) и зациклите каждую часть.

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

Сравните входные данные с первой и второй цифрами и, если они между ними, передайте индекс цикла указанное число раз в предварительно определенный пустой список, заполнив его.

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

Разделите список планет на новые строки (опять же, лучше, чем запятые по некоторым причинам) и выберите элемент, соответствующий индексу, выбранному случайным образом из списка.


Хороший. Как Random (u) учитывает различные вероятности для каждой планеты? (Я ничего не знаю о древесном угле).
Абсент

Он выбирает индекс из списка с правильным распределением индексов planetType из-за того, что «помещает индекс цикла указанное число раз в предварительно определенный пустой список, заполняя его таким образом». затем используя выбранный индекс, чтобы получить имя planetType.
Джонатан Аллан

@JonathanAllan Понял, спасибо
Абсент

111 байт , я думаю? В общем, попробуйте использовать символы ранее в классе символов, см. Сжатие # 11. Порядок по умолчанию сохраняет еще один байт, но это в основном только в том случае, если у вас есть только символы
только ASCII

@ ASCII-only Очистить как грязь ... почему там лучше переводы строк, но есть пробелы для другой строки?
Нил

3

R , 196 193 190 175 171 байт

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

Попробуйте онлайн!

Первоначально вдохновленный этим решением @rturnbull, однако, поскольку оба представления значительно эволюционировали, теперь это, по сути, смесь идей оригинального автора @Giuseppe, который очень помог мне в комментариях и моих. Вот краткое изложение ключевых моментов, которые помогли уменьшить количество байтов:

  • Кодирование данных планеты в формате CSV. Сбор имен, readLinesчтобы избежать большого количества символов кавычек вокруг строк.

  • Настраиваем тепловые параметры, чтобы мы могли использовать <и >знаки вместо <=и >=.

  • Изменение формата данных о высокой температуре с Heat min, Heat maxна, Heat min, Heat Deltaчтобы избавиться от двузначных чисел.
    Заменяется смещением всех чисел на -3

  • Деление всех вероятностей планеты на 5, что также приводит к наименьшему количеству цифр.

  • Умножение вектора вероятностей планет на вектор логических значений (показывающий, удовлетворяет ли наш вход тепловой энергии), чтобы свести на нет вероятности неподходящих планет.

Возможно, еще несколько байтов можно было бы получить, применив какое-то сжатие данных.
Я думаю, больше нет.


1
t=вместо того, text=чтобы сохранить 3 байта, а также.
Джузеппе


Твердый ответ, тем не менее, использование read.csvдля одного столбца предложил полностью readLinesизбавиться от кавычек, хотя вы должны явно установитьn
Giuseppe

@Giuseppe, это 171 байт, так как вы также удалили скобки, которые были необходимы для сохранения приоритета оператора, и ваша версия дает неправильные вероятности. Тем не менее, блестящее предложение!
Кирилл Л.

О, я удивлялся, откуда взялись эти скобки ...
Джузеппе

3

Python, 282 байта , 261 байт:

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)

Довольно просто - уверен, что это может быть больше в гольфе - Все еще в поисках лучшего способа представления дальности планеты и данных вероятности. Если я нахожусь в пределах досягаемости типа планеты, добавляю его в список в соответствии с вероятностью, затем случайным образом печатает один.

РЕДАКТИРОВАТЬ: с благодарностью Джонатана Фреха - переделать цикл for, чтобы сбить несколько байтов. Лучший способ добавления предметов в список


3
Добро пожаловать в PPCG! Не знаю, как вы посчитали байты, но я получаю только 283. Меньше, если этот отступ - это вкладка вместо 4 байтов.
Мартин Эндер

1
Не i in range(x[1], x[2])исключает ли верхний край тепла, в отличие от спецификации?
Graipher


1
Может ли это помочь? 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)]
УсыMoses

1
@Chromane Извинения, кажется, что комментарии раздели некоторых персонажей.
УсыMoses

2

Октава с пакетом статистики, 178 176 174 158 байт

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

Код определяет анонимную функцию, которая вводит число и выводит строку.

Попробуйте онлайн!

объяснение

Код

@(h)

определяет анонимную функцию с вводом h.

Струна

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

делится на запятые с помощью

strsplit(...,',')

В результате получается массив ячеек строк, где каждая строка является классом планеты.

Код

'IIIJLLLO'-70

определяет показанную строку и вычитает 70из кодовых точек ее символов. Это дает массив минимальных значений тепла минус 1 , то есть [3 3 3 4 6 6 6 9].

По аналогии,

'PMMNPQQR'-70

производит массив максимальных значений тепла плюс 1 , то есть [10 7 7 8 10 11 11 12].

Сравнения

h>...&h<...

дать массив, содержащий trueили falseуказывающий, какие классы планет возможны.

С другой стороны,

'UPPPP_TL'-70

определяет массив случайных значений случайности [15 10 10 10 10 25 14 6].

Операция

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

является поэлементным умножением последних двух массивов ( trueи falseведет себя как 0и 1соответственно). Это дает массив, в котором у каждого класса планет есть либо случайный шанс, либо, 0если этот класс невозможен на основании входных данных. Этот массив будет использоваться в качестве весов в случайной выборке

Вызов функции

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

выбирает одну из ячеек из массива ячеек строк (первый входной аргумент), используя вычисленный массив весов (четвертый входной аргумент). В частности, функция randsampleавтоматически нормализует весовые коэффициенты для вероятностей, а затем выполняет случайный выбор с этими вероятностями. Результатом является массив ячеек, содержащий строку. Код

{1}

используется для извлечения этой строки, которая составляет вывод функции.


2
Отличное объяснение, спасибо. Отличная оценка тоже.
Абсент


1

Perl 5 ( -p), 230 байт

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

Попробуйте онлайн!


Если вы уберете одну из них в минимальную теплоту и добавите одну в максимальную теплоту (что дало бы [Ice,4,5,11]вместо [Ice,4,6,10]и т. Д.), То вы сможете использовать <вместо <=и >вместо >=, таким образом сохраняя 2 байта. (да, это не много ...)
Дада

1

Ним , 314 298 294 байта

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

Для цикла теперь в одной строке, нет возврата, меньше байтов для неявного типа

4 пробела удалены (спасибо Кевину )

Попробуйте онлайн!


Я никогда не программировал Nim, но я думаю, что вы можете играть в гольф четыре места: одно в for n in[(; и три в if h>=n[1]and h<=n[2].
Кевин Круйссен

1

05AB1E , 78 76 байт

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

Попробуйте онлайн!

объяснение

”Œï²°™Ä²° Gaia classêη•™Äµ‰Ÿ± Lava”
толкает строку 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 байта

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

Разделение hна отдельные битовые маски и случайные значения случайности (см. Объяснение) экономит несколько байтов, устраняя назначение hи упрощая range()понимание в списке.

Предыдущее решение

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

Определяет анонимную функцию, которая принимает int и возвращает тип планеты.

Для каждого типа планеты было рассчитано 13-битное значение. Верхние 8 битов определяют битовую маску действительных значений тепла для этого типа планеты. Нижние 5 битов - это случайный шанс для этого типа планеты. Например, «класс Gaia» является допустимым типом для значений нагрева от 4 до 7, поэтому он имеет маску 0b00001111. Это случайный шанс 10 или 0b01010. Комбинируя их, мы получаем 13-битное значение 0b0000111101010для типа «класс Gaia». 13-битные значения для каждого типа планет объединяются, чтобы получить значение для h(самые младшие 13 битов относятся к типу "Лед"). (Более новый ответ не объединяет эти значения).

Понимание списка перебирает 13-битные значения, чтобы создать список весов, где вес - это случайный шанс, если тип планеты является правильным выбором для данного значения тепла, и ноль в противном случае. Для каждого типа планет (h>>i&31)извлекает случайный шанс для этого типа планет. (h>>i+n+1&1)оценивается как 1, если тип планеты является правильным выбором для значения теплоты, nи оценивается как 0 в противном случае.

Функция библиотеки random.choices(choices, weights)выбирает элемент из списка вариантов на основе списка весов.


i+n+1может быть i-~n. TIO
овс

1

Рубин , 214 193 189 байт

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

Попробуйте онлайн!


Извините, я не получаю вывод, это будет первый элемент в списке?
Абсент

@Absinthe Я добавил несколько заголовков, проверьте еще раз. Это все уровни тепла от 4 до 11 и случайно сгенерированная планета для каждого
Асоне Тухид

Ах, я понимаю, спасибо, хотя в идеале должен быть только один вывод строки
Absinthe

@Absinthe Вы правы, это был только мой собственный тестовый код, теперь вы можете ввести
желаемое

1

Haskell , 377 364 358 318 312 270 265 262 256 251 байт

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)

(Я добавил разрывы строк для лучшей распечатки). Задача говорит «возврат», а не «печать», так fчто это функция, которая возвращает случайно выбранное имя планеты в IOмонаду f :: Int -> IO String.

mainЯвляется main = do {f 10 >>= print}( Haskell гольф советы говорит , что это не считается). Печать

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

(редактирует: удалил &базовый регистр; переместился main; изменил на четверки и unzipпереключился на охрану шаблонов и >>=следуя советам от Laikoni , спасибо !; вместо этого реализовал подход из решения Jelly , повторяя имена; явный тип больше не нужен ; другой совет от Laikoni экономит еще 3 байта; сделал это IOфункцией; реализовал совет из чата).

Попробуйте онлайн!


Ницца! Чтобы избежать затопления комментариев, вы можете присоединиться к чату Haskell « Монады и люди», чтобы обсудить ваш ответ.
Лайкони

0

Java 8, 398 384 байта

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

Это, безусловно, можно сыграть в гольф еще немного, но вероятность в сочетании со строками не очень легко в Java.

Объяснение:

Попробуйте онлайн.

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

Мин , 280 277 байт

: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

Начинается с высокой температуры в стеке, оставляет строку в стеке. Тот же общий процесс, что и в Python 2.

объяснение

Обратите внимание, что мин является конкатенацией

: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 (файл CSV) + 1 (имя файла) = 192 байта

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

Попробуйте онлайн! (это слегка измененная версия, которая создает временный файл CSV, описанный ниже)

Импортирует файл CSV, используя ipcsv(сокращенно Import-CSV) с именем aв локальном каталоге, который содержит следующее:

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

Это автоматически создает итеративную хеш-таблицу таких вещей:

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

Затем мы используем Where-Object( ?) , чтобы вытащить те записи , где наш вход целое число $zявляется -inдиапазон $_.mдо $_.x(то есть, он находится в тепловом диапазоне). Затем мы закачиваем их в Foreach-Objectцикл ( %), который создает массив строк имен на основе случайного совпадения этих имен. Например, это создаст массив 15 "Gas Giant"строк, если это тепло соответствует. Затем мы помещаем те, в Get-Randomкоторые вытащим соответствующую строку с соответствующим весом.


-1

PHP , 1236 байт

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

Попробуйте онлайн!


5
Ответы на вопросы по коду-гольфу должны проявить усилия в игре в гольф. Вы можете сделать это намного короче, просто удалив пробелы . Следующим шагом будет сокращение имен переменных до имен из одного символа.
овс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.