Створіть сонячну систему


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 це нижній регістр, оскільки це не власне іменник
Absinthe

1
@Absinthe Тоді чому велика величина великої величини тмосфери?
Ерік Аутгольфер

17
... хтось це сказав? | Ласкаво просимо до PPCG та приємного першого виклику!
користувач202729

3
@EricDuminil aka анти-візерунок стрілки, він же вкладений-якщо-заява-чорт! 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 Code Golf ми зазвичай не приймаємо відповіді.
користувач202729

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

2
@Absinthe так, я вважаю, що описовий розділ часто хороший, навіть якщо це не є езотеричне подання мови :)
Джонатан Аллан,

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

Спробуйте в Інтернеті!


Це приємний підхід. Можливо, мені доведеться подумати над тим, як видалити мою заяву, якщо лабіринт, якщо користь цьому в C # :)
Абсент

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


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

4

JavaScript 212

Редагувати 6 байтів, зберегти 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]]

менше гольфу

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 байтів, використовуючи стиснення 8 баз із зміщенням трьох і шести ... використовувати [971,648,648,657,675,1636,932,445]з z/8&7+3, z%8+6і z>>6:)
Джонатан Аллан

@JonathanAllan компенсує! Відмінна ідея, thx
edc65

@JonathanAllan мені потрібні дужки, (z/8&7)+4тому що &має нижчий пріоритет - це буде7/8&(7+4)
edc65

1
@Shaggy Ви бачили коментар прямо над вашим? (довга історія коротка: ні)
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. Пояснення:

≔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-лише Очистити як грязь ... чому нові рядки там кращі, але пробіли для іншого рядка?
Ніл

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, це 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)

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

РЕДАКТУВАТИ: Маючи на увазі Джонатана Фреха - перепрофілюйте цикл, щоб вибити кілька байт. Кращий спосіб додавання елементів до списку


3
Ласкаво просимо до PPCG! Не знаю, як ви рахували байти, але я отримую лише 283. Менше, якщо цей відступ - це вкладка, а не 4 байти.
Мартін Ендер

1
Чи не i in range(x[1], x[2])виключає верхній край тепла, на відміну від специфікації?
Грайфер


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

1
@Chromane Вибачення, схоже, що коментарі позбавили деяких персонажів.
MustacheMoses

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].
Kevin Cruijssen

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 результат
Asone Tuhid

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"

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

Спробуйте в Інтернеті!


Приємно! Щоб уникнути затоплення коментарів, ви можете приєднатися до чату Haskell Of Monads and Men, щоб далі обговорити свою відповідь.
Laikoni

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

Однозначно можна пограти ще трохи, але ймовірність у поєднанні з Strings не дуже проста в 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.

Пояснення

Зауважте, що min є конкатенативним

: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.