Simplistic Lava Lamp

18

3

Introduction:

I think everyone knows what a Lava Lamp is, but in case they do not:

enter image description here
(Image source)

They're basically glass tubes that contain wax in a translucent liquid. The bottom part is heated when the lamp is turned on, causing a change in density and thus the wax floats to the top. When it cools down, it falls down again, causing the effect we see above.

It usually takes about 45-60 minutes for the base of the lamp to rise in temperature high enough to change the solid wax to liquid wax (if the lamp is located in an area at room temperature).

More information on Wikipedia, which is also used as source for some of the text above.

Challenge:

Given a positive integer n indicating the amount of minutes that have passed since we've turned the Lava Lamp on, output a random state of the Lava Lamp based on integers on five levels.

For this challenge we'll say the Lava Lamp contains 1000 units of wax in total, and we have five levels where the wax can be at.

1) If n is below 45, the Lava Lamp is still heating up, so the output will be four empty lines with 1000 at the bottom:





1000

2) If n is in the range [45, 60) the Lava Lamp has increased in temperature enough for wax to move around, but no very high yet. The wax can reach up to and including the third level.
3) If n is 60 or higher, the wax can be at any of the five levels.

So given the positive integer n as input, we'll output a random state with the three rules above in mind.

Here are some example outputs:

Possible outputs for any n that is >= 45:



523
106
371


913

87

Possible outputs for any n that is >= 60:

73
113
312
5
497
284
55
637

24

Constant output for n that is <= 44 (and possible output for any n):





1000

Challenge rules:

  • There can be empty lines, even though the level above it is not empty.
  • Just 0 isn't allowed on any line. Should be empty instead.
  • Output is somewhat flexible. You are allowed to output a list/array of strings/objects instead of a new-line delimited result as above. The reason I say strings/objects is due to the rule above. An empty line should be "", null, [], etc., but cannot be 0 or a negative integer (nor can it be false) (I.e. ["", "", 913, "", 87] for n >= 45). You are also allowed to reverse the output (I.e. 1000\n\n\n\n instead of \n\n\n\n1000 or [87, null, 913, null, null] instead of [null, null, 913, null, 87]).
  • The numbers should all be integers. The can be decimals with 0 as decimal value, but none of the numbers should have any decimal digits, and the integers should always sum to exactly 1000.
  • All possible random outputs based on n should have a non-zero chance of occurring.
  • A trailing new-line (so there are six lines of output) is allowed.

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code.
  • Also, adding an explanation for your answer is highly recommended.

Kevin Cruijssen

Posted 2018-09-11T07:44:53.423

Reputation: 67 575

May an empty level be represented with a single space? – Arnauld – 2018-09-11T08:20:56.877

@Arnauld Sure. Can be anything except for 0, a negative number, or false. – Kevin Cruijssen – 2018-09-11T08:48:55.673

Is the output always 5 levels, even when n < 60? – Emigna – 2018-09-11T09:18:24.160

@Emigna Yes, the output is always 5 levels. For n < 45 only 1 level is filled however (top or bottom depending on the order you output it in), which is 1000. With 45 <= n < 60 three of the five, and with n >= 60 all five. But the output will always contain five 'lines'. – Kevin Cruijssen – 2018-09-11T10:04:43.887

I assume it's not allowed, but it would be funny to bypass the 0 is an empty string by outputting in unary. – Jo King – 2018-09-12T02:06:20.330

Answers

5

MathGolf, 21 20 bytes

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

Try it online!

This is my first answer in my new language. I based my solution on Emigna's 05AB1E solution, but used some neat features of MathGolf to make it a tiny bit shorter.

Explanation

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)

maxb

Posted 2018-09-11T07:44:53.423

Reputation: 5 754

If the features aren't builtins for this challenge in of itself, the non-competing tag won't be necessary. Since mid last year non-competing is no longer a thing. Since it's very new I assume there isn't an online compiler for your language yet? Could you instead perhaps add some screenshots (or links to screenshots if it would clutter the post too much) as verification? And I would contact @Dennis' to ask if your language could be added to TryItOnline.

– Kevin Cruijssen – 2018-09-12T11:39:35.170

2@KevinCruijssen Thanks for the feedback! I'll add some screenshots, and I'm working on getting the language to TIO. I'll contact Dennis once I feel that I'm not constantly adding new features. – maxb – 2018-09-12T11:44:33.293

Have you considered creating a room for your language? I'm very interested in learning it!

– Jo King – 2018-09-15T10:36:05.187

@JoKing glad to hear you're interested! I'll try to create a room sometime this weekend. I only just got the language on TIO thanks to Dennis, I'm working on making it accessible to everyone! – maxb – 2018-09-15T10:55:37.020

@JoKing I created a room for MathGolf. I'll try to answer any questions as soon as I can, I know the documentation is a bit unfinished.

– maxb – 2018-09-17T07:14:37.213

8

Python 2, 117 113 108 107 106 105 bytes

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

Try it online!

Returns a reversed list (bottom first)


Version inspired by the stackoverflow answer in the comments (edgecases are more likely):

Python 2, 129 bytes

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

Try it online!

TFeld

Posted 2018-09-11T07:44:53.423

Reputation: 19 246

I don't know exactly how your code work, but does every state have a non-zero chance of occurring? All your numbers are hovering near the 333 or 200 for the 3 or 5 parts respectively. I don't see any spikes/outliers towards 0 or 1000. Or are the chances for those just astronomically small (but still non-zero) in comparison to integers near 333 and 200? – Kevin Cruijssen – 2018-09-11T08:54:14.747

1@KevinCruijssen Each of the 1000 lava-units are put into a random bin (0 or 0-2 or 0-4), and counted. The chances of none of then going into either is there, but very small. – TFeld – 2018-09-11T08:59:14.523

Ah ok, that makes sense. Now I also understand your code better already. Thanks! +1 from me. – Kevin Cruijssen – 2018-09-11T09:01:17.820

7

JavaScript (ES6), 78 bytes

Returns a reversed array where empty levels are filled with a space.

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

Try it online!

Commented

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

Arnauld

Posted 2018-09-11T07:44:53.423

Reputation: 111 334

I actually have the same question as the comment I made for the Python answer: Does every state have a non-zero chance of occurring?

– Kevin Cruijssen – 2018-09-11T08:55:31.867

1

@KevinCruijssen Each state has a non-zero chance of occurring, but extreme values have a very low probability. If I did my maths correctly, you are ~$10^{90}$ times more likely to be hit by a meteorite than to get an intermediate empty slot in there. :p

– Arnauld – 2018-09-11T09:15:21.077

Rofl, nice analogy with the meteorite. ;) I now indeed see that your method is similar to the Python answer in that it puts values in one of the 3 or 5 spots in the array, up to a count of 1000. Nice answer, so +1 from me. – Kevin Cruijssen – 2018-09-11T09:30:04.593

6

R, 85 84 bytes

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

-1 byte thanks to @Giuseppe

Try it online!

Explanation (ungolfed):

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

J.Doe

Posted 2018-09-11T07:44:53.423

Reputation: 2 379

If NA is allowed as empty line/element, here's a 77 byte solution (Try it online!) or an 80 byte solution (Try it online!) if the element names are a problem

– duckmayr – 2018-09-11T23:19:35.097

6

C (gcc), 131, 116, 90, 89, 87 bytes

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

Try it online!

Update: Fixed a bug in the original. Fused in the helper function, reducing an additional 15 bytes.

Update 2: -25 bytes thanks to ErikF.

Update 3: -1 byte thanks to ceilingcat.

Degolf

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
}

user77406

Posted 2018-09-11T07:44:53.423

Reputation:

You can eliminate the puts() by combining the printing into a single printf() and putting the subtraction into the loop end. Also, I think you're allowed to put the srand() initialization into the caller. Try it online!

– ErikF – 2018-09-12T01:11:18.973

I realized that I missed the "no zeroes" restriction. Here's the fixed version: Try it online!

– ErikF – 2018-09-12T01:50:38.257

Some last tweaks! Try it online!

– ErikF – 2018-09-12T01:57:38.660

Great; I golfed it down by an additional byte. – None – 2018-09-12T09:43:25.697

1Also, we did it! We beat Python! – None – 2018-09-12T09:53:35.383

5

05AB1E, 27 26 25 bytes

Saved a byte thanks to Adnan.
Saved another byte thanks to Kevin Cruijssen.

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

Try it online!

Explanation

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

Emigna

Posted 2018-09-11T07:44:53.423

Reputation: 50 798

1Nice answer! I like the way you've used 5Å0 and ǝ, and ε0Û at the end. I tried to come up with something shorter, but I'm unable to. I have the feeling it can somehow still be golfed, but I'm currently not seeing it (perhaps it cannot and it's just a random feeling). •A–•60в is 1 byte longer than 44 59‚ instead of shorter. And ε0Û to replace the 0s with empty strings also seems to be the shortest possible, since 0K simply removes the 0-items completely and removes any digit 0 in all numbers. – Kevin Cruijssen – 2018-09-11T10:00:22.837

1@KevinCruijssen: Yeah I've looked and looked to find a shorter way of doing 44 59‚, but I can't find it (•H|•2ô is the same count). My previous solution (also 27 bytes) used 45 and 60 which are easier to generate in different ways, but I think that was invalid as it output 1, 3 or 5 levels depending on input and not always 5. – Emigna – 2018-09-11T10:04:30.187

Ah, •H|•2ô is indeed also a smart way, hadn't thought about that. And it should indeed output 5 lines. I saw your previous answer indeed and was about to comment it only outputted 1 line for n < 45, but then you deleted it. Glad you've found another 27-byte solution. :) – Kevin Cruijssen – 2018-09-11T10:07:49.900

2

I think ŽH|2ô is what you are looking for?

– Adnan – 2018-09-11T10:11:41.687

@Adnan: Oh, nice. I didn't know about Ž, only Ƶ. Thanks :) – Emigna – 2018-09-11T10:31:18.723

@Adnan Oh, never seen Ž used before either. Does that only apply to compressed integers as alternative for •..•? Or does it have some other use cases as well? – Kevin Cruijssen – 2018-09-11T11:26:55.480

2@KevinCruijssen It acts exactly like that. Did some research using previous answers using 05AB1E and this was one of the things I added in the rewrite. It does not have any other use cases right now. – Adnan – 2018-09-11T16:28:58.217

@Adnan I've edited my 05AB1E tip about compression to mention it as well. :)

– Kevin Cruijssen – 2018-09-11T16:33:55.667

-1 byte by changing ŽH|2ô to „,;Ç. Not sure why I hadn't thought about this before.. – Kevin Cruijssen – 2018-09-12T06:56:50.380

@KevinCruijssen: Oh yeah, that's smart. Thanks :) – Emigna – 2018-09-12T08:06:22.703

4

JavaScript (Node.js), 87 86 bytes

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):""

Try it online!

The 83-byte solution ((n/15-2|0)*s<4) is reserved first because I need to check for larger n.

UPDATE: Yeah, (n/15-2|0)*s<4 didn't work because for larger n because n large enough makes the sum fail to reach 1000.

Shieru Asakoto

Posted 2018-09-11T07:44:53.423

Reputation: 4 445

4

PHP, 92 bytes

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

Run as pipe with -R or try it online.

Titus

Posted 2018-09-11T07:44:53.423

Reputation: 13 814

3

Java (JDK 10), 121 117 113 111 bytes

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

Try it online!

It's biased towards putting more wax near the top, but it's theoretically possible for any legal arrangement of wax to appear.

edit: 4 bytes were saved by @KevinCruijssen

In Human-readable 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;
  }
}

SamYonnou

Posted 2018-09-11T07:44:53.423

Reputation: 816

2Math.random()*(w+1) can be Math.random()*-~w for -2 bytes. Here the relevant tip as reference why.. Nice answer! +1 from me. EDIT: Actually, 2 more bytes can be saved by using j temporary as variable for w+1 (since it will be overwritten right after in the print anyway) and use j*=Math.random() instead so you won't need the cast to (int) (117 bytes). – Kevin Cruijssen – 2018-09-11T18:48:59.780

@KevinCruijssen nice! Also I just noticed that the &i>2 condition isn't necessary – SamYonnou – 2018-09-11T20:28:49.227

3

Clean, 215 bytes

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

Try it online!

So I've finally found a shorter way to get a random seed than importing System._Unsafe, System.Time and using toInt(accUnsafe time)...
And boy is it truly in the spirit of codegolf - embedding a call to C, ignoring the world state type normally used to ensure the evaluation order of such things.

Οurous

Posted 2018-09-11T07:44:53.423

Reputation: 7 916

3

Powershell, 188 162 bytes

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

Try it online!

-2 bytes by @Kevin Cruijssen
-4 bytes by removing optional Get- verb
-20 bytes by shortning loop and removing spaces

Edwin

Posted 2018-09-11T07:44:53.423

Reputation: 71

Hi, welcome to PPCG! Great first answer! I did some basic testing, and everything seems to work great. I know barely anything about Powershell, but is it possible to change else{if($t-ne 1e3){Get-Random(1000-$t)}} to elseif($t-ne 1e3){Get-Random(1000-$t)}? I see you've used an elseif earlier in your code, so this should save you 2 bytes. Also, maybe Tips for golfing in Powershell or Tips for golfing in <all languages> might give some inspiration for more? Enjoy your stay! :)

– Kevin Cruijssen – 2018-09-13T20:04:11.440

1totally correct about the ifelse. Removed its else counterpart earlier in the process. Link gave some inspiration too! – Edwin – 2018-09-14T06:26:15.870

2

Pascal (FPC), 192 190 bytes

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.

Try it online!

Using packing into bins method by TFeld. Prints bottom row first with a trailing newline.

It seems that FPC doesn't have problems with random(0), so I have some unusual adding there.


My original submission, golfed down to 209 bytes:
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.

Try it online!

AlexRacer

Posted 2018-09-11T07:44:53.423

Reputation: 979

2

PHP, 113 108 99 97 93 bytes

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

Try it online!

-11 bytes thanks to @titus
-9 bytes because everything is a string

Einacio

Posted 2018-09-11T07:44:53.423

Reputation: 436

2

Jelly, 28 bytes

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

A full program printing the result (upside down, as has been allowed).

Try it online! - this is altered to use 7 rather than ȷ (1000) because the implementation is golf-tastically slow! (...for \$n>59\$ a list of \$10^{15}\$ 5-tuples is built and then filtered, from which to choose)

How?

>“,;‘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

Jonathan Allan

Posted 2018-09-11T07:44:53.423

Reputation: 67 804

1"You are also allowed to reverse the output (I.e. 1000\n\n\n\n instead of \n\n\n\n1000 or [87, null, 913, null, null] instead of [null, null, 913, null, 87])." So yes, you are allowed to use the 28-byte version without the . – Kevin Cruijssen – 2018-09-12T06:54:13.713

2

Charcoal, 37 bytes

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

Try it online! Link is to verbose version of code. Explanation:

F²F²

Loop twice, twice. Alternatively I could have integer divided the loop index by 2 for the same byte count.

‹³⁺ι÷Iθ¹⁵

If the outer index plus a fifteenth of the temperature is greater than three...

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

... then push a random integer up to and including 1000 - the sum so far. Unfortunately Charcoal can't calculate the sum of an empty list so I have to substitute the empty string instead.

⊞υ⁻φΣυ

Push the leftover amount to the list.

Eυ⎇ιIιω

Convert the list to string, but use the empty string instead of zero.

Neil

Posted 2018-09-11T07:44:53.423

Reputation: 95 035

2

Perl 6, 62 bytes

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

Try it online!

An anonymous code block that takes a string and returns a list of integers, with Nil or an empty list ([]) in place of 0s.

Explanation:

{($!=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

Jo King

Posted 2018-09-11T07:44:53.423

Reputation: 38 234

2

Twig, 126 bytes

This was an actually fun challenge!

This code creates a macro that has to be imported.

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

To import it, just do this:

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

This should do the trick.

You can try it on https://twigfiddle.com/t4dfgy
Notice: Due to the page removing whitespaces, I was forced to add an - at the end of the line, to prove that it is outputting the correct number of lines.

On a regular installation, you would just see the newlines without issues.

Ismael Miguel

Posted 2018-09-11T07:44:53.423

Reputation: 6 797

2

J, 56 55 54 48 43 40 bytes

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

Try it online!

-3 bytes thanks to FrownyFrog


Another conceptually nice method that's a bit longer but guarantees perfectly uniform distribution over all possibilities, per the method here:

J, 53 bytes

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

Try it online!

Jonah

Posted 2018-09-11T07:44:53.423

Reputation: 8 729

Isn't $!.a: just {.? – FrownyFrog – 2019-09-24T09:56:59.453

@FrownyFrog Thanks. I had forgotten that taking more elements than are available results in "zero" fill. – Jonah – 2019-09-24T13:47:41.877

2

PowerShell, 115 105 98 bytes

-17 bytes thanks to mazzy

$a=,0*5
45,60-ge"$args"|%{$i+=2}
$i..4|%{$t+=$a[$_]=random(1001-$t)}
$a[4]+=1e3-$t
$a|%{"$_"*!!$_}

Try it online!

A golf of Edwin's lovely answer. If you like this, upvote him.

Veskah

Posted 2018-09-11T07:44:53.423

Reputation: 3 580

1

nice. a bit more golf Try it online!

– mazzy – 2019-09-24T18:57:41.553

1

golf again 98 bytes

– mazzy – 2019-09-24T19:21:07.510

1

Ruby, 62 55 bytes

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

Try it online!

Tests are limited to 0-99 degrees, because lava lamps could be dangerous at higher temperatures:

G B

Posted 2018-09-11T07:44:53.423

Reputation: 11 099

Hi there. I'm afraid your answer is invalid. It currently has 0 for the empty lines. The empty lines in the array can be anything except for 0, false or a negative number. So it can be null, "", [], etc., but not 0. Not sure if Ruby has object-arrays/lists so you can transform the 0s to something else, but if not you'll have to print them instead of returning an array/list. – Kevin Cruijssen – 2018-09-12T10:59:15.830

Fixed, but I think it's a little too arbitrary. – G B – 2018-09-12T12:01:33.883