Illustrare ritmi musicali


24

Sai, sembrano così:

fonte

L'obiettivo è quello di disegnare un'illustrazione di battiti musicali come la seguente:

=     =      =
=  =  =      =          =
== = ==   =  ==     = ====
== ====  == ===   = = =======
======== == ====  = ========= =
=================================

Le regole sono:

  • La larghezza dell'illustrazione è di 33 simboli, ma se necessario, sono consentiti tutti gli spazi finali che superano questa larghezza.
  • Ogni colonna è composta da segni di uguale ( =).
  • Ogni colonna ha un'altezza casuale (l'altezza della colonna successiva non dovrebbe dipendere in alcun modo dall'altezza della colonna precedente), che varia da 1 a 6. Va anche bene se almeno è possibile ottenere un input senza rigore probabilità matematica (ovvero alcuni input potrebbero apparire più raramente di altri).
  • Una colonna non può galleggiare sopra il fondo e presentare degli spazi vuoti.
  • Poiché ogni colonna ha un'altezza minima di 1, anche l'ultima riga non può avere spazi vuoti: è sempre composta da 33 segni di uguale.
  • Dal momento che è possibile non avere colonne con l'altezza di 6 (dopotutto è tutto casuale): in questo caso non è necessario avere una riga superiore fatta di spazi. Si applica a tutti i casi limite di questa natura: se all'improvviso il codice non ha fornito colonne con altezza maggiore di 1, non è necessario disporre di linee aggiuntive fatte di spazi sopra la linea inferiore.
  • Non prendi nessun input .

@Lynn Oh, inizialmente lo ha specificato, ma l'ho rimosso per sbaglio dal post.
nicael,

11
(Nitpicking) Mi sembra uno spettrogramma in un dato istante, piuttosto che una rappresentazione di qualsiasi ritmo
Luis Mendo,

2
Le colonne possono essere separate da spazi? (vale a dire, la riga in basso sarebbe = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =)
LegionMammal978,

2
Va bene avere linee extra sopra l'output?
John Dvorak,

1
"L'altezza della colonna successiva non dovrebbe dipendere in alcun modo dall'altezza della colonna precedente" - vengono generati i generatori di numeri casuali incorporati nella maggior parte delle lingue. Per questo motivo una funzione come Math.random()è direttamente calcolabile dalla sua precedente chiamata se i parametri del generatore congruenziale lineare sono noti, il che significa che dovresti modificare la maggior parte delle funzionalità casuali incorporate per soddisfare questi criteri. Suggerisco che sia meglio formulato.
Patrick Roberts,

Risposte:



13

Dyalog APL , 14 byte

⊖⍉↑'='⍴¨⍨?33⍴6

Spiegazione

33⍴6 33 ripetizioni di 6

?numero intero casuale nell'intervallo [1, n ] per ciascuno dei 33 6 s

'='⍴¨⍨ simbolo di uguaglianza ripetuto ognuna di quelle volte

converti l'elenco di elenchi in una tabella di righe

trasporre righe in colonne, colonne in righe

capovolgere

L'esempio funziona

L'ingresso è rientrato di sei spazi:

      ⊖⍉↑'='⍴¨⍨?33⍴6
=          ==        =      ==   
= =    =   ==      ====     ==   
= = = ===  ==  === ==== =  ===  =
= = ===== ==== === ==== = ====  =
=== ============== ==== ====== ==
=================================
      ⊖⍉↑'='⍴¨⍨?33⍴6
         =  =  =    =    =       
  =      =  =  ==  == == =  =    
 === == ==  =  === =======  =    
==== == ==  ====== ==========   =
==== ============= ========== = =
=================================
      ⊖⍉↑'='⍴¨⍨?33⍴6
             =    =   =  =       
         =   =    =   = == =     
=      = =   =    ==  = ==== === 
= = =  = =   =    ==  = ==== ====
=====  = == ==  ============ ====
=================================

9

Gelatina, 14 byte

6x33X€”=ẋz⁶Ṛj⁷

Provalo qui.


11
Uh oh, non può essere giusto. La gelatina per definizione deve essere più corta dell'APL.
Adám,

Non è molto efficiente, ma 6ṗ33Xfunziona anche.
Dennis,

9

JavaScript (ES6), 116 byte

(a=Array(33).fill``.map(_=>[,,,,,,].fill` `.fill('=',Math.random()*6)))[0].map((x,i)=>a.map(x=>x[i]).join``).join`
`

Anteprima dello snippet

Dai un'occhiata nel frammento animato qui sotto:

F = () => (a=Array(33).fill``.map(_=>[,,,,,,].fill` `.fill('=',Math.random()*6)))[0].map((x,i)=>a.map(x=>x[i]).join``).join`
`

var interval;
G = () => output.innerHTML = F().split('\n').map((r, i) => `<span id="row-${6-i}">${r}</span>`).join('\n');
A = () => {
  clearInterval(interval);
  if (auto.checked) {
    speed.disabled = false;
    interval = setInterval(G, speed.value);
  } else {
    speed.disabled = true;
  }
}
S = () => {
  if (stylized.checked) {
    output.classList.add('stylized');
  } else {
    output.classList.remove('stylized');
  }
}

generate.onclick = G;
auto.onchange = speed.onchange = A;
stylized.onchange = S;

G();
A();
S();
#output {
  background: #000;
  color: #9fff8a;
  overflow: hidden;
  padding: 1em;
  line-height: 1;
}

#output.stylized {
  line-height: 0.25;
  font-size: 2em;
  margin: 0.5em 0 0 0;
  padding: 0.5em;
}

.stylized #row-1 { color: #9fff8a; }
.stylized #row-2 { color: #c5ff8a; }
.stylized #row-3 { color: #e0ff8a; }
.stylized #row-4 { color: #ffe88a; }
.stylized #row-5 { color: #ffc28a; }
.stylized #row-6 { color: #ff8a8a; }
<button id="generate">Generate</button>
<label>Auto: <input id="auto" type="checkbox" checked/></label>
<label>Speed: <select id="speed">
  <option value="25">25</option>
  <option value="50">50</option>
  <option value="100" selected>100</option>
  <option value="200">200</option>
  <option value="400">400</option>
  <option value="600">600</option>
  <option value="800">800</option>
  <option value="1000">1000</option>
</select></label>
<label>Stylized: <input id="stylized" type="checkbox" checked/></label>
<pre id="output"></pre>


1
Wow, è davvero fantastico!
nicael,

8

C, 87 byte

f(x,y){for(y=6;y--;){srand(time(0));for(x=33;x--;)putchar("= "[rand()%6<y]);puts("");}}

Chiama come f();. Questa risposta si basa sul fatto che sei chiamate consecutive time(0)restituiscono lo stesso risultato (in secondi). Questo è praticamente sempre vero, ma probabilmente vale la pena menzionarlo.


Metti xe yper evitare di dichiararli come int. Poiché non vi è alcun input, è consentito? Se sì, è una bella idea!
aloisdg dice Reinstate Monica l'

2
Ho appena provato il tuo codice. Puoi eseguirlo con quello è f();bello! Non sapevo che C potesse farlo.
aloisdg dice Reinstate Monica l'

Mi piace davvero il tuo codice. Lo porto su C # per un risultato di 117 byte. Non sono sicuro di pubblicarlo perché è letteralmente il tuo codice.
aloisdg dice Reinstate Monica l'

1
Sentiti libero di pubblicarlo, a condizione che mi accrediti. :)
Lynn,

8

Cheddar, 68 65 byte (non concorrenti)

->(1:33).map(->IO.sprintf("%6s","="*Math.rand(1,7))).turn().vfuse

O_O Cheddar sta davvero andando bene! Usa sprintfe turnper fare gran parte del lavoro. vfuseè un fusibile verticale che significa che unisce l'array ma verticalmente. Questo è molto golfy ma anche piuttosto veloce. La versione è pre-release v 1.0.0-beta.10 , che post-date la sfida.

Spiegazione

->           // Anonymous function
  (1:33)     // Range 1-33 inclusive
  .map(->    // Loop through the above range
    IO.sprintf("%6s",       // `sprintf` from C/C++
      "="*Math.rand(1,7)    // Repeat `=` a random time from [1,7)
    )
  ).turn().vfuse     // Turn it 90deg, and fuse it vertically

Alcuni esempi di esecuzione:

inserisci qui la descrizione dell'immagine


5

05AB1E , 22 byte

Nessun auto join, nessun riempimento automatico durante la trasposizione, osabie è condannato a questo. Codice:

33F6ð×6L.R'=×ðñ})ø€J¶ý

Utilizza la codifica CP-1252 . Provalo online! .


5

Python 2, 95 byte

from random import*
x=map(randrange,[6]*33)
for y in range(6):print''.join('= '[z>y]for z in x)

4

Python 3, 115 byte

Python non ha mai avuto nemmeno una possibilità ...

from random import*
for k in zip(*[[' ']*(6-len(j))+j for j in[randint(1,6)*['=']for i in[0]*33]]):print(*k,sep='')

Come funziona

from random import*    Import everything in the random module
randint(1,6)*['=']     Create a list containing a random number in [1,6] of '='...
...for i in[0]*33      ...33 times...
[...]                  ...and store in a list X
for j in...            For all lists j in X...
[' ']*(6-len(j))+j     ...create a list containing j padded with the correct number of
                       spaces to give a height of 6...
[...]                  ...and store in a list Y

Y now contains a list for each output line, but transposed.

for k in zip(*...):...  For all lists k in the transpose of Y...
print(*k,sep='')        Print all elements in k with no separating space

Provalo su Ideone



3

SpecaBAS - 76 byte

1 FOR x=1 TO 33: r=1+INT(RND*6): FOR y=7-r TO 6: ?AT y,x;"=": NEXT y: NEXT x

Stampa un segno di uguale nella coordinata dello schermo pertinente.

enter image description here

con una macchia di colore e un GOTOanello diventa

enter image description here


2

K4, 18 byte

Essenzialmente una porta della soluzione APL (non sorprende).

+-6$(33?1+!6)#'"="

2

C #, 200 117 byte

()=>{var s="";int x,y=6;for(;y-->0;){var r=new Random();for(x=33;x-->0;)s+="= "[r.Next(6)<y?1:0];s+='\n';}return s;};

Passo all'algoritmo @Lynn e salvo 83 byte!

C # lambda senza input e dove output è una stringa. Provalo online .

Codice:

()=>{
    var s="";int x,y=6;
    for(;y-->0;){
        var r=new Random();
        for(x=33;x-->0;)
            s+="= "[r.Next(6)<y?1:0];
        s+='\n';
    }return s;
};

2

Haskell, 164 byte

Essendo un linguaggio puramente funzionale, Haskell è stato condannato fin dall'inizio. L'ho fatto comunque e si scopre che il sovraccarico necessario in realtà non è così grande.

import System.Random
import Data.List
f r n|r>n=' '|0<1='='
s=do
g<-newStdGen
mapM_ putStrLn$transpose$map(\n->map(f$mod n 6)[0..5])(take 33(randoms g)::[Int])

Uso:

s

Spiegazione:

import System.Random

per poter usare newStdGenerandoms

import Data.List

per poter usare transpose

f r n|r>n=' '|0<1='='

definisce una funzione che stampa uno spazio se il suo primo argomento è più grande del secondo e un =altro. Viene chiamato con map (f m) [0..5]un determinato numerom e l'elenco [0,1,2,3,4,5]. (Vedi sotto)

s=do
g<-newStdGen

Crea un nuovo generatore di numeri casuali standard

(take 33(randoms g)::[Int])

accetta 33 numeri interi casuali.

map(\n->map(f$mod n 6)[0..5])

Calcola m = n % 6e mappa (f m)l'elenco [0,1,2,3,4,5], che risulta in uno dei"======", " =====", ..., " =" . Queste linee sono mappate all'elenco dei 33 numeri interi casuali risultanti in una tabella. (Una tabella in Haskell è un elenco di elenchi)

transpose$

cambia le colonne e le righe della tabella

mapM_ putStrLn$

stampa ogni riga della tabella


1

CJam, 19 byte

{5mrS*6'=e]}33*]zN*

Provalo online!

Spiegazione

{       e# 33 times...
  5mr   e#   Push a random number in [0 1 2 3 4 5].
  S*    e#   Create a string with that many spaces.
  6'=e] e#   Pad to length 6 with =.
}33*    
]       e# Wrap all 33 strings in a list.
z       e# Transpose that list.
N*      e# Join the lines with linefeeds.

1

Mathematica, 78 byte

StringRiffle[(PadLeft[Array["="&,#+1],6," "]&/@5~RandomInteger~33),"
",""]&

Funzione anonima. Non accetta input e restituisce una stringa come output. Il carattere Unicode è U + F3C7, che rappresenta \[Transpose].


1

R, 102 byte

m=rep(" ",33);for(i in 1:6){n=ifelse(m=="=",m,sample(c(" ","="),33,T,c(6-i,i)));m=n;cat(n,"\n",sep="")}

Spiegazione

m=rep(" ",33) init un vettore vuoto per il ciclo imminente

n=ifelse(m=="=",m,sample(c(" ","="),33,T,c(6-i,i)))Se c'è un =nella riga sopra, assicurati che anche il punto sotto abbia un =; altrimenti scegli casualmente. Le scelte casuali sono ponderate per assicurarsi che a) la riga inferiore sia tutta =eb) si ottenga una forma ordinata per l'intera cosa.

cat(n,"\n",sep="") invia quella riga alla console con una nuova riga alla fine e senza spazi tra gli elementi!


1

PHP, 95 92 89 byte

<?php for(;++$i<34;)for($j=6,$e=' ';$j--;)$a[$j].=$e=rand(0,$j)?$e:'=';echo join("
",$a);

Abbastanza felice con questo in realtà. Per un po 'ho avuto una versione che in teoria poteva generare qualsiasi input ma in pratica avrebbe generato solo blocchi solidi di = ma questo è sia più breve che equamente distribuito!
Genera 7 avvisi di qualcosa di indefinito ogni volta che lo esegui, ma va bene.

modifica: bene ho appena imparato che join è un alias di implode, quindi è carino.


1

J, 18 byte

|.|:'='#~"0>:?33#6

Roba molto semplice. Con un bugfix da miglia!


Questo seleziona numeri interi casuali nell'intervallo [0, 6] mentre l'OP voleva [1, 6]. Potresti fare >:?33#6per ottenere numeri casuali nell'intervallo [1, 6]. Inoltre, una copia di grado 0 sarebbe più breve usando '='#~"0. Ciò comporta, |.|:'='#~"0>:?33#6ma sfortunatamente, il risparmio di 2 byte finisce per essere mitigato dall'inclusione dell'operatore di incremento.
miglia,

@miles Whoa, grazie! Molto bello.
Conor O'Brien,

1

Perl, 64 byte

@f=$_="="x33;s/=/rand>.4?$&:$"/ge,@f=($_.$/,@f)while@f<6;print@f

uso

perl -e '@f=$_="="x33;s/=/rand>.3?$&:$"/ge,@f=($_.$/,@f)while@f<6;print@f'
  = =           =  ==      =    =
  = =         ===  ==      =    =
= = =         ===  ==      =    =
= = =   = =   ===  ===   = =    =
= = == =====  === ====   ===  = =
=================================

Perl, 68 byte

Versione alternativa che si basa sui codici di escape ANSI per spostare il cursore in giro, prima scendendo di 6 righe, quindi scrivendo la riga originale (tutte le = s), spostandosi su una riga e stampando s/=/rand>.4?$&:$"/geripetutamente la stringa sostituita ( ) fino a quando non effettua più sostituzioni. Questo può finire per scrivere più di sei righe, ma alla fine viene sostituito con una riga vuota.

Nota: \x1bs sono in realtà il Esccarattere ASCII .

print"\x1bc\x1b[6B",$_="="x33;print"\x1b[1A\x1b[33D$_"while s/=/rand>.4?$&:$"/ge

1

Rubino, 102 99 84 83 byte

s='
'*203;33.times{|j|a=(' '*rand(6)).ljust 6,'=';6.times{|i|s[i*34+j]=a[i]}};$><<s

Approccio nuovo e significativamente più breve, dove inizio con una stringa piena di nuove righe.

Versione precedente ...

s='';204.times do|i|s+=->i{i%34==0?"\n":i>170?'=':s[i-34]=='='?'=':rand(2)==1?'=':' '}[i]end;puts s

... ha dato un output con la nuova linea principale. La mia prima presentazione in Ruby, usando un approccio simile a quello di @ Barbarossa, ma in loop singolo.

Cosa mi è piaciuto in Ruby mentre lavoravo a questo programma:

  • .times ciclo continuo
  • rand() che è piuttosto breve
  • accatastamento di operatori ternari senza parentesi

Non mi è piaciuto (principalmente in termini di golf):

  • obbligatorio $ per le variabili globalinon così obbligatorio in .timesloop
  • do e end parole chiave che può essere sostituito con un blocco a linea singola
  • 0 non è falsa

0

JavaScript, 179 byte

Sto ancora lavorando un po 'sul golf. Mi piace dal momento che è semplice.

n=>{a=Array(33).fill(0).map(n=>Math.floor(Math.random()*6)+1);r=Array(6).fill("");r.map((e,m)=>{a.map(n=>{if (n<=m+1){r[m]+="="}else r[m]+=" "})});return r.join('\n');}

Uso:

>q=n=>{a=Array(33).fill(0).map(n=>{return Math.floor(Math.random() * 6)+1});
r=Array(6).fill("");r.map((e,m)=>{a.map(n=>{if (n<=m+1){r[m]+="="}else r[m]+=" "})});return r.join('\n');}
>q();
           = =  =   =    = =     
=   =    = = =  =  == =  = =  =  
= = =  = === ====  ====  = = === 
= = =  = === ==========  ======= 
= === ===========================
=================================

Dovresti essere in grado di sostituire .map(n=>{return Math.floor(Math.random() * 6)+1})con .map(n=>Math.floor(Math.random()*6)+1). Lambda sono grandi :)
aloisdg dice Reinstate Monica l'

if (n<=m+1){r[m]+="="}elsepotrebbe essereif(n<=m+1)r[m]+="=" else
aloisdg dice Reinstate Monica l'

Ho dovuto creare il mio PRNG e il mio programma Forth non è molto più lungo. : P
mbomb007,

0

Avanti, 190 byte

Ho dovuto creare il mio PRNG , uno spostamento di xor preso da qui . La parola fè la parola che chiamereste più volte per vedere l'output.

variable S utime S !
: L lshift xor ;
: R S @ dup 13 L dup 17 rshift xor dup 5 L dup S ! 6 mod ;
: f
33 0 DO R LOOP
1 -5 DO
33 0 DO
I PICK J + 0< 1+ IF ." =" ELSE SPACE THEN
LOOP CR
LOOP
; f

Provalo online : tieni presente che l'ora di sistema è uno dei due valori in base al server (o qualcosa) che esegue il codice. A parte questo, per qualche motivo non cambiano nell'IDE online. Quindi vedrai solo due possibili uscite. Puoi impostare manualmente il seme cambiandoutime in un numero intero.

Ungolfed

variable seed                   \ seed with time
utime seed !

: RNG                           \ xor-shift PRNG
seed @
dup 13 lshift xor
dup 17 rshift xor
dup 5 lshift xor
dup seed !
6 mod                           \ between 0 and 6, exclusive
;

: f 33 0 DO RNG LOOP            \ push 33 randoms
    1 -5 DO                     \ for (J = -6; J <  0; J++)
        33 0 DO                 \ for (I =  0; I < 33; I++)
            I PICK J + 0< 1+ IF \ if  (stack[I] < J)
                61 EMIT         \ print "="
            ELSE
                32 EMIT         \ print " "
            THEN
        LOOP
        CR                      \ print "\n"
    LOOP
; f

Ungolfed online


0

JavaScript, 165 byte

// function that fills a column with a specified number of = signs
m=l=>Array(6).fill``.map((e,i)=>i<l?"=":" ");
// fill an array of 33 length with columns of random number of = signs
a=Array(33).fill``.map(e=>m(Math.ceil(Math.random()*6)));
// transponse the rows and columns and print to console
a[0].map((c,i)=>a.map(r=>r[5-i])).map(r=>console.log(r.join``))

Le newline non sono necessarie ma rendono più semplice vedere cosa sta succedendo. Non è la soluzione più ottimale, ma almeno per me ha senso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.