Aiutami a suonare la tromba


14

La tromba è uno strumento aerophone valvolato, di solito lanciato B♭. Il suono viene emesso quando il giocatore fa vibrare le labbra per spostare l'aria all'interno dello strumento. Quella vibrazione viene acquisita impostando la bocca in un modo specifico, chiamato embouchure. Imboccature diverse, con labbra più strette o più larghe, producono tonalità diverse.

Inoltre, ogni valvola nella tromba cambia anche il tono dello strumento. Quando viene premuto, una valvola chiude un percorso all'interno del tubo dello strumento, facendo fluire l'aria attraverso un percorso più lungo, riducendo così il tono del suono originale. Ai fini di questa sfida, considereremo la B♭tromba standard, in cui la prima valvola abbassa l'intonazione di un passo completo, la seconda abbassa l'intonazione di un mezzo passo e la terza abbassa l'intonazione di uno e un mezzo passo.

La sfida

La tua sfida è quella di creare un programma o una funzione che, dati due input embouchuree valves, determini l'intonazione della nota suonata.

Ai fini di questa sfida, le note seguiranno la sequenza:

B♭, B, C, C♯, D, E♭, E, F, F♯, G, G♯, A.

Regole

  • L'I / O può essere preso / dato in qualsiasi metodo ragionevole .
  • Si applicano scappatoie standard .
  • Puoi usare be #invece di e se lo desideri.
  • L'ingresso per valvespuò essere preso come un elenco di valvole depresse ( 1, 3) o un elenco booleano ( 1, 0, 1).
  • Questo è , quindi vince il codice più corto in ogni lingua.

Casi test:

Valves in questi casi di test viene fornito un elenco booleano, dove 0 significa depresso e 1 significa premuto.

Embouchure:    Valves:   Output:
B♭             0 0 0     B♭
B♭             0 1 0     A
B♭             1 0 1     F
C♯             0 0 1     B♭
C♯             1 1 1     G
E♭             1 0 0     C♯
G              0 1 1     E♭
G♯             1 0 0     F♯
G♯             0 0 1     F
G              1 0 0     F
F♯             1 0 0     E
D              1 0 1     A
A              1 1 1     E♭
E              1 1 0     C♯
E              0 0 1     C♯

Dichiarazione di non responsabilità: non sono ancora un musicista, quindi mi scuso per il macello che avrei potuto fare sui casi di test. Le correzioni sono apprezzate.


2
Percussionista qui. Aspetta, ecco come si scrive l'imboccatura.
Ho

1
@vasilescur hai ragione. Risolverò quelli e rivedere eventuali altri errori possibili. Grazie per il testa a testa.
J. Sallé,

1
Come qualcuno che suona la tromba da molto tempo, sono davvero confuso dalla misurazione di Embouchure ... Ad esempio cos'è un Embouchure in C #?
Bendl

1
Dovrebbe F# 100essere E non F?
Level River St

2
@bendl Non esiste una cosa del genere. Non puoi suonare una C#tromba senza premere nessuna valvola. Solo note specifiche ( B♭-F-B♭-D-F-A♭-B♭...), la serie di sovratoni di B♭. Tuttavia, anche se non riflette uno strumento reale, la sfida è perfettamente ben definita.
Chris

Risposte:


4

Pitone 3 2, 125 119 81 byte

lambda e,f,s,t,n=2*'A G# G F# F E Eb D C# C B Bb'.split():n[n.index(e)+2*f+s+3*t]

Provalo online!

Salvataggio di molti byte grazie a Jonathan Allan.


La mia soluzione originale (in Python 3 ):

n=2*'Bb B C C# D Eb E F F# G G# A'.split()
e,f,s,t=str(input()).split()
print(n[n.index(e,9)-2*int(f)-int(s)-3*int(t)])

Provalo online!

6 byte salvati grazie a @HyperNeutrino.


Spiegazione

Per prima cosa, faccio una serie di note, ma raddoppiano in lunghezza, quindi non devo preoccuparmi di fare un giro da Bba A.

Quindi, prendo l'input nel seguente formato (ad esempio):

Bb 1 0 1

Trovo quindi l'indice della nota di partenza usando n.index(e,9)( 9c'è per assicurarmi di iniziare bene nel mezzo dell'elenco (raddoppiato). Calcolo l'offset desiderato con l'espressione:

2*int(f) - int(s) - 3*int(t)

Dov'è fla prima valvola, sè la seconda valvola ed tè la terza.

Infine, stampa semplicemente la nota trovata nell'elenco sottraendo l'offset dall'indice iniziale.


3
salva qualche byte separando per spazi. "<some string>".split()si divide per spazio bianco per impostazione predefinita
HyperNeutrino

Salva 30 byte spostandoti su Python 2 (evitando stre intlanciando e consentendo l'input valutato) e invertendo le note e spostandoti in avanti (evitando ,9la indexchiamata. Provalo online!
Jonathan Allan

... e altri 8 passano alla funzione (che funziona in Python 2 o 3) Provalo online!
Jonathan Allan,

@JonathanAllan Ho imparato diversi trucchi da golf Python dai tuoi miglioramenti. Grazie mille!
vasilescur

... infatti puoi usare la lista nel suo ordine originale senza ripetizioni e sottrarre valori poiché l'indice negativo non va mai oltre i limiti (il più negativo ti porterebbe 'Bb', 1, 1, 1ad indicizzare -6quale sarebbe E, come richiesto) - è ciò che TFeld ha da allora fatto .
Jonathan Allan,

3

Wolfram Language (Mathematica) , 100 byte (e 134 per una tromba funzionante)

l="Bb,B,C,C#,D,Eb,E,F,F#,G,G#,A"~StringSplit~",";f=l[[Mod[#&@@#&@@l~Position~#-2#2-#3-3#4-1,12]+1]]&

Provalo online!

Abbastanza semplice.

l="Bb,B,C,C#,D,Eb,E,F,F#,G,G#,A"~StringSplit~",";f=EmitSound@SoundNote[l[[Mod[#&@@#&@@l~Position~#-2#2-#3-3#4-1,12]+1]],1,"Trumpet"]&

Un output migliore per il costo di 34 byte.


Aspetta ... Mathematica ha l'uscita audio ??? Wicked!
Tito

Naturalmente Mathematica ha un built-in per l'uscita audio. Questo è oro
J. Sallé,

2

Gelatina ,  37  36 byte

ØAḣ7;⁾#b“®JXrẊỤȥ’ṃnŒl$œṗ$Ḋ©i_⁸æ.J¤ị®

Un collegamento diadico che accetta le valvole come un elenco di 1s 0come un elenco che rappresenta [second, first, third]a sinistra e l'imboccatura come un elenco di caratteri a destra che restituisce un elenco di caratteri.

Provalo online!

Come?

ØAḣ7;⁾#b“®JXrẊỤȥ’ṃnŒl$œṗ$Ḋ©i_⁸æ.J¤ị® - Link: list of integers, V; list of characters, E
ØA                                   - yield uppercase alphabet
  ḣ7                                 - head to index 7 = "ABCDEFG"
     ⁾#b                             - literal list of characters = "#b"
    ;                                - concatenate = "ABCDEFG#b"
        “®JXrẊỤȥ’                    - literal integer = 2270857278734171
                 ṃ                   - base decompress (i.e. convert to base 9 using the 'digits' "bABCDEFG#")
                                     -                 = "ABbBCC#DEbEFF#GG#"
                        $            - last two links as a monad:
                     $               -   last two links as a monad:
                   Œl                -     to lower case = "abbbcc#debeff#gg#"
                  n                  -     not equal? (vectorises) = [1,1,0,1,1,1,0,1,1,0,1,1,1,0,1,1,0]
                      œṗ             -   partition at truthy indices = [[],"A","Bb","B","C","C#","D","Eb","E","F","F#","G","G#"]
                         Ḋ           - dequeue = ["A","Bb","B","C","C#","D","Eb","E","F","F#","G","G#"]
                          ©          - copy to register and yield
                           i         - first index of E in there
                                 ¤   - nilad followed by links as a nilad:
                             ⁸       -   chain's left argument, V
                                J    -   range of length [1,2,3]
                              æ.     -   dot product (i.e. 1*second + 2*first + 3*third)
                            _        - subtract
                                   ® - recall from register
                                  ị  - index into (1-based and modular)


1

Javascript 96 byte

Seguendo l'idea di @vasilescur, questa è l'implementazione in js

(a,b,c,d,_="B♭,B,C,C♯,D,E♭,E,F,F♯,G,G♯,A".split`,`)=>(l=_.concat(_))[l.indexOf(a,9)-(2*b+c+3*d)]

a=(a,b,c,d,_="B♭,B,C,C♯,D,E♭,E,F,F♯,G,G♯,A".split`,`)=>(l=_.concat(_))[l.indexOf(a,9)-(2*b+c+3*d)]
console.log(a('B♭',0,0,0))
console.log(a('B♭',0,1,0))
console.log(a('B♭',1,0,1))
console.log(a('C♯',0,0,1))
console.log(a('C♯',1,1,1))
console.log(a('E♭',1,0,0))
console.log(a('G',0,1,1))
console.log(a('G♯',1,0,0))
console.log(a('G♯',0,0,1))
console.log(a('G',1,0,0))
console.log(a('F♯',1,0,0))
console.log(a('D',1,0,1))
console.log(a('A',1,1,1))
console.log(a('E',1,1,0))
console.log(a('E',0,0,1))


3 byte in meno;) A proposito, gli appartamenti e gli oggetti taglienti devono essere contati come 3 byte, vero?
Shieru Asakoto,

Oh nvm (non l'ho visto be mi #è permesso) ma devi usare be #invece di flat e sharp.
Shieru Asakoto,

1

Lotto, 188 byte

@set n=%1
@set/aC=0,D=2,Eb=3,E=4,F=5,G=7,A=9,Bb=10,B=11,n=(%n:#=+1%+12-%2*2-%3-%4*3)%%12
@for %%n in (C.0 C#.1 D.2 Eb.3 E.4 F.5 F#.6 G.7 G#.8 A.9 Bb.10 B.11)do @if %%~xn==.%n% echo %%~nn

Usi #e b: questo significa che Ebe Bbsono nomi di variabili legali; #viene gestito eseguendo una sostituzione di stringa in +1. Il risultato della sostituzione della stringa viene quindi valutato automaticamente e le valvole vengono quindi prese in considerazione prima che il risultato venga cercato in un elenco.


1

Stax , 32 byte

τ┤=Yº○!AÄΔâß₧←╥╟ö'ÄD├æñßf╧å▬tó÷╖

Eseguilo ed esegui il debug online

Prende un nome di nota e un elenco di valvole depresse. Costruisce una matrice di nomi di note, quindi calcola l'intervallo totale della valvola e ottiene la nota a tale offset nell'array.

"AbABbBCC#DEbEFF#G" just a literal
{VA#}(Y             partition at capital letters and store in y
,]I                 get the index of the input note
,2R:t               swap 1s and 2s in valve list
{-F                 subtract valve list from note index
y@                  look up result from note array

Esegui questo




0

73 caratteri Perl6 / Rakudo

Tecnicamente questo è 83 byte perché ho inserito i caratteri Unicode, ma scambiandoli con gli equivalenti ASCII darei 73 byte.

Come {code block}con parametri come $^aquesto è un lambda, con una firma ($a, $b, $c, $d).

{$_=2*$^b+$^c+3*$^d;'AG♯GF♯FEE♭DC♯CBB♭'x 2~~/$^a(\w\W?)**{$_}/~~/\w\W?$/}

Chiamalo:

say { ... }("D", 1, 0, 1)
>> A

Meno-giocato a golf:

sub f($a, $b, $c, $d) {
   my $totalShift = 2*$b + $c + 3*$d;
   my $doubledScale = 'AG♯GF♯FEE♭DC♯CBB♭' x 2;
   my $matchEmbOnward = $doubledScale ~~ / $^a (\w\W?)**{$totalShift} /;
   my $matchFinalNote = $marchEmbOnward ~~ / \w \W? $ /;
   return $matchFinalNote;
}

Qui raddoppiamo una stringa '...' x 2usando l' xoperatore infix, quindi cerchiamo l'imboccatura seguita da n note usando l'operatore smartmatch '...' ~~ /.../: le cerniere regex su \w\W?cui è un carattere di parola quindi forse un carattere di non parola.

Cerchiamo n istanze di questo tramite (\w\W?)**{$_}, dove abbiamo già calcolato n = $_da params $ba $d. Questo produce una corrispondenza dalla nota di imboccatura alla nota risultante, di cui vogliamo solo l'ultima, quindi abbiniamo quella con un'altra ~~ /\w\W?$/.

Il calcolo del $_primo è necessario per consentire la $^bcreazione implicita di parametri sul blocco.

76 caratteri

Un'alternativa che utilizza un array anziché le corrispondenze di stringhe è 3 caratteri in più:

{$_=<B♭ B C C♯ D E♭ E F F♯ G G♯ A>;.[((.first: $^a,:k)-2*$^b-$^c-3*$^d)%12]}

La ricerca dell'imboccatura nell'elenco viene ottenuta con @arr.first: $^a, :k, che restituisce l'indice (chiave) dell'elemento trovato con :k.

L'impostazione dell'array su $_(come oggetto) ci consente di usarlo .firste utilizzarlo .[ ]senza spendere troppi caratteri.


0

C (gcc) , 155 byte

char r[][12]={"bb","b","c","c#","d","eb","e","f","f#","g","g#","a"};u;v(z,y,x,w)char*z;{for(;u<12;u++)if(!strcmp(z,r[u]))break;u=u-2*y-x-3*w;u=u<0?12+u:u;}

Provalo online!

Approccio semplice.

L'ingresso della valvola è 0,1.

L'immissione dell'imboccatura deve essere minuscola. È interessante notare che TiO non sta trovandostrcmpi() senza includere string.h, mentre mingw-gcc lo consente con l' -Wimplicit-function-declarationavvertimento standard .

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.