The game shapez.io has a huge variety of shapes you can produce, such as:
Each shape has a unique short code, for example the above is CrWbScRu.
This means, going clockwise from top right, red circle (Cr), blue wedge (Wb), cyan star (Sc), uncolored rectangle (Ru).
There are four different shapes:
- Rectangle -
R - Wedge -
W - Star -
S - Circle -
C
And eight different colours:
- uncolored -
u - red -
r - green -
g - blue -
b - yellow -
y - purple -
p - cyan -
c - white -
w
A quadrant is made out of one of each of these - (shape)(color). A quadrant can also be empty with --. This means there are 33 possible quadrants.
Four quadrants concatenated together make a layer, of which there are \33ドル^4 - 1 = 1185920\$ possibilities. You can't have an empty layer (--------). These layers can be stacked on top of one another by joining with : - the code CyCyCyCy:SrSrSrSr looks like:
Shapes can be stacked up to 4. This means there are \$\left(33^{4}-1\right)+\left(33^{4}-1\right)^{2}+\left(33^{4}-1\right)^{3}+\left(33^{4}-1\right)^{4} = \$ 1.97 septillion possible shapes total.
Your challenge is to randomly generate one of these.
Your generation does not have to be uniformly random, as long as every possible shape has a nonzero chance of being chosen.
Specs
- Each quadrant is one of
SWCRfollowed by one ofugbrycpw, or--. - A layer is four quadrants concatenated together.
- A shape is 1-4 layers joined by
: - You should generate a not-necessarily-uniformly-random shape.
You can view shapes at https://viewer.shapez.io/.
Scoring
This is code-golf, shortest wins!
20 Answers 20
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.
[4ε‘\„W‘’»Õpcw’â„--a×ばつ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:
SpSgCgRy:CyRgRcSw:RrCuScRu:ScSyWuCp
[ ... Dg# # until the the output is not empty, do the following:
4 # 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
„--a # 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×ばつ # string of 8 -'s
K # remove all occurences from the list
':ý # join the list by ":"
-
\$\begingroup\$ Damnit! Beaten by better string compression! :( \$\endgroup\$Shaggy– Shaggy2021年08月25日 14:23:19 +00:00Commented Aug 25, 2021 at 14:23
-
1\$\begingroup\$
4Lto4for -1. Also, the challenge states it can't have an empty layer, not that the entire output can't be empty. So'-8×K':ýDgĀ#is incorrect, since it only checks if the entire shape is empty. You can fix this with':ýD'-8×å≠#, which is also 1 byte shorter. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2021年09月02日 07:08:18 +00:00Commented Sep 2, 2021 at 7:08 -
1\$\begingroup\$ @KevinCruijssen Thanks for the -1! But for the second part of your comment the challenge states A shape is 1-4 layers [...], and since layers can't be empty this implies the output is not empty.
'-8×Kremoves empty layers, no? With your suggestion the output always has 4 layers. \$\endgroup\$ovs– ovs2021年09月02日 07:45:22 +00:00Commented Sep 2, 2021 at 7:45 -
1\$\begingroup\$ Ah, I misread the challenge regarding the second part. You're indeed correct that it has 1-4 layers, and empty layers should be removed, so your approach was correct. I think you can remove the
gfor another -1, though?Āwill be truthy for a non-empty string and falsey for"". \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2021年09月02日 07:59:42 +00:00Commented Sep 2, 2021 at 7:59 -
\$\begingroup\$ @KevinCruijssen Yes that works, thanks again \$\endgroup\$ovs– ovs2021年09月02日 08:22:21 +00:00Commented Sep 2, 2021 at 8:22
Jelly, (削除) 38 (削除ここまで) (削除) 35 (削除ここまで) 34 bytes
"SWCR"p"¬,ĖṆḷ8»Żṗ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"¬,ĖṆḷ8»Żṗ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)
"¬,ĖṆḷ8» - 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
-
\$\begingroup\$ @JonathanAllan Corrected \$\endgroup\$2021年08月25日 18:29:39 +00:00Commented Aug 25, 2021 at 18:29
-
1\$\begingroup\$ Good job golfing :) \$\endgroup\$Jonathan Allan– Jonathan Allan2021年08月25日 18:59:19 +00:00Commented Aug 25, 2021 at 18:59
-
\$\begingroup\$ @JonathanAllan I still think I can beat 05AB1E somehow :) \$\endgroup\$2021年08月25日 19:00:04 +00:00Commented Aug 25, 2021 at 19:00
-
1\$\begingroup\$ @JonathanAllan I couldn't beat 35 with any patches of a single link, so I've gone with your 35 byte one. Thanks for the golfs! \$\endgroup\$2021年08月25日 19:40:57 +00:00Commented Aug 25, 2021 at 19:40
-
1\$\begingroup\$ Aha, I saw the
4µand the length of"SWCR", and thought to myself, "it must be possible to make a save using that somehow!" 34 bytes :D ...EDIT: although now the4can go back in if we want TIO \$\endgroup\$Jonathan Allan– Jonathan Allan2021年08月25日 20:27:35 +00:00Commented Aug 25, 2021 at 20:27
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.
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:
Screenshot of the image produced by the aforementioned code.
-
\$\begingroup\$ Btw, you can probably replace getShape with
gor something. \$\endgroup\$emanresu A– emanresu A2021年08月25日 20:46:41 +00:00Commented Aug 25, 2021 at 20:46 -
1\$\begingroup\$ I like the
Random r=new();bit, haven't seen that before! \$\endgroup\$jdt– jdt2021年08月25日 22:25:13 +00:00Commented Aug 25, 2021 at 22:25
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.
aß4Æ"RWCS"ï`Õ1⁄2wbgp` p-2 ö4 qÃfÈr-Ãq':
-
\$\begingroup\$ How does this prevent generating empty layers? \$\endgroup\$ovs– ovs2021年08月25日 10:46:47 +00:00Commented Aug 25, 2021 at 10:46
-
1\$\begingroup\$ @ovs, the right function generates the layer, which could possibly be entirely empty, and it is then run through the left function which removes all
-s in it. If that produces an empty string then the process is repeated until a valid layer is generated. \$\endgroup\$Shaggy– Shaggy2021年08月25日 10:53:08 +00:00Commented Aug 25, 2021 at 10:53
Charcoal, 51 bytes
⪫EE⊕‽4⊕‽⊖X33¦4⭆E4÷ιX33λ⎇%λ33+§RWSCλ§urgbypcw÷λ4--¦:
Try it online! Link is to verbose version of code. Explanation:
‽4 Random integer 0-3
⊕ Incremented
E Map over implicit range
X33¦4 334
⊖ Decremented
‽ Random integer
⊕ Incremented
E Map over random integers
E4 Map over quadrants
÷ι Current random integer
÷ Integer divide by
33 Literal integer `33`
X Raised to power
λ Current quadrant
⭆ Map over values and join
λ Current value
% 33 Modulo literal `33`
⎇ If nonzero then
§RWSCλ Cyclically indexed colour
+ Concatenated with
§urgbypcw Shape cyclically indexed by
λ Current value
÷ Integer divide by
4 Literal integer `4`
-- Else literal string `--`
⪫ : Join with literal `:`
Implicitly print
Vyxal rR, 37 bytes
\:4c/oƛ«3⟩∑ḣ`«`SWRC`Ẋ‛--J3322‹c/oτ∑58ε-;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).
4c/oƛ ; # array of length (random 1-4) filled with...
3322‹c/o # 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
58ε- # Pad with `-` from the start
j # Join the whole thing by...
\: # Semicolons.
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)
-
\$\begingroup\$ Won't this always generate 4 layers instead of a random number? \$\endgroup\$Shaggy– Shaggy2021年08月25日 23:25:01 +00:00Commented Aug 25, 2021 at 23:25
-
\$\begingroup\$ @Shaggy it can generate empty layers (with a one in 5**4=625 probability, which is quite high) which are then deleted. What remains is anything between 0 and 4 layers. In the case of 0 layers (very rare) it calls itself again recursively to avoid ouputting nothing. \$\endgroup\$Level River St– Level River St2021年08月25日 23:29:42 +00:00Commented Aug 25, 2021 at 23:29
-
\$\begingroup\$ Ah. I'd read it as the replace & repeat being done for each layer, rather than the final image. Interesting approach; I wonder if I can save anything on my Japt solution by doing something similar? \$\endgroup\$Shaggy– Shaggy2021年08月26日 11:26:14 +00:00Commented Aug 26, 2021 at 11:26
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!
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]}
-
2\$\begingroup\$ How does this avoid the possibility of empty layers? \$\endgroup\$Shaggy– Shaggy2021年08月25日 15:46:05 +00:00Commented Aug 25, 2021 at 15:46
-
\$\begingroup\$ @Shaggy I fix it. \$\endgroup\$Denis Ibaev– Denis Ibaev2021年08月27日 09:07:58 +00:00Commented Aug 27, 2021 at 9:07
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;
}
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
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``
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
Shape
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----
MathGolf, 49 bytes
{╘4{4{"CRSW"w"bcgpruwy"w+v¶╛æ;û--}Γy}Γ'-8*a-}↔':u
The first output was: CwRuRrRw:RpSwSbRp:RcWpRpCu:CpWwWgWc:
enter image description here
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.
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)+':':''
-
\$\begingroup\$ Your comment made me go back to double check my solution and I realised I'd screwed up in how I was avoiding empty layers, preventing all possible outputs. \$\endgroup\$Shaggy– Shaggy2021年08月26日 15:48:19 +00:00Commented Aug 26, 2021 at 15:48
-
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)
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.
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
Explore related questions
See similar questions with these tags.
graphical-outputchallenge. \$\endgroup\$