Konvertieren Sie zwischen Musiknotenschlüsseln

12

Bevor Sie gehen, müssen Sie nicht viel musikalische Notation verstehen, um diese Herausforderung zu tun.

ERLÄUTERUNG

In Standardnoten gehen Doppelschlüssel über die Seite, die als Referenzpunkte zu den Noten dienen, damit Sie wissen, welche Note gespielt werden soll. Wenn Sie mit dem Violinschlüssel und dem Bassschlüssel noch nicht vertraut sind, finden Sie hier eine Beschreibung aus Wikipedia:

Ein Notenschlüssel ist ein musikalisches Symbol, das die Tonhöhe geschriebener Noten angibt. Auf einer der Zeilen am Anfang der Daube platziert, zeigt es den Namen und die Tonhöhe der Noten in dieser Zeile an. Diese Linie dient als Bezugspunkt, an dem die Namen der Noten in einer anderen Linie oder einem anderen Raum der Daube festgelegt werden können.

Noten

In der obigen Abbildung ist die obere Hälfte der Linien der Violinschlüssel, der mit a bezeichnet ist Violinschlüssel

Die untere Hälfte ist der mit a bezeichnete Bassschlüssel Bass-Schlüssel

Wie man auf dem Violinschlüssel eine Note auf der am weitesten unten liegenden Linie ein sieht E . Auf dem Bassschlüssel (Ich bin nicht Noten außerhalb der Schlüssel Linien für diese Herausforderung zu zählen), ist die unterste Zeile ein G . Um diese Herausforderung abzuschließen, müssen Sie folgende Schritte ausführen:

HERAUSFORDERUNG

Konvertieren Sie eine Eingabe in einer der folgenden Formen (Ihrer Wahl) in den entgegengesetzten Schlüssel. Ob es sich um den Violinschlüssel oder den Bassschlüssel handelt, kann ein Truthey / Falsey-Wert in Ihrer Sprache sein (nicht nur zwei beliebige Werte), z

F # T oder F # True oder F # Treble

aber nicht

F # -1 oder F # 4

Leerzeichen und Großschreibung sind optional, Wohnungen werden nicht angezeigt und nachfolgende Leerzeichen sind nicht zulässig.

Input          Expected Output
E   Treble     G
F   Treble     A
F#  Treble     A#
G   Treble     B
G#  Treble     C
A   Treble     C
A#  Treble     C#
B   Treble     D
C   Treble     E
C#  Treble     F
D   Treble     F
D#  Treble     F#
E   Treble     G
F   Treble     A
F#  Treble     A#
G   Bass       E
G#  Bass       F
A   Bass       F
A#  Bass       F#
B   Bass       G
C   Bass       A
C#  Bass       A#
D   Bass       B
D#  Bass       C
E   Bass       C
F   Bass       D
F#  Bass       D#
G   Bass       E
G#  Bass       F
A   Bass       F
A#  Bass       F#

Seien Sie gewarnt, dies ist keine triviale Herausforderung für konstante Unterschiede. Schauen Sie sich die Ein- und Ausgänge genau an. Wenn Sie ein Klavier anschauen,

Klavier

Die schwarzen Tasten sind scharfe Stellen, die mit # gekennzeichnet sind. Beachten Sie, dass es kein E # oder B # gibt. Dies bedeutet, dass Sie, wenn Sie G # für den Bassschlüssel erhalten, anstatt E # zurückzugeben, F zurückgeben müssen

Dies ist , also gewinnt die kleinste Anzahl von Bytes.

FantaC
quelle
1
Müssen wir uns um Wohnungen sorgen? Wie wäre es mit Doppelebenen / Sharps?
mypetlion
1
Bitte erstellen Sie keine Tags für Themen, die diese nicht rechtfertigen.
Jonathan Allan
3
Ist abschließendes Leerzeichen (Rückkehr C statt C) in Ordnung?
Lynn
2
Ist die Verwendung von 1und -1(oder sogar sagen 4und -4) für die Eingabe des Notenschlüssel-Indikators zulässig oder wäre dies nur akzeptabel, wenn es sich um wahrheitsgemäße / falsche Werte in unserer Sprache handelt?
Jonathan Allan
1
Dies ist eine nette und gut präsentierte Herausforderung, aber es wäre IMO mit etwas entspannten Eingabe- / Ausgabeformaten noch besser gewesen.
Arnauld

Antworten:

5

Jelly ,  35  34 Bytes

Ich habe das Gefühl, dass eine gewisse Arithmetik diese Methode für sich gewinnen könnte.

ØAḣ7µW€ż;€”#$Ẏ
Ç”C4¦”F⁵¦
Ñi+_⁸?4ị¢

Probieren Sie es online!

Ein vollständiges Programm, das 1 ) die Notenschlüsselanzeige 0oder 1für Bässe bzw. Höhen und 2) die Note nimmt; und Drucken der resultierenden Notiz.

Wäre 31 Bytes, wenn -4und wäre 4akzeptabel als Schlüsselindikator-Eingabewerte ( Ñi+_⁸?4ị¢kann dann werden Ñi+⁸ị¢), aber dies wurde klargestellt als nicht erlaubt, es sei denn -4 ist falsch und 4 ist wahr, was für Jelly nicht der Fall ist.

Wie?

Baut eine Tastatur mit Phantom B#und E#Tasten auf, findet den Index der Eingabe und versetzt diese 4in die gewünschte Richtung, indexiert zurück in eine Tastatur, wobei diese Phantomtasten durch die erforderlichen Ergebnisse (die Taste darüber) ersetzt werden:

ØAḣ7µW€ż;€”#$Ẏ - Link 1, keyboard with phantoms: no inputs
ØA             - alphabet yield        -> ['A', 'B', ..., 'Z']
   7           - literal seven
  ḣ            - head                  -> ['A','B','C','D','E','F','G']
    µ          - new monadic chain, call that K
     W€        - wrap €ach             -> ["A","B","C","D","E","F","G"] ("" being lists of characters)
            $  - last two links as a monad:
          ”#   -   character '#'
        ;€     -   concatenate to €ach -> ["A#","B#","C#","D#","E#","F#","G#"]
       ż       - zip together          -> [["A","A#"],["B","B#"],["C","C#"],["D","D#"],["E","E#"],["F","F#"],["G","G#"]]
             Ẏ - tighten               -> ["A","A#","B","B#","C","C#","D","D#","E","E#","F","F#","G","G#"]

Ç”C4¦”F⁵¦ - Link 2, keyboard with phantoms replaced: no inputs
Ç         - call the last link (1) as a monad  ["A","A#","B","B#","C","C#","D","D#","E","E#","F","F#","G","G#"]
    ¦     - sparse application:
   4      - ...to index: literal four
 ”C       - ...action: character 'C'    -> ["A","A#","B","C","C","C#","D","D#","E","E#","F","F#","G","G#"]
        ¦ - sparse application:
       ⁵  - ...to index: literal ten
     ”F   - ...action: character 'F'    -> ["A","A#","B","C","C","C#","D","D#","E","F","F","F#","G","G#"]

Ñi+_⁸?4ị¢ - Main link: integer, clef (1 Treble / 0 Bass); list of characters, key
                                      e.g. 0; "D#"
Ñ         - next link (1) as a monad (no atom for next link as a nilad, but this works here anyway)
          -                               ["A","A#","B","B#","C","C#","D","D#","E","E#","F","F#","G","G#"]
 i        - first index of key in that    8
      4   - literal four
     ?    - if:
    ⁸     - ...condition: chain's left argument, clef
  +       - ...then: addition
   _      - ...else: subtraction          4
        ¢ - next link as a nilad          ["A","A#","B","C","C","C#","D","D#","E","F","F","F#","G","G#"]
       ị  - index into                    "C"
Jonathan Allan
quelle
Grüner Scheck: Hmm, also hat noch niemand diese Punktzahl übertroffen - ich bin ziemlich schockiert.
Jonathan Allan
9

Befunge, 70 64 Bytes

~0~:70p##~+2%00p+"A"-~7%2++7%:3%2%00g*:10p+"A"+,00g!10g+#@_"#",@

Probieren Sie es online!

Die Eingabe sollte in der Form C# Trebleoder erfolgen F Bass, obwohl der Schlüssel einfach der erste Buchstabe (dh Toder B) sein kann, da der Rest der Eingabe sowieso ignoriert wird.

Erläuterung

~0        Read the note and push a zero (the purpose of this will become apparent later).
~:70p     Read the following sharp or space and write that out as the next instruction.

Infolge dieser Codeänderung wird die nächste Befehlssequenz eine von zwei Formen annehmen:

##~       The first # jumps over the second, and thus we perform the read instruction.
 #~       But if there's only one #, we'll ending up skipping the read instruction.

Zu diesem Zeitpunkt enthält der Stapel entweder note,0,sharp,spaceoder note,0,space.

+2%       Add the top two stack items mod 2, returning 1 if we read a sharp, else 0 if not.
00p       Save this 'sharp' boolean for later use.

Zu diesem Zeitpunkt enthält der Stapel entweder note,0oder nur note(mit einer impliziten Null darunter).

+         By adding the top two items, we combine the 0 (if present) onto the note below.
"A"-      We can then subtract 'A' to convert the note into a number in the range 0 to 6.
~7%2+     Read the T/B clef, then mod 7 and add 2, returning 2 or 5 (the conversion offset).
+7%       Add that offset to our note number, then mod 7, to get the converted note number.
:3%2%     Make a dup, and calculate mod 3 mod 2 to determine the special cases (B# or E#).
00g*      Multiply that by the 'sharp' boolean, since we only care if the input was sharp.
:10p      Duplicate and save this special case boolean for later.
+         Now add it to the note number, since the special cases need to be offset by 1.
"A"+,     Then we can finally convert the number back into a character and output it.
00g!10g+  Now we check if the original note was not sharp, or if this was a special case.
#@_       If so, we exit immediately.
"#",@     Otherwise, we output a '#'.
James Holderness
quelle
3

Perl 5, 56 Bytes

$_=<>;s/./chr 65+(-4*<>+ord$&)%7/e;s/B#/C/;s/E#/F/;print

Liest die Notiz und den Notenschlüssel als zwei Zeilen von STDIN und druckt die neue Notiz an STDOUT. Der Notenschlüssel ist 0für Höhen und 1für Bässe.

faubi
quelle
3

JavaScript (ES6) 74 Byte

Nimmt die Eingabe in currying Syntax (note)(clef)wo clefist 0für Bass und 1für die Höhen .

n=>c=>'FC.DAFCGDAEBF'[k=(parseInt(n,36)*15+!n[1]*90+c)%98%13]+(k<5?'#':'')

Demo

Wie?

Das macht zwar etwas weniger Spaß als meine Vorgängerversion, aber die zugrunde liegende Nachschlagetabelle F#,C#,(unused),D#,A#,F,C,G,D,A,E,B,Fermöglicht es nun, die # -Bedingung zu verkürzen und gleichzeitig den NUL- Zeichentrick zu vermeiden - was vermutlich ein bisschen grenzwertig war.


Vorherige Version 76 75 Bytes

n=>c=>'ACCDFF.CDEFGABCDE'[k=parseInt(4*!!n[1]+c+n,21)%24%17]+'\0#'[45>>k&1]

Demo

Wie?

Die Eingabe (n, c) wird durch die folgenden Schritte verarbeitet:

  1. Wir bewerten zuerst, 4 * !!n[1] + c + nwo wahr ist (auf 1 erzwungen ), wenn die Note ein # enthält , und falsch (auf 0 erzwungen ), wenn dies nicht der Fall!!n[1] ist . Der Ausdruck ergibt einen numerischen Wert, der vor dem String n eingefügt wird .4 * !!n[1] + c

  2. Impliziter Schritt: Führende Nullen und nachfolgende # werden von ignoriert parseInt(). Beispielsweise "5G#"wird tatsächlich analysiert als "5G".

  3. Wir konvertieren den neuen String in einen Dezimalwert, indem wir ihn als Basis-21-Größe analysieren.

  4. Wir wenden modulo 24 an.

  5. Wir wenden modulo 17 an.

Unten finden Sie eine Übersichtstabelle für alle möglichen Eingabepaare sowie die erwartete Ausgabe. Beachten Sie, dass der Ausgabe ein # hinzugefügt werden muss, wenn das Endergebnis 0 , 2 , 3 oder 5 ist . Daher die Verwendung der Binärmaske 101101 ( 45 dezimal).

 n   | c | (1)   | (2)   | (3) | (4) | (5) | Output
-----+---+-------+-------+-----+-----+-----+-------
"E"  | 1 | "1E"  | "1E"  |  35 |  11 |  11 | "G"
"F"  | 1 | "1F"  | "1F"  |  36 |  12 |  12 | "A"
"F#" | 1 | "5F#" | "5F"  | 120 |   0 |   0 | "A#"
"G"  | 1 | "1G"  | "1G"  |  37 |  13 |  13 | "B"
"G#" | 1 | "5G#" | "5G"  | 121 |   1 |   1 | "C"
"A"  | 1 | "1A"  | "1A"  |  31 |   7 |   7 | "C"
"A#" | 1 | "5A#" | "5A"  | 115 |  19 |   2 | "C#"
"B"  | 1 | "1B"  | "1B"  |  32 |   8 |   8 | "D"
"C"  | 1 | "1C"  | "1C"  |  33 |   9 |   9 | "E"
"C#" | 1 | "5C#" | "5C"  | 117 |  21 |   4 | "F"
"D"  | 1 | "1D"  | "1D"  |  34 |  10 |  10 | "F"
"D#" | 1 | "5D#" | "5D"  | 118 |  22 |   5 | "F#"
-----+---+-------+-------+-----+-----+-----+-------
"E"  | 0 | "0E"  | "E"   |  14 |  14 |  14 | "C"
"F"  | 0 | "0F"  | "F"   |  15 |  15 |  15 | "D"
"F#" | 0 | "4F#" | "4F"  |  99 |   3 |   3 | "D#"
"G"  | 0 | "0G"  | "G"   |  16 |  16 |  16 | "E"
"G#" | 0 | "4G#" | "4G"  | 100 |   4 |   4 | "F"
"A"  | 0 | "0A"  | "A"   |  10 |  10 |  10 | "F"
"A#" | 0 | "4A#" | "4A"  |  94 |  22 |   5 | "F#"
"B"  | 0 | "0B"  | "B"   |  11 |  11 |  11 | "G"
"C"  | 0 | "0C"  | "C"   |  12 |  12 |  12 | "A"
"C#" | 0 | "4C#" | "4C"  |  96 |   0 |   0 | "A#"
"D"  | 0 | "0D"  | "D"   |  13 |  13 |  13 | "B"
"D#" | 0 | "4D#" | "4D"  |  97 |   1 |   1 | "C"
Arnauld
quelle
3

Python 2 , 77 Bytes

Funktion, die nach druckt STDOUT. Truewandelt Bässe in Höhen und FalseHöhen in Bässe um.

def f(n,c):N=ord(n[0])-63-4*c;M=-~N%3<1<len(n);print chr((N+M)%7+65)+n[1:2-M]

Probieren Sie es online!

Erläuterung:

  • Die erste Anweisung N=ord(n[0])-63-4*c;berechnet den Index (0 bis 7) des Buchstabens der neuen Note, ohne Berücksichtigung von Schärfen.
    • ord(N[0])-63-4*cRuft den Index des aktuellen Buchstabens ab und addiert oder subtrahiert 2 je nach dem Wert von c(Variable zum Umschalten der Konvertierungsrichtung).
  • Die nächste Anweisung M=-~N%3<1<len(n);berechnet, ob diese Variable angepasst werden muss. Wenn zum Beispiel die neue Note Escharf ist und die ursprüngliche Note scharf war, muss dies auf eine eingestellt werden F. Die verkettete Ungleichung funktioniert wie folgt:
    • -~N%3<1prüft, ob der Index der neuen Note in der Reihenfolge ist 3n-1. Dies ergibt nur wahr für EundB , die beiden Noten, die kein scharfes haben.
    • 1<len(n)prüft, ob die ursprüngliche Note scharf war (dies würde die Länge der Saite größer als 1 machen). Dies ist erforderlich, da die neuen Notizbuchstaben nicht angepasst werden müssen, wenn kein Scharfzeichner vorhanden ist.
    • Hier wird der Wert von Mentweder Trueoder False, der bei der Berechnung als verwendet werden kann , 1und die 0jeweils, so dass die Einstellung durchzuführen brauchen wir nur M zu N hinzufügen und modulo um 7.
  • Die abschließende Anweisung erstellt das Endergebnis und gibt es aus.
    • chr((N+M)%7+65) Fügt die Anpassung bei Bedarf hinzu und konvertiert den Wert von einem Index zurück in ein Zeichen.
    • +n[1:2-M]fügt ein scharfes Symbol hinzu, wenn sowohl M=0(keine Einstellung vorgenommen wurde) als auch der ursprüngliche Wert scharf waren.
FlipTack
quelle
1
Sorry, nur 0 & 1, Truthey & Falsey oder T & B
FantaC
@tfbninja danke für die Klarstellung
FlipTack
2

Java 8, 119 Bytes

n->b->(b?"C D E F G A B C# F F# A# C":"F G A B C D E F# A# C D# F").split(" ")["A B C D E F G A#C#D#F#G#".indexOf(n)/2]

Erläuterung:

Probieren Sie es hier aus.

n->b->         // Method with String and boolean parameters and String return-type
  (b?          //  If it's Treble:
    "C D E F G A B C# F F# A# C"
               //   Use this String
   :           //  Else (it's Bass):
    "F G A B C D E F# A# C D# F")
               //   Use this String
  .split(" ")  //  Split this String by spaces,
   [           //  and then get the item at index:
    "A B C D E F G A#C#D#F#G#".indexOf(n)
               //   Get the index of the String on the left,
    /2]        //   and divide this by 2
               // End of method (implicit / single-line return-statement)
Kevin Cruijssen
quelle
1
eine andere Lösung mit 99 Bytes:n->b->((char)((n.charAt(0)-(b?0:4))%7+65)+n.substring(1)).replaceAll("B#","C").replaceAll("E#","F")
Nahuel Fouilleul
@NahuelFouilleul Ah schön! Ich dachte tatsächlich etwas mit einem Charcast und ein Modulo könnte kürzer sein. Da es sich jedoch etwas zu sehr von meiner aktuellen Antwort unterscheidet, können Sie es auch als separate Antwort veröffentlichen. Du hast meine Zustimmung, wenn du das tust. :)
Kevin Cruijssen
0

R , 111 Bytes

function(k,C,N=paste0(LETTERS[2:15%/%2],c("","#")))sub("E#","F",sub("B#","C",N[which(k==N[(4:17+6*C)%%14+1])]))

Probieren Sie es online!

Ungolfed:

function(k,C){
  N=paste0(LETTERS[2:15%/%2],c("","#")) # Generate a vector of the notes, including E# and B#
  M=N[(4:17+6*C)%%14+1])                # Create a copy that's cycled either up 4 or down 4
  P=N[which(k==M)]                      # Look up the input note in the complementary vector
  P=sub("B#","C",P)                     # Replace B# with C
  P=sub("E#","F",P)                     # Replace E# with F
}
user2390246
quelle