简约熔岩灯


18

介绍:

我想每个人都知道熔岩灯是什么,但万一他们不知道:

在此处输入图片说明
(图片来源)

它们基本上是在半透明液体中包含蜡的玻璃管。打开灯时,底部会被加热,从而导致密度变化,因此蜡会浮到顶部。冷却后,它会再次掉落,从而产生我们上面看到的效果。

灯的底座通常需要大约45-60分钟的时间才能升高到足以将固体蜡变为液体蜡的温度(如果灯位于室温下的区域)。

有关Wikipedia的更多信息,该信息也用作上述某些文本的来源。

挑战:

给定一个正整数n,该值指示自从我们打开熔岩灯以来经过的分钟数,请基于五个级别的整数输出熔岩灯的随机状态。

对于此挑战,我们将说熔岩灯总共包含1000单位蜡,并且我们可以将蜡置于5个级别。

1)如果n低于45,熔岩灯仍在加热,因此输出将是四个空行,1000底部是:





1000

2)如果熔岩灯的温度n在此范围内,则[45, 60)其温度升高到足以使蜡移动的程度,但还没有很高。蜡可以达到并包括第三级。
3)如果n60或更高,则蜡的含量可以为五个级别中的任何一个。

因此,给定正整数n作为输入,我们将牢记上述三个规则来输出随机状态。

以下是一些示例输出:

可能的输出n>= 45



523
106
371


913

87

可能的输出n>= 60

73
113
312
5
497
284
55
637

24

常量输出n<= 44(以及任何可能的输出n):





1000

挑战规则:

  • 即使上面的级别不为空,也可以有空行。
  • 只是0不允许在任何行上。应该为空。
  • 输出有些灵活。您可以输出字符串/对象的列表/数组,而不是上述的以换行符分隔的结果。我说字符串/对象的原因是由于上述规则。一个空行应""null[]等,但不能是0或负整数(也不能被false)(即["", "", 913, "", 87]用于n >= 45)。您还可以反转输出(即,1000\n\n\n\n代替\n\n\n\n1000[87, null, 913, null, null]代替[null, null, 913, null, 87])。
  • 这些数字都应该是整数。可以是带有0十进制值的小数,但是这些数字都不能包含任何十进制数字,并且整数应始终精确地相加1000
  • 基于的所有可能的随机输出n都应该有非零的发生机会。
  • 允许尾随换行符(因此有六行输出)。

通用规则:

  • 这是,因此最短答案以字节为单位。
    不要让代码高尔夫球语言阻止您发布使用非代码高尔夫球语言的答案。尝试针对“任何”编程语言提出尽可能简短的答案。
  • 标准规则适用于您的答案,因此您可以使用STDIN / STDOUT,具有正确参数的函数/方法和返回类型的完整程序。你的来电。
  • 默认漏洞是禁止的。
  • 如果可能的话,请添加一个带有测试代码的链接。
  • 另外,强烈建议为您的答案添加说明。


空层可以用单个空格表示吗?
Arnauld

@Arnauld当然。可以是除0负数或之外的任何数字false
凯文·克鲁伊森

即使在输出时,输出也总是5个电平n < 60吗?
Emigna '18

@Emigna是的,输出始终为5级。对于n < 45只有1水平然而填充(顶部或底部取决于你的顺序将其输出上),这是1000。随着45 <= n < 60三五次,并与n >= 60所有五个。但是输出将始终包含五个“行”。
凯文·克鲁伊森

Answers:


5

MathGolf21 20字节

5º*♪{k[K∞╟(]m<Σ∞wΦ}σ

在线尝试!

这是我用新语言的第一个答案。我的解决方案基于Emigna的05AB1E解决方案,但是使用了MathGolf的一些巧妙功能使其变得更短一些。

说明

5º*                   push 5, [0], multiply (yielding [0,0,0,0,0]
   ♪                  push 1000
    {                 start block
     k                push input as integer
      K∞              push 22 and double it, yielding 44
        ╟(            push 60 and decrease, yielding 59
          α           wrap last two elements in array, yielding [44,59]
           m<         map is less than, giving [0,0], [1,0] or [1,1]
             Σ        sum array, giving 0, 1 or 2
              ∞       double, giving 0, 2 or 4
               w      push random integer in range
                Φ     increase array element
                 }    execute for loop (loops 1000 times)
                  σ   convert to string and remove leading zeroes (implicit map)

如果这些功能本身并不是内置的,则不需要竞争标签。自去年年中以来,不竞争不再是问题。由于它是非常新的,我认为还没有针对您的语言的在线编译器?您是否可以添加一些屏幕截图(如果太过分混乱,则可以添加到屏幕截图的链接)作为验证?我会与@Dennis联系,询问是否可以将您的语言添加到TryItOnline中
凯文·克鲁伊森

2
@KevinCruijssen感谢您的反馈!我将添加一些屏幕截图,并且正在努力将语言转换为TIO。一旦我感觉到我并没有不断添加新功能,我将与Dennis联系。
maxb

您是否考虑为自己的语言创造空间?我对学习非常感兴趣!
Jo King

@JoKing很高兴听到您感兴趣!这个周末我将尝试创建一个房间。丹尼斯(Dennis)的帮助下,我才刚刚在TIO上获得了语言,我正在努力使所有人都能使用它!
maxb

@JoKing 我为MathGolf创建了一个房间。我会尽力回答所有问题,因为我知道文档尚未完成。
maxb

8

Python 2中117个 113 108 107 106 105字节

from random import*
def f(n):a=['']*5;exec"i=randint(0,(n>44)+(n>59)<<1);a[i]=(a[i]or 0)+1;"*1000;print a

在线尝试!

返回反向列表(从下至上)


受注释中的stackoverflow 答案启发的版本(更有可能是边缘情况):

Python 2,129字节

from random import*
def f(n):a=sorted([1000]*5+sample(range(1001)*5,(n>44)+(n>59)<<1));print[y-x or''for x,y in zip([0]+a,a)[:5]]

在线尝试!


我不知道您的代码是如何工作的,但是每个状态发生的可能性都不为零吗?您的所有数字都分别徘徊在3或5部分的333或附近200。我看不到0或的任何峰值/异常值1000。还是333与和附近的整数相比,那些天文学上的机会很小(但仍非零)200
凯文·克鲁伊森

1
@KevinCruijssen将1000个熔岩单位中的每一个放入一个随机的容器中(00-20-4),然后进行计数。没有机会进入任何一个的机会都是存在的,但是可能性很小。
TFeld

嗯,那很有道理。现在,我也已经更好地了解了您的代码。谢谢!向我+1。
凯文·克鲁伊森

7

JavaScript(ES6),78个字节

返回一个反向数组,其中空的级别用空格填充。

t=>(a=[...'     '],g=k=>k?g(k-1,a[Math.random()*(t>59?5:t<45||3)|0]++):a)(1e3)

在线尝试!

已评论

t => (                      // t = input
  a = [...'     '],         // a[] = output array, initially filled with 5 spaces
  g = k =>                  // g = recursive function taking an iteration counter k
    k ?                     //   if k is not equal to zero:
      g(                    //     do a recursive call:
        k - 1,              //       decrement k
        a[                  //       update a[]:
          Math.random() * ( //         pick a random slot:
            t > 59 ? 5 :    //           among all 5 slots if t > 59
            t < 45          //           force the 1st slot if t < 45
            || 3            //           among the 3 first slots otherwise
          ) | 0             //         round the above result to an integer
        ]++                 //       increment the wax amount on this slot
      )                     //     end of recursive call
    :                       //   else:
      a                     //     stop recursion and return a[]
)(1e3)                      // initial call to g() with k = 1000

实际上,我与对Python答案所做的评论有相同的问题:每个状态发生的可能性都非零吗?
凯文·克鲁伊森

1
1090

Rofl,和陨石很好的比喻。;)我现在确实看到您的方法与Python答案类似,因为它将值放置在数组中3个或5个点之一中,最多1000个。
凯文·克鲁伊森

6

R85 84字节

function(n)write(ifelse(t<-table(cut(runif(1e3,2*(n<60)+3*(n<45),5),0:5)),t,""),1,1)

-1字节感谢@Giuseppe

在线尝试!

说明(无胶体):

function(n){
      # Generate 1000 random uniform numbers in [5,5] (if n<45),
      # in [2,5] (if 45<=n<60) and in [0,5] (if n>=60).
    x = runif(1e3,2*(n<60)+3*(n<45),5) 
      # Code each by the number of the interval it falls in (0,1],(1,2]...(4,5]
    cx = cut(x,0:5)
      # Tabulate the intervals. Because cut() returns a factor,
      # zero counts are included 
    t = table(cx)
      # Vector-wise replace zero elements with "" and cat out, 1 per line.
    t1 = ifelse(t,t,"")
    write(t1,1,1)
}

如果NA允许用作空行/元素,则在元素名称有问题的情况下,使用77字节的解决方案(在线尝试!)或80字节的解决方案(在线尝试!
duckmayr

6

C(gcc)1311169089,87个字节

L(l,a,v,A){for(A=5,v=1e3;A--;v-=a)printf("%d\n"+!a*2,a=l>59|A<3&l>44?rand()%-~v:!A*v);}

在线尝试!

更新:修复了原始错误。融合在辅助函数中,减少了额外的15个字节。

更新2:-25字节,感谢ErikF。

更新3:-1字节,感谢ceilingcat。

德戈尔夫

L(l,a,v,A){
    for(A=5,v=1e3;A--;v-=a)
        printf("%d\n"+!a*2, // No clue how this works anymore, but it'll advance the pointer 
                            // to the string constant when a number shouldn't be printed.
        a=l>59|A<3&l>44?rand()%-~v // Random integer to print in [0, v]
        :!A*v); // If bottom layer, return remaining volume
}

您可以puts()通过将打印合并为一个printf()并将减法放入循环末端来消除。另外,我认为您可以将srand()初始化放入调用方中。在线尝试!
ErikF

我意识到我错过了“无零”限制。这是固定版本:在线尝试!
ErikF

最后一些调整!在线尝试!
ErikF

大; 我打了一个额外的字节。

1
另外,我们做到了!我们击败了Python!

5

05AB1E27 26 25字节

多亏了Adnan,节省了一个字节。
感谢Kevin Cruijssen保存了另一个字节。

5Å0₄FD„,;ÇI‹O·ÝΩ©è>®ǝ]ε0Û

在线尝试!

说明

5Å0                         # initialize with a list of 5 zeroes
   ₄F                       # 1000 times do:
     D                      # duplicate the list
      „,;ÇI‹                # check if the input is larger than 44 and/or 59
            O·              # sum and double, yielding (0,2 or 4)
             ÝΩ             # pick a random number between and 0 and the number above
               ©è           # get the count in that level
                 >          # increment it
                  ®ǝ        # insert it at the same position
                     ]      # end loop
                      ε0Û   # remove leading zeroes on each level

1
好答案!我喜欢你的使用方式5Å0ǝε0Û结尾。我试图提出更短的内容,但是我做不到。我感觉它仍然可以打高尔夫球,但是我目前没有看到它(也许不能,只是一种随意的感觉)。•A–•60в44 59‚原来短1个字节。而ε0Û更换0空字符串S还似乎是最短的,因为0K简单地完全消除了0项,并删除任何数字0中的所有数字。
凯文·克鲁伊森

1
@KevinCruijssen:是的,我一直在寻找并找到一种更短的方法44 59‚,但是我找不到(•H|•2ô相同的计数)。用我以前的解决方案(也27个字节)4560其更容易以不同的方式产生,但我认为这是因为它的输出无效135取决于输入电平,而不是总是5
Emigna '18

啊,•H|•2ô确实是一种聪明的方法,没有考虑过。它确实应该输出5行。我确实看到了您先前的答案,并打算对其进行评论,但只为输出了1行n < 45,但是您删除了它。很高兴您找到了另一个27字节的解决方案。:)
Kevin Cruijssen

2
我想ŽH|2ô你在找什么?
阿德南(Adnan)

2
@KevinCruijssen它的行为完全一样。使用05AB1E使用先前的答案做了一些研究,这是我在重写中添加的内容之一。目前没有任何其他用例。
阿德南

4

JavaScript(Node.js)87 86字节

f=(n,w=1e3,s=5,r=n<45|n<60&s<4|s<2?w:Math.random()*w|0)=>s?`${r||""}
`+f(n,w-r,s-1):""

在线尝试!

(n/15-2|0)*s<4首先保留83字节的解决方案(),因为我需要检查是否更大n

更新:是的,(n/15-2|0)*s<4没有用,n因为n太大,因为足够大会使总和无法达到1000。


4

PHP,92字节

$i=5;for($n=1e3;$i--;$n-=$x)echo($x=rand($i?0:$n,$i<($argn<60?$argn<45?:3:5)?$n:0))?:"","
";

与管道一起运行-R在线尝试


3

干净,215字节

import StdEnv,Math.Random,Text
? ::!Int->Int
?_=code{ccall time "I:I"
}
$n#l=take(max(2*min(n/15-2)2)0+1)(genRandReal(?0))
#l=map toInt[1E3*e/sum l\\e<-l]
|sum l==1000=map(\v|v>0=v<+"\n"="\n")(l++repeat 0)%(0,4)= $n

在线尝试!

所以,我终于找到了一个更短的方式来获得比进口随机种子System._UnsafeSystem.Time并用toInt(accUnsafe time)...
和男孩是真心codegolf的精神-嵌入到C的呼叫时,忽视正常使用,保证了评价的世态型这样的事情的顺序。


3

的Java(JDK 10) 121个 117 113 111字节

m->{for(int w=1000,j,i=5;i-->0;w-=j=i>0?j*=Math.random():w,System.out.println(j<1?"":j))j=m>59|m>44&i<3?w+1:0;}

在线尝试!

它倾向于在顶部放置更多的蜡,但是从理论上讲,任何合法的蜡排列都可能出现。

编辑:@KevinCruijssen保存了4个字节

在人类可读的Java中:

(int minutes /* golfed variable m */) -> {
  int waxRemaining = 1000; // golfed variable w

  // golfed version goes from index 4 to 0 in a bit of a roundabout way
  // starting at 5 but decrementing right away
  for (int level = 4 /* golfed variable i */; level <= 0; level--) {
    // golfed variable j
    // the golfed version initializes this to (waxRemaining + 1)
    // in order to juice out some extra bytes during the Math.random() call
    int waxAtLevel = 0;

    // the golfed version does all of these ifs as ternary operations
    // and avoids using 2-character operators wherever possible
    // so e.g. "a == 0" becomes "a<1" and "a && b" becomes "a&b"
    // since here we are certain things can't be negative,
    // and took a good look at the Java operator precedence cheat-sheet
    // to make sure "&" and "|" would work properly to give a truthy value
    if (level == 0) {
      // if we are at the bottom level, just put the rest of the wax there
      waxAtLevel = waxRemaining;
    } else if (minutes >= 60 || (minutes >= 45 && level < 3)) {
      // otherwise if we are at a legal level put a random portion of the remaining wax there
      // note: the random portion can be between 0 and waxRemaining inclusive
      waxAtLevel = (int) (Math.random() * (waxRemaining + 1));
    }

    if (waxAtLevel > 0) {
      // only print the amount of way at this level if its greater than 0
      System.out.print(waxAtLevel);
    }
    System.out.println();

    waxRemaining -= waxAtLevel;
  }
}

2
Math.random()*(w+1)可以是Math.random()*-~w-2个字节。这里相关提示作为参考。。好答案!向我+1。编辑:实际上,通过使用j临时变量作为变量,可以再保存2个字节w+1(因为无论如何它将在打印后立即被覆盖)并使用j*=Math.random()代替,因此您不需要强制转换为(int)117个字节)。
凯文·克鲁伊森

@KevinCruijssen真好!我也注意到&i>2条件不是必须的
SamYonnou

3

Powershell188162字节

param($m);$t=0;$a=,0*5;$s=if($m-lt45){4}elseif($m-lt60){2}else{0};$s..4|%{$t+=$a[$_]=if($_-eq4){1e3-$t}elseif($t-ne1e3){Random(1000-$t)}}$a|%{if($_){$_}else{''}}

在线尝试!

@Kevin Cruijssen -2字节-通过缩短 循环并删除空格
来删除可选的Get-verb
-20字节-4字节


嗨,欢迎来到PPCG!很棒的第一答案!我做了一些基本的测试,一切似乎都很好。我对Powershell几乎一无所知,但是可以更改else{if($t-ne 1e3){Get-Random(1000-$t)}}elseif($t-ne 1e3){Get-Random(1000-$t)}吗?我看到您elseif在代码中使用了更早的版本,因此这应该为您节省2个字节。另外,也许Powershell 中的打高尔夫球技巧<all language>中的打高尔夫球技巧可能会为您带来更多灵感?入住愉快!:)
Kevin Cruijssen

1
完全正确的ifelse。在此过程的早期删除了其他else副本。链接也给了一些启发!
埃德温

2

帕斯卡(FPC)192190字节

var n,a:word;z:array[0..4]of word;begin read(n);if n>44then a:=a+3;if n>59then a:=a+2;Randomize;for n:=0to 999do inc(z[random(a)]);for n:=0to 4do if z[n]>0then writeln(z[n])else writeln end.

在线尝试!

TFeld装箱装箱法。首先打印底行,后跟换行符。

FPC似乎没有问题random(0),因此我在其中添加了一些异常内容。


我最初提交的内容压缩到209个字节:

var n,i,a,r:int32;begin read(n);if n>44then a:=a-2;if n>59then a:=a-2;r:=1000;Randomize;for i:=-3to-0do begin if i>a then begin n:=random(r+1);if n>0then write(n);r:=r-n;end;writeln;end;if r>0then write(r)end.

在线尝试!


2

木炭,37字节

F²F²⊞υ∧‹³⁺ι÷Iθ¹⁵‽⊕⁻φΣ∨υω⊞υ⁻φΣυEυ⎇ιIιω

在线尝试!链接是详细版本的代码。说明:

F²F²

循环两次,两次。或者,对于相同的字节数,我可以用整数将循环索引除以2。

‹³⁺ι÷Iθ¹⁵

如果外部指数加上温度的十五分之一大于三...

⊞υ∧...‽⊕⁻φΣ∨υω

...然后将一个随机整数推至并包括1000-到目前为止的总和。不幸的是,木炭无法计算空列表的总和,因此我不得不替换为空字符串。

⊞υ⁻φΣυ

将剩余金额推入列表。

Eυ⎇ιIιω

将列表转换为字符串,但使用空字符串而不是零。


2

果冻,28个字节

>“,;‘SḤ‘µȷŻṗS⁼¥ƇȷX;0ẋ5¤ḣ5Yḟ0

完整程序打印结果(允许的情况下,上下颠倒)。

在线尝试!-更改为使用,7而不是ȷ(1000),因为实现速度在高尔夫球运动上很慢!(...对于ñ>59 的清单 1015 先创建5元组,然后过滤,然后从中选择)

怎么样?

>“,;‘SḤ‘µȷŻṗS⁼¥ƇȷX;0ẋ5¤ḣ5Yḟ0 - Main Link: integer, n
 “,;‘                        - list of code-page indices = [44,59]
>                            - greater than? (vectorises)
     S                       - sum (i.e. 0, 1 or 2)
      Ḥ                      - double (i.e 0, 2 or 4)
       ‘                     - increment (i.e. 1, 3 or 5)
        µ                    - start a new monadic link, call that x (i.e. f(x))
         ȷ                   - literal 1000
          Ż                  - zero-range = [0,1,2,...,1000]
           ṗ                 - Cartesian power (all tuples of length x using those numbers)
               Ƈ             - filter keep if:
              ¥              -   last two links as a dyad:
            S                -     sum
             ⁼  ȷ            -     equals 1000? (i.e. only valid tuples)
                 X           - random choice (get one of these tuples)
                      ¤      - nilad followed by link(s) as a nilad:
                   0         -   zero
                    ẋ5       -   repeat five times = [0,0,0,0,0]
                  ;          - concatenate     (e.g. [354,388,258,0,0,0,0,0])
                       ḣ5    - head to index 5 (e.g. [354,388,258,0,0])
                         Y   - join with newlines
                          ḟ0 - filter out zeros
                             - implicit print

1
也允许您反转输出(即,1000\n\n\n\n代替\n\n\n\n1000[87, null, 913, null, null]代替。[null, null, 913, null, 87])。因此,可以,使用不带的28字节版本
凯文·克鲁伊森

2

嫩枝,126字节

这实际上是一个有趣的挑战!

这段代码创建了一个必须导入的宏。

{%macro a(s,z=1000)%}{%for _ in 4..1%}{%set t=s>59or(s>44and _<3)?random(z):''%}{%set z=z-t%}{{t}}
{%endfor%}{{z}}{%endmacro%}

要导入它,只需执行以下操作:

{%- import 'macro.twig' as a -%}
{{- a.a(50) -}}

这应该可以解决问题。

您可以在https://twigfiddle.com/t4dfgy上尝试使用它。
注意:由于该页面删除了空格,我被迫-在行尾添加a ,以证明其输出的行数正确。

在常规安装中,您只会看到换行而没有问题。


2

Perl 6,62个字节

{($!=1e3)||@,|((+$!-($!-=$!.rand+|0)||@)xx($_/15+|0)*2-4)[^4]}

在线尝试!

匿名代码块,它接收一个字符串并返回一个整数列表,用Nil或空列表([])代替0s。

说明:

{($!=1e3)||@,|((+$!-($!-=$!.rand+|0)||@)xx($_/15+|0)*2-4)[^4]}
{                                                            }  # Anonymous code block
 ($!=1e3)  # Initialise $! to 1000
                +$!-($!-=$!.rand+|0)     # Pick a random value from 0 to $!
                                    ||@  # Or an empty array if it is zero
            ,  (                       )xx  # Repeat this
                                          ($_/15+|0)*2-4  # The given value mapped to 0,2,4
             |(                                         )[^4] # Get the first four values
 ($!    )||@  # Where the first value is the leftover number in $! or an empty array

2

PHP113 108 99 97 93字节

<?php $i=$argv[1];while($a++<1e3){${r.rand(1,$i<60?$i<45?:3:5)}++;}echo"$r5
$r4
$r3
$r2
$r1";

在线尝试!

@titus
-9个字节,因此-11个字节,因为一切都是字符串


2

J56 55 54 48 43 40字节

5{.1e3(2<@-/\[,0,~[:\:~?@$~)2*1#.>&44 59

在线尝试!

-3字节归功于FrownyFrog


另一种在概念上不错的方法,该方法要长一些,但可以确保按照以下方法在所有可能性上实现完全均匀的分配:

J,53字节

5$!.a:[:<@(+/);._1 0:,(1e3#1)({~#?#)@,0$~2*1#.>&44 59

在线尝试!


是不是$!.a:{.
FrownyFrog

@FrownyFrog谢谢。我忘记了,使用多于可用元素的元素会导致“零”填充。
约拿


1

红宝石62 55字节

->n{w=1000;[4,4,3,3].map{|r|r*15>n||w-=q=rand(w);q}<<w}

在线尝试!

测试限于0-99度,因为熔岩灯可能很危险在更高的温度下:


嗨,您好。恐怕您的答案无效。它当前具有0用于空行。数组中的空行可以是除以外的任何内容0,也可以是false负数。因此,它可以是null""[],等,但不0。不知道Ruby是否具有对象数组/列表,以便可以将0s 转换为其他对象,但是如果不是,则必须打印它们而不是返回数组/列表。
凯文·克鲁伊森

已修复,但我认为这有点太武断了。
GB
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.