创建一个太阳系


39

介绍

这是基于我最近在制作计算机游戏时遇到的一个实际问题,我认为这将使一轮不错的

有七种主要的恒星光谱类别,它们散发出不同的热量。从恒星接收的热量极大地影响了恒星周围行星的地质,这是光谱类别和距恒星距离的一个因素。因此,水星实际上是融化的,海王星冻结了。

我的游戏中的银河是程序生成的,并且为给定的恒星随机选择行星类型实际上是一个真正的“ if声明地狱”!

挑战

您的方法应基于最小热量阈值,最大热量阈值和随机数,从适合于恒星类别的行星类型列表中选择一个行星。为简单起见,此挑战将仅使用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那为什么Dense A tmosphere是大写的呢?
Erik the Outgolfer

17
...有人说吗?| 欢迎来到PPCG,也是第一个挑战!
user202729 '18

3
@EricDuminil又名箭头反模式,又名嵌套if语句地狱!wiki.c2.com/?ArrowAntiPattern
苦艾酒

Answers:


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

疯!做得好。
苦艾酒

@苦艾酒您可以简单地投票。旁注:在Code Golf上,我们通常不接受答案。
user202729 '18

2
@ user202729我将在一两天内添加投票。我在GitHub页面上寻找Jelly试图解开此代码。我相信疯了!最合适的是:)
苦艾酒

2
@Absinthe是的,我相信即使对于非深奥的语言陈述,描述性部分通常也是一件好事:)
Jonathan Allan

3
你们真是疯了。
Selvek '18

7

[R 225个 223 183字节

感谢朱塞佩(Giuseppe)的巧妙重构,将其减少到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语句迷宫,如果在C#中对此有利:)
苦艾酒

我怀疑节省逻辑索引,而不是使用withdata.framesubset将缩短。
朱塞佩


@Giuseppe,您可以通过对行星数据使用一些技巧来获得更多字节,但是我想我也将使用您将概率向量与其余数据分离的想法来改善我的水平。
Kirill L.

4

JavaScript 212

编辑 6个字节以保存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%)可以通过替换(z/16&15)为来节省2 z/16&15。无论如何,您都可以使用以8和3为偏移量的基数8压缩来保存6个字节... [971,648,648,657,675,1636,932,445]z/8&7+3z%8+6z>>6:)一起使用
Jonathan Allan

@JonathanAllan抵消了!好主意,谢谢
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端口的长度为203200字节:

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解决方案!
Kirill L.

4

木炭115111字节

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

在线尝试!链接是详细版本的代码。编辑:由于仅@ASCII,节省了4个字节。说明:

≔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”¶‽υ

在换行符上分割行星列表(由于某种原因再次优于逗号),然后选择与从列表中随机选择的索引相对应的元素。


好东西。随机(u)如何影响每个行星的不同概率?(我对木炭一无所知)。
苦艾酒

由于“将循环索引按给定的次数推入预定义的空列表,从而填充了它,因此,它正在从列表中选择一个行星类型索引正确分布的索引。” 然后使用选定的索引来获取planetType名称。
乔纳森·艾伦,

@JonathanAllan懂了,谢谢
苦艾酒

111字节,我觉得呢?通常,只需在字符类中尝试使用较早的字符,请参见compression#11。默认顺序会保存另一个字节,但这基本上仅在您只有符号的情况下
ASCII码仅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 maxHeat min, Heat Delta以消除两位数。
    替换为将所有数字都减-3

  • 将所有行星的概率除以5,这也会减少几位数。

  • 将行星概率向量与布尔向量相乘(指示我们的输入是否满足热量需求),以使不合适的行星的概率为零。

通过应用某种数据压缩可能会获得更多的字节。
我认为,现在不再。


1
t=而不是text=会节省3个字节。
朱塞佩


可靠的答案,但是,read.csv建议readLines您单独设置一栏,以完全消除引号,尽管您必须明确设置n
Giuseppe

@Giuseppe,它是171个字节,因为您还删除了保持运算符优先级所必需的括号,并且您的版本给出了错误的概率。尽管如此,一个绝妙的建议!
Kirill L.

哦,我想知道这些括号是从哪里来的
朱塞佩

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)

非常简单-肯定可以打更多球-还在寻找一种更好的方式来表示行星范围和概率数据。如果i在行星类型的范围内,则根据概率将其添加到列表中,然后随机打印一个。

编辑:感谢乔纳森·弗雷奇(Jonathan Frech)-重做for循环以减少几个字节。将项目追加到列表的更好方法


3
欢迎来到PPCG!不知道如何计算字节,但是我只有283。如果该缩进是制表符而不是4字节,则减少。
Martin Ender '18

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

使用input定义一个匿名函数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<...

给出一个包含truefalse指示可能的行星类别的数组。

另一方面,

'UPPPP_TL'-70

定义随机机会值数组[15 10 10 10 10 25 14 6]

手术

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

是后者的两个阵列的逐元素乘法(truefalse表现得象01分别地)。这样就给出了一个数组,其中每个行星类别都有其随机的机会,或者0根据输入无法确定该类别的机会。该数组将用作随机抽样中的权重

函数调用

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

使用计算出的权重数组(第四输入参数)从字符串的单元数组(第一输入参数)中选择一个单元。具体来说,该功能会randsample自动将权重标准化为概率,然后使用这些概率进行随机选择。结果是包含字符串的单元格数组。代码

{1}

用于提取该字符串,该字符串构成函数输出。


2
很好的解释,谢谢。分数也很高。
苦艾酒

2

Python 3,263字节

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

在线尝试!


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个字节。(是的,不是很多...)
Dada

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个空格(感谢Kevin

在线尝试!


我从来没有编程过Nim,但是我想你可以打四个空间:一个在for n in[(;一个在。和三个在if h>=n[1]and h<=n[2]
凯文·克鲁伊森

1

05AB1E78 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并返回Planet类型。

对于每种行星类型,计算出一个13位的值。高8位定义了该行星类型的有效热量值的位掩码。最低的5位是该行星类型的随机机会。例如,“ Gaia类”是热值4到7的有效类型,因此其掩码为0b00001111。它的随机机会为10或0b01010。合并它们将得出0b0000111101010“ Gaia类”类型的13位值。将每种行星类型的13位值连接起来以获取的值h(最低的13位是“冰”行星类型的值)。(较新的答案未合并这些值)。

列表推导对13位值进行迭代以创建权重列表,如果行星类型是给定热量值的有效选择,则权重是随机机会,否则为零。对于每种行星类型,(h>>i&31)提取该行星类型的随机机会。(h>>i+n+1&1)如果行星类型是热值的有效选择,则结果为1 n,否则为0。

库功能random.choices(choices, weights)根据权重列表从选项列表中选择一个项目。


i+n+1可以i-~nTIO
ovs '18

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}

在线尝试!


抱歉,我没有得到输出,它将是列表中的第一项吗?
苦艾酒

@苦艾酒我添加了一些标题,再次检查。这是所有4到11的热量水平,每个都是一个随机生成的行星
Asone Tuhid

嗯,我明白了,尽管理想情况下应该只有一个字符串输出
苦艾酒

@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该函数会将随机选择的行星名称返回到IOmonad中f :: Int -> IO String

mainmain = do {f 10 >>= print}Haskell的高尔夫提示说,它不计数)。版画

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

(编辑:除去&的基础情况;移动main出来;变为四倍和unzip,并切换到图案警卫和>>=以下建议 Laikoni,由于!;实现从接近果冻溶液代替,重复的名称;明确的类型,不再需要; Laikoni的另一个建议可再节省3个字节;使其成为IO功能;在聊天室中实施的建议)。

在线尝试!


真好!为了避免泛滥成灾,您可以加入Haskell 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"";}

它肯定可以打更多的球,但是在Java中将Strings与Strings组合使用的可能性并不大。

说明:

在线尝试。

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)导入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
回答高尔夫球问题时,需要显示出打高尔夫球的努力。您只需删除空白就可以使它更短。下一步是将变量名称缩短为单个字符名称。
ovs
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.