| Bytes | Lang | Time | Link |
|---|---|---|---|
| 037 | Japt | 210825T100229Z | Shaggy |
| 155 | Wolfram Language Mathematica | 231120T035612Z | dalamaja |
| 106 | FMSLogo | 231119T102350Z | jan |
| 158 | Bash | 231119T124905Z | matteo_c |
| 117 | JavaScript ES6 | 210826T091845Z | Arnauld |
| 114 | JavaScript V8 | 231117T020352Z | l4m2 |
| 049 | MathGolf | 210902T105326Z | Kevin Cr |
| 036 | 05AB1E | 210825T092700Z | ovs |
| nan | Java JDK | 210826T082407Z | mindover |
| 514 | CSASM v2.5.1 | 210827T205923Z | absolute |
| 129 | Python 3 | 210825T120348Z | Jitse |
| 138 | Perl 5 | 210825T140727Z | Denis Ib |
| nan | C#[9.0] 203 Bytes Condensed | 210825T202103Z | Taco |
| 137 | C gcc | 210825T160608Z | jdt |
| 118 | JavaScript | 210825T150014Z | Shaggy |
| 034 | Jelly | 210825T181837Z | caird co |
| 114 | Ruby | 210825T225514Z | Level Ri |
| 037 | Vyxal rR | 210825T205720Z | emanresu |
| 064 | APLDyalog Unicode | 210825T112139Z | ovs |
| 051 | Charcoal | 210825T092810Z | Neil |
Japt, 40 39 38 37 bytes
This version has a very high probability of having all 4 layers, using a similar approach as Level's Ruby solution of generating all 4 layers, removing the ones consisting entirely of empty quadrants and making a recursive call if there are none left.
ªß4Æ"RWCS"ï`Õ½wbgp` p-² ö4 qÃfÈr-Ãq':
Wolfram Language (Mathematica), 155 bytes
r=RandomInteger
c=RandomChoice
t=Table
StringRiffle[StringJoin/@(Nest[#/.c@#->"--"&,#,r@2]&/@t[t[#<>#2&@@c@*Characters/@{"RWSC","urgbypcw"},4],r@3+1]),":"]
The distribution of the non-empty quadrants is uniform, but the distribution of shapes is not, as empty quadrants are generated after the fact.
TIO requires two extra bytes for symbol assignment so that the output can be printed.
FMSLogo, 106 bytes
show bl map[word pick bf invoke[(crossmap "word ? ? ? ?)]se[--]crossmap "word[RWCS urgbycpw]":]random 1500
Don't try it online. The calormen.com logo interpreter does not support "templates" (which is what logo calls anonymous functions) on map, only procedure names; it's error messages also leave something to be desired. The program works in FMSLogo 8.3.2 and propably MSWLogo and UCBLogo as well, as FMSLogo is based on them.
Explaination:
- Logo is based on lisp but allows omitting parentheses around procedures that use their default arity.
crossmapgenerates all possible combinations of the members of its inputs, which can be given in a list. The first input is a function, or "template", which is passed each combination to combine them.- I don't know a better way to remove the empty layer yet, so the first
crossmapgenerates a 1185921 element list of every possible layer and thenbfremoves the first one. That's why this program takes approximately 27 seconds to run on my laptop. - Numbers can be coerced to strings in logo, so
mapmaps the big instruction list in the middle over the characters of a random number, which has some length between one and four.repeat 1+random 4[...]would not output the concatenation of the results, and usingmap[...]iseq random 4 4is 4 characters longer. - I would not be able to tell, of course, but maybe some correlation in the random number generator makes some shapes actually impossible. I am not going to investigate.
Anonymous functions can not be called the normal way, unlike in javascript for example. They must be called by apply, map, or similar, which is why I consider
[bl map[word pick bf invoke[(crossmap "word ? ? ? ?)]se[--]crossmap "word[RWCS urgbycpw]":]random 1500]
to be an invalid submission.
Alternative much faster 5 characters longer solution, which, unlike the submission, can propably produce empty output:
FMSLogo, 111 bytes
show bl map[invoke[if ?="--------: ["][?]]word map[pick se[--]crossmap "word[RWCS urgbcypw]]1234 ":]random 1500
Sample shape: CpCuRpSc:SwSuCcWr:Sb--RwSb (everyone seems to do this)
Bash, 158 bytes
p='eval printf %s, '
s=$($p {S,W,C,R}{u,g,b,r,y,c,p,w})--
l=`$p{$s}{$s}{$s}{$s}`
$p{$l}:{$l}:{$l}:{$l}|tr , \\n|sed -E "s/-{4}(:|$)//g;/(^|:)(:|$)/d"|shuf -n1
JavaScript (ES6), 117 bytes
-2 thanks to @l4m2
Although this is not required, this solution has a uniform distribution.
f=(k=(R=Math.random)()*4|0,q=R(n=4)*1185920)=>n--?f(k,q/33)+'SWCR-'[((q%=33)&35)%7]+'ugbrycpw-'[q>>2]:k?f(k-1)+':':''
JavaScript (V8), 117 116 114 bytes
f=(k=n=5*~R(4))=>++n?n%5?R(~k%5)?'--'+f(k+1):'SWCR'[R(4)]+'ugbrycpw'[R(8)]+f(k):':'+f(n):''
R=n=>Math.random()*n|0
If already \$k\$ empty in this layer, then there's \$\frac 1{4-k}\$ probably be not empty, aka 1 when already 3 empty
MathGolf, 49 bytes
{╘4{4{"CRSW"w"bcgpruwy"w+v¶╛æ;û--}Γy}Γ'-8*a-}↔':u
The first output was: CwRuRrRw:RpSwSbRp:RcWpRpCu:CpWwWgWc:

Explanation:
{ ... }↔ # Do while false without popping:
╘ # Empty the stack (in case we've encountered a fully empty result)
4{ # Loop 4 times:
4{ # Inner loop 4 times:
"CRSW"w # Push a random character from "CRSW"
"bcgpruwy"w # Push a random character from "bcgpruwy"
+ # Concat these two characters together
v # Push a random integer in the range [-2147483648,2147483647]
¶╛ # If this integer is a prime number,
æ # use the following four character as inner code-block:
; # Discard the earlier character pair
û-- # Push "--"
} # After the inner loop:
Γ # Wrap the top four items into a list
y # And join this list together to a single string
} # After the outer loop:
Γ # Wrap the top (up to) four items into a list
'-8*a- '# Remove any strings consisting of 8 "-"
}↔ # After the do-while false:
':u '# Join the list with ":" delimiter
# (after which the entire stack is output implicitly as result)
Compressed strings are pretty mediocre in MathGolf, so unfortunately it won't save any bytes here. "CRSW"w can be ╖╖`'w+wδ which is 1 byte longer, and "bcgpruwy" can be ╕█≈║☺ 'ußy which is the same byte-count.
05AB1E, 35 40 38 36 bytes
+5 to prevent empty output which would've occured with probability \$33^{-16}\$
-2 bytes thanks to Kevin Cruijssen!
Quite slow, generates \$33^4\$ possible layers 4 times and chooses a random one each time. Layers of all - are removed.
[₄ε‘¥„W‘’»Õpcw’â„--ª4ãΩJ}'-8×K':ýDĀ#
At the cost of two bytes this can actually run fast: Try it online!
Because every quadrant in each layer has a \$1\$ in \$33\$ chance of being empty the resulting shapes are quite noisy:
[ ... Dg# # until the the output is not empty, do the following:
₄ # push constant 1000
ε } # for each digit in this number:
‘¥„W‘ # dictionary compressed string "SRCW"
’»Õpcw’ # dictionary compressed string "rugbypcw"
â # cartesian product of the two strings
„--ª # append "--" to this list
4ã # 4th cartesian power, all 4-element combinations from the length-2 strings
Ω # choose a random one
J # join into a single string
'-8× # string of 8 -'s
K # remove all occurences from the list
':ý # join the list by ":"
Java (JDK), 263 253 bytes
-10 thanks to ceilingcat! Forgot that | exists and that ternary ifs can be written without parentheses. D'oh!
String f(int i){var r=new Random();var q=""+"SWCR-".charAt(r.nextInt(5));q+=q.equals("-")?'-':"ugbrycpw".charAt(r.nextInt(8));return i<1?(f(2)+f(2)+f(2)+f(3)).substring(1):i<9?i>2|r.nextInt(2)<1?(":"+f(9)+f(9)+f(9)+f(9)).replace(":--------",f(1)):"":q;}
Took forever to find something promising, ow my head...
This won't win any prices, but I liked the approach so here it is anyways. It uses the same function recursively with a different parameter to build different parts of the string.
I hope I find the template for Java lambdas again, I keep forgetting how the boilerplate needs to look for them to work :(
EDIT:
Function lamdas aren't shorter in this case, since you don't call but apply() them, which is WAY longer. Still, thanks for the template Johan du Troit!
Explained:
// function is called with 0 to start
String f(int i) {
// use var because it's shorter
var r=new Random();
// build a quadrant
// decide on a type...
var q=""+"SWCR-".charAt(r.nextInt(5));
// ...and append the color. If the type is "-" then append a "-" instead
q+=q.equals("-")?'-':"ugbrycpw".charAt(r.nextInt(8));
// decide what to return
return
// shape case: build full shape
i<1?
// a shape consists of four layers
// each layer starts with a :, cut the first one off
(f(2)+f(2)+f(2)+f(3)).substring(1)
// not the starting case, check for layer case
:i<9?
// build one layer. It either doesn't exist or contains four shapes
// note: 3 overrides the random decision and always returns a layer
i>2|r.nextInt(2)<1?
// replace an empty layer with a newly generated one...
(":"+f(9)+f(9)+f(9)+f(9)).replace(":--------",f(1))
// ...or return a nonexistant layer
:""
// not the shape case nor the layer case, return the quadrant calculated above
:q;
}
CSASM v2.5.1, 514 bytes
func a:
lda 0
sta $1
lda ""
sta $2
push 1
push 5
extern Random.Next(i32,i32)
pop $a
.lbl a
push $a
brfalse b
dec $a
push 0
pop $1
push ""
pop $3
.lbl c
push $1
push 4
sub
brfalse d
inc $1
push "RWSC-"
push 5
extern Random.Next(i32)
dup
push 1
add
substr
dup
push "-"
sub
len
brtrue f
dup
add
br e
.lbl f
push "urgbypcw"
push 8
extern Random.Next(i32)
dup
push 1
add
substr
add
.lbl e
push $3
swap
add
dup
pop $3
push "--------"
sub
len
brtrue c
push 0
pop $1
push ""
pop $3
br c
.lbl d
push $2
push $3
add
pop $2
push $a
brfalse a
push $2
push ":"
add
pop $2
br a
.lbl b
push $2
print
ret
end
Whew, this was one mammoth of a program to write.
This submission defines a function a which generates then prints the random shape string as is specified by the challenge.
Explained:
func a:
; $a = random value in [1, 4]
; $1 = loop counter for quadrants
; $2 = final string
; $3 = build string
lda 0
sta $1
; Initialize $2 to an empty string
lda ""
sta $2
; Initialize $a to the random value specified above
push 1
push 5
extern Random.Next(i32,i32)
pop $a
.lbl a
; Stop looping if $a == 0
push $a
brfalse b
dec $a
; Reset $1 and $3
push 0
pop $1
push ""
pop $3
.lbl c
; Stop looping if $1 == 4
push $1
push 4
sub
brfalse d
inc $1
; Get a random letter in "RWSC-"
push "RWSC-"
push 5
extern Random.Next(i32)
dup
push 1
add
substr
; Check if the letter was "-"
dup
push "-"
sub
len
brtrue f
; Letter was "-"; just add the other one
dup
add
br e
.lbl f
; Letter was not "-"; Get the color
push "urgbypcw"
push 8
extern Random.Next(i32)
dup
push 1
add
substr
; Add the two parts together
add
.lbl e
; Add the new piece to $3
push $3
swap
add
dup
pop $3
; Check $3. If it's "--------", generate another layer
push "--------"
sub
len
brtrue c
; Reset the quadrants counter and build string
push 0
pop $1
push ""
pop $3
br c
.lbl d
; Append the layer to the result
push $2
push $3
add
pop $2
; If $a == 0, don't add the ":"
push $a
brfalse a
push $2
push ":"
add
pop $2
br a
.lbl b
; Print the result
push $2
print
ret
end
The first run of this code produce the following shape:
--Cp----:--RgSg--:CgRwWbRr:WyWpWwWw

More examples of shapes generated by the code:
--ScWyRp
WuWuCbRg:--RbSwRc:CwRuWrCb
CgSgRpCb:Cu--SrRb
Wc--CcCg:----CrRu
SyCbWc--
SrCbSc--:----WrWb
Ry--CgSr:--Cp--Sw
--CwWpCc:CbCpRcSy:CpWw--Cy:--Ru----
Python 3, 129 bytes
from random import*
print(':'.join(''.join(sample(q,4))for q in[[i+j for i in'RWSC'for j in'urgbypcw']*4+['--']*3]*randint(1,4)))
For each layer, 4 items are picked from a distribution containing 3 empty quadrants and the other shape-colour combinations 4 times.
Perl 5, 95 138 bytes
{@q=(qw(: --),map{$s=$_;map$s.$_,ugbrycpw=~/./g}C,R,W,S);@i=map$_%5?$==1+rand
33:0,1..rand 19;@i%5==4&&" @i "!~/ (1 ){4}/||redo;say@q[@i]}
C#[9.0] - 191, 235, 228, 204, 203 Bytes (Condensed)
static Random r=new();static string g(){var z="";for(int j,i,l=r.Next(1,4);l-->0;z+=":")for(i=j=0;i++<4;)z+=r.Next()%8<1&&j++<3?"--":$"{"CRWS"[r.Next(0,3)]}{"rgbypcuw"[r.Next(0,7)]}";return z.Trim(':');}
+44bytes due to a missed requirement.-5bytes by reducingGetShapetogper @emanresu A's recommendation.-24bytes by usingvar, consolidating declarations and using constant strings per @Johan du Toit.-1byte by swapping==0for<1per @ceilingcat.
How it Works
// Create a new random number generator using C# 9.0's `new` invocation.
static Random r = new();
static string g() {
// Create a variable to store the possible shapes.
string s = "CRWS",
// Create a variable to store the possible colors.
c = "rgbypcuw",
// Create a variable to store the result.
z = "";
// Create an iteration variable to iteratively create between 1 and 4 layers randomly.
// Evaluate for stop then decrement.
// Append `:` to the result.
for (int l = r.Next(1, 4); l-- > 0; z+=":")
// Create an iteration variable to iteratively create the four quadrants.
// Create a variable for tracking the number of empty quadrants.
for (int i = 0, j = 0; i++ < 4;)
// If we haven't reached the maximum number of allowed empty quadrants, a new one can still be added.
// Use a random number to determine if we should create an empty quadrant.
// Since && short circuits, the increment of J doesn't occur unless we're adding an empty quadrant.
if (r.Next() % 8 == 0 && j++ < 3)
// Add an empty quadrant.
z += "--";
// Otherwise, add a shape and color from the variables above,
// using a random index within the bounds of the variables lengths.
else
z += $"{s[r.Next(0, 3)]}{c[r.Next(0, 7)]}";
// Return the result and remove any trailing `:`.
return z.Trim(':');
}
Sample Output
I called the method in a for loop over 10 iterations to sample the output for this post:
--CyCpCb:RpCu--Rc
RpCyWbWc:RcWuWyWc
CyWy--Cr:RrWpWuWg
Wp--WuRc
RpCcCgWp
CbWuWgCu:--RcRbWg:CcCuCpCc
RgRpCyCu:CbWyWuCu
CgCuRpCu
CyRc--Ru:WuRuRbRu:--CgRbWr
WpCgCpRu
Resulting Image Sample
I ran the shape code CbWuWgCu:--RcRbWg:CcCuCpCc through and got this result:

C (gcc), 137 bytes
#define r rand()
m;b;q(){m=r;m&30||q();}f(){for(q(b=5+r%4*5);--b;)printf(b%5?m&1<<b%5?"%c%c":"--":":"+!q(),"WRSC"[r%4],"rugbywcp"[r%8]);}
-5 bytes thanks ceilingcat!
JavaScript, 125 120 119 115 112 118 bytes
To avoid the possibility of an empty layer, we force the 4th quadrant to be non-empty if all previous quadrants are already empty (+6 bytes 'cause I realised I'd screwed that up).
Need to figure out a way to shorten the selection of the characters.
(r=x=>Math.random(g=s=>s[7]?l--?s+`:`+g``:s:g(s+`RWSC-`[c=r(5^s==`------`)]+`urgbypcw-`[c-4?r(8):8]))*x|0,l=r(4))=>g``
Jelly, 38 35 34 bytes
“SWCR”p“¬,ĖṆḷ⁸»Żṗ4XʋⱮ4ẸƇƊṆ¿o⁾--j”:
This just about finishes on TIO most of the time (it has a \$1\$ in \$33^{16}\$ chance of taking longer), taking around 55 seconds. Full program, as we require Jelly's smash-printing to get the correct output
-4 bytes thanks to Jonathan Allan!
The first sample output I got was:
How it works
“SWCR”p“¬,ĖṆḷ⁸»Żṗ4XʋⱮ4ẸƇƊṆ¿o⁾--j”: - Main link. No arguments. Left argument = 0
Ɗ - Group the previous 3 links into a monad f(_): (ignores the argument)
“SWCR” - Set the return value to “SWCR”
ʋ - Group the previous 4 links into a dyad g(“SWCR”, i): (ignores i)
“¬,ĖṆḷ⁸» - Compressed string: “rugbypcw”
p - Cartesian product with “SWCR”
Ż - Prepend a zero (represents “--”)
ṗ4 - 4th Cartesian power
X - Choose a random list
Ɱ4 - Yield [g(“SWCR”,1), g(“SWCR”,2), g(“SWCR”,3), g(“SWCR”,4)]
ẸƇ - Remove any that are just zeros
¿ - While:
Ṇ - The left argument is falsey ([] or 0)
Ɗ - Set the left argument to f(_)
o⁾-- - Replace all zeros with “--”
j”: - Join by ”: and smash-print
Ruby, 117 114 bytes
->{s=((0..19).map{|i|i%5<1??::"-SWCR"[(r=rand 40)/8]+"rgbpucyw-"[r<8?8:r%8]}*'').gsub ?:+?-*8,''
s>''?s[1,99]:f[]}
A function returning a string.
Commented code (original version)
->{s=
((0..19).map{|i|i%5<1? #Iterate 20 times to make an array. if i%5==0
?:: #put a colon, else...
"-SWCR"[(r=rand 40)/8]+ #Select a shape
(r<8??-:"rgbpucyw"[r%8]) #If selected shape is - then put another -, else put a colour
}*''). #Convert the 20-element array into a string
gsub(?:+?-*8,'') #Delete all instances of :--------
s<?!?f[]:s[1,99]} #If s is empty, recursively call f[] to try again. Else output s (minus the initial colon)
Vyxal rR, 37 bytes
\:4℅ƛ«3⟩∑ḣ`«`SWRC`Ẋ‛--J33²²‹℅τ∑₅8ε-;j
This uses a quite neat custom-base-decompression-based approach to ensure there'll never be an empty layer. It basically generates a random number between 1 and \$33^4 - 1\$, decompresses it with the key as all possible quadrants (with -- first, so 0 can never occur, so empty layers won't either).
4℅ƛ ; # array of length (random 1-4) filled with...
33²²‹℅ # Random integer between 1 and 33^4-1 inclusive
τ # Decompressed by...
Ẋ # Cartesian product of...
«3⟩∑ḣ`« # Compressed string `bcgpruwy`
`SWRC` # String literal `SWRC`
‛--J # Prepend a `--`
∑ # Concatenate all this
₅8ε- # Pad with `-` from the start
j # Join the whole thing by...
\: # Semicolons.
APL(Dyalog Unicode), 64 bytes SBCS
A full program that prints the shape.
⊃{∊⍺':'⍵}/{∊((⊂'--'),,'RWCS'∘.,'urgbypcw')[?4⍴33]}⍣{∨/'-'≠⍺}¨⍳?4
?4 random integer between 1 and 4
... ¨⍳ call the function on the left this many times and collect the results in a list:
{ ... }⍣{∨/'-'≠⍺} until any char in the result is not -:
'RWCS'∘.,'urgbypcw' Cartesian product of the two strings
, flatten into a list of 2-char strings
(⊂'--'), prepend the empty quadrant
( ... )[?4⍴33] get elements at 4 random indices between 1 and 33.
∊ flatten into a string
{∊⍺':'⍵}/ join with :
⊃ get the first element from the nested output
Charcoal, 51 bytes
⪫EE⊕‽⁴⊕‽⊖X³³¦⁴⭆E⁴÷ιX³³λ⎇﹪λ³³⁺§RWSCλ§urgbypcw÷λ⁴--¦:
Try it online! Link is to verbose version of code. Explanation:
‽⁴ Random integer 0-3
⊕ Incremented
E Map over implicit range
X³³¦⁴ 33⁴
⊖ Decremented
‽ Random integer
⊕ Incremented
E Map over random integers
E⁴ Map over quadrants
÷ι Current random integer
÷ Integer divide by
³³ Literal integer `33`
X Raised to power
λ Current quadrant
⭆ Map over values and join
λ Current value
﹪ ³³ Modulo literal `33`
⎇ If nonzero then
§RWSCλ Cyclically indexed colour
⁺ Concatenated with
§urgbypcw Shape cyclically indexed by
λ Current value
÷ Integer divide by
⁴ Literal integer `4`
-- Else literal string `--`
⪫ : Join with literal `:`
Implicitly print


