C (gcc), 413 394 389 379 378 360 342 327 307 299 298 293 bytes
#define F;for(b[8]=b[v=24]=3,n=0;n
#define B,b[n]==
a[]=L"14444448888888822222",b[32],r[24],n,k,j,t=20,v;main(i){srand(&i)F<v;*b=b[16]=1)r[n++]=n/3-~n F<4;a[k]=a[t])b[i=4+n++*8]=a[k=rand()%t--]-48 F<16;r[j]=r[v])b[r[j=rand()%v--]]=a[n++]-48 F<32;n++)printf("%d%d%d%d%d\n"B 1 B 3 B 4 B 8 B 2);}
Try it online!
#define F;for(b[8]=b[v=24]=3,n=0;n
#define B,b[n]==
a[]=L"14444448888888822222",b[32],r[24],n,k,j,t=20,v;main(i){srand(time(0))F<v;*b=b[16]=1)r[n++]=n/3-~n F<4;a[k]=a[t])b[i=4+n++*8]=a[k=rand()%t--]-48 F<16;r[j]=r[v])b[r[j=rand()%v--]]=a[n++]-48 F<32;n++)printf("%d%d%d%d%d\n"B 1 B 3 B 4 B 8 B 2);}
try it online -earlier algorithm 307 bytes
Many thanks to @ceilingcat for more byte savings (360 to 342 - then 342 to 328 and 327 to 307 - then modified algorithm from 328 to 299 and 298 to 293).
Compiles ok without #include<stdio.h>
using the -w
compiler flag, thanks to @Arnaud for pointing this out.
As written it generates a fresh sequence each time. If we are allowed manual intervention of a new number in srand
to generate a different drum sequence with say srand(6);
then we can save 16 bytes.
Thanks to @Arnaud who made asked the question about generating the transpose matrix, which is what this program does. Thanks also for suggesting the change from int
to char
for a[20]
that saves 15 bytes. Also thanks for @Post Rock Garf Hunter who figured out a way to remove white space near the B
s and then saved more bytes fixing up the #defines so that F
is included in R
. `#define' tokens often seem to need whitespace so they are cleanly identified.
This code works on tio.run
, but elsewhere may need to include time.h
.
How the program works
logic:
- setup
- 4 sounds are fixed (at 1,9,17,25)
- remaining sounds to be distributed randomly are in
a[20]
b[32]
holds output - one cell for each beat (1 to 32, but in C of course 0 to 31)
- 4 of the
b
cells must have something (at 5,13,21,29)
- remaining sounds randomly scattered to empty cells
r[24]
holds list of empty cells (2,3,4, 6,7,8 etc. in C 0,1,2, 4,5,6 etc.)
- execute
- put in 4 fixed sounds
- choose random sound from
a
to put in each of 4 cells with sounds
- choose random cell from
r
to put in random sound from remaining a
sounds (simplification to algorithm is possible here by putting remaining sounds one by one from 1 to 16 (or 0 to 15) in a random cell, but this gave more bytes..., but now thanks to @ceilingcat this is now smaller see tio.run link for details)
- print result
this is a long version of the code without the #define
and other space savers to show the logic, but with small differences e.g. in final version a
is char *
not int *
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a[20]={1,4,4,4,4,4,4,8,8,8,8,8,8,8,8,2,2,2,2,2},
b[32]={},r[24],n,k,j,t=20,v=24;
time_t q;srand(time(&q));
//random initialization
for(n=0;n<24;n++n=0;n<v;n++)r[n]=n+n/3+1;
// set up r with list of cells that don't definitely have sound 012,456 etc.
b[0]=b[16]=1;b[8]=b[24]=16;
//put in fixed sounds
for (n=0;n<4;n++)
{k=rand()%t--;b[4+n*8]=a[k];a[k]=a[t];}
//choose a random sound from a to put in each of 4 cells that must have sound
// each sound selected is then replaced by the sound at the end of the list
// and the length of the list is reduced by one
for (n=0;n<16;n++)
{k=rand()%t--;j=rand()%v--;b[r[j]]=a[k];a[k]=a[t];r[j]=r[v];}
// random cell from remaining `r` cells and random sound are selected
// again after selection from list final item replaces selected and length
// reduced by one
for (n=0;n<32;n++)
{printf("%d%d%d%d%d\n",(b[n]==1),(b[n]==16),(b[n]==4),(b[n]==8),(b[n]==2));}
// print out 0 and 1 from logical tests to print transpose matrix
return 0;
}