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.