Müzik anahtarları arasında dönüştürme


12

Ayrılmadan önce, bu meydan okumayı yapmak için çok fazla nota anlamak zorunda değilsiniz.

AÇIKLAMA

Standart notalarda, çift nota anahtarı sayfada nota referans noktası görevi görür ve hangi notanın çalınması gerektiğini size bildirir. Tiz ve bas nota anahtarı hakkında henüz bilgi sahibi değilseniz, Wikipedia'dan bir açıklama :

Bir nota anahtarı, yazılı notların perdesini göstermek için kullanılan müzikal bir semboldür. Çıtanın başlangıcındaki satırlardan birine yerleştirildiğinde, o satırdaki notların adını ve perdesini gösterir. Bu çizgi, çıtadaki diğer herhangi bir çizgi veya boşluktaki nota adlarının belirlenebileceği bir referans noktası olarak işlev görür.

Nota

Yukarıdaki resimde, çizgilerin üst yarısı tiz nota anahtarıdır ve bir Üçlü nota anahtarı

Alt yarısı, bas nota anahtarıdır. Bass nota anahtarı

Eğer en alttaki satırda bir not nota anahtarı tiz görebileceğiniz gibi bir olduğu e . (Bu meydan okuma için nota anahtarı satırlarının dışında not saymıyorum) Bas nota anahtarı üzerinde en alt satır G'dir . Bu zorluğu tamamlamak için aşağıdakileri yapmanız gerekir:

MEYDAN OKUMA

Aşağıdaki formlardan birinde (seçiminiz) bir girdi verildiğinde, karşıt nota anahtarı dönüştürün. Tiz veya Bas nota anahtarı olsun, dilinizde bir Truthey / Falsey değeri olabilir (sadece iki değer değil), ör.

F # T veya F # Doğru veya F # Tiz

Ama değil

F # -1 veya F # 4

Boşluklar ve büyük harf kullanımı isteğe bağlıdır, Daireler görünmez ve sondaki boşluklara izin verilmez.

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#

Dikkatli olun, bu önemsiz bir sabit fark meydan okuması değildir. Giriş ve çıkışlara yakından bakın. Bir piyanoya bakarsanız,

Piyano

siyah tuşlar, # ile gösterilen keskin işaretlerdir. Bir E # veya B # olmadığını unutmayın. Bu , Bass nota anahtarı üzerinde G # verildiğinde , E # döndürmek yerine F döndürmeniz gerektiği anlamına gelir.

Bu , bu yüzden en küçük bayt sayısı kazanır.


1
Daireler için endişelenmeli miyiz? Çifte daire / keskinliğe ne dersiniz?
mypetlion

1
Lütfen onları garanti etmeyen konular için etiket oluşturmayın.
Jonathan Allan

3
Sondaki boşluk ( C yerine geri dönüyor C) iyi mi?
Lynn

2
Kullanıyor 1ve -1(hatta söylemek, 4ve -4) izin nota anahtarı göstergesi girişi için veya onlar bizim dilde truthy / Falsey değerler ise bu sadece kabul edilebilirdir?
Jonathan Allan

1
Bu güzel ve iyi sunulmuş bir mücadeledir, ancak biraz rahat giriş / çıkış formatlarıyla daha iyi IMO olurdu.
Arnauld

Yanıtlar:


5

Jöle ,  35  34 bayt

Bazı aritmetik bu yöntem üzerinden kazanabilirsiniz bir duygu var.

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

Çevrimiçi deneyin!

1) sırasıyla nota anahtarı göstergesi 0veya 1Bas veya Tiz ve 2) notu alan tam bir program ; ve ortaya çıkan notun basılması.

31 bayt olur ise -4ve 4nota anahtarı göstergesi giriş değerleri (o olarak kabul edilebilir Ñi+_⁸?4ị¢olabilir Ñi+⁸ị¢), ancak Falsey ve 4 jöle için durum böyle değildir, truthy olmadıkça -4 izin bu açıklığa kavuşturulmuştur.

Nasıl?

Fantom B#ve E#tuşlara sahip bir klavye oluşturur , girişin dizinini bulur, 4gerekli yönde, bu fantom tuşlarının gerekli sonuçlarıyla (üstlerindeki tuş) değiştirilmesiyle klavyeye geri indeksler.

Ø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"

Yeşil onay: Hmm, bu yüzden henüz kimse bu puanı geçemedi - oldukça şok oldum.
Jonathan Allan

9

Befunge, 70 64 bayt

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

Çevrimiçi deneyin!

Giriş formda olmalı C# Trebleveya F Bassher ne kadar nota anahtarı ilk harf (yani Tveya B) olabilse de , girişin geri kalanı yine de yok sayılır.

açıklama

~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.

Bu kod değişikliğinin bir sonucu olarak, sonraki talimat dizisi iki formdan birini alacaktır:

##~       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.

Bu noktada, yığın ya içerir note,0,sharp,spaceya da 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.

Bu noktada, yığın ya içerir note,0ya da sadece note(aşağıda örtük bir sıfır ile).

+         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 '#'.


3

JavaScript (ES6) 74 bayt

Tımar sözdiziminde girişi Alır olduğu için bas ve için tiz .(note)(clef)clef01

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

gösteri

Nasıl?

Bu aslında önceki sürümümden biraz daha az eğlenceli, ancak altta yatan sınırlama tablosu olan NUL karakter hilesinden kaçınarak # koşulunu F#,C#,(unused),D#,A#,F,C,G,D,A,E,B,Fkısaltmaya izin veren temel arama tablosu şimdi .


Önceki sürüm 76 75 bytes

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

gösteri

Nasıl?

Giriş (n, c) aşağıdaki adımlarla işlenir:

  1. Biz ilk değerlendirmek 4 * !!n[1] + c + nnerede !!n[1]olduğu doğrudur (coerced 1 nota bir içeriyorsa) # ve false (coerced 0 aksi). İfade 4 * !!n[1] + c, n dizesinin önüne eklenen sayısal bir değerle sonuçlanır .

  2. Örtük adım: baştaki sıfırlar ve sondaki # tarafından yoksayılır parseInt(). Örneğin "5G#", aslında olarak ayrıştırılır "5G".

  3. Yeni dizeyi, taban-21 miktarı olarak ayrıştırarak ondalık bir değere dönüştürürüz.

  4. Modulo 24'ü uyguluyoruz.

  5. Modulo 17'yi uyguluyoruz.

Aşağıda, beklenen çıktı ile birlikte tüm olası giriş çiftleri için özet tablo bulunmaktadır. Bir Not # nihai sonucu ise, çıkış eklenmelidir 0 , 2 , 3 ya da 5 . Bu nedenle, 101101 ikili maskesinin kullanımı ( ondalık olarak 45 ).

 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"

3

Python 2 , 77 bayt

Yazdırma işlevi STDOUT. Truebasları tizlere, Falsetizleri basa dönüştürür.

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]

Çevrimiçi deneyin!

Açıklama:

  • İlk ifade, N=ord(n[0])-63-4*c;keskinlikleri dikkate almadan yeni notun mektubunun dizinini (0 ila 7) hesaplar.
    • ord(N[0])-63-4*cgeçerli harfin dizinini alır ve değerine bağlı olarak 2 ekler veya çıkarır c(dönüşüm yönünü değiştirmek için değişken)
  • Sonraki ifade, M=-~N%3<1<len(n);bu değişkenin ayarlanması gerekip gerekmediğini hesaplar. Örneğin, yeni not Eve orijinal notun keskin olması durumunda, bunun bir a olarak ayarlanması gerekir F. Zincirli eşitsizlik şu şekilde işler:
    • -~N%3<1yeni not dizininin sırada olup olmadığını kontrol eder 3n-1. Bu yalnızca için geçerlidir verecektir Eve Bkeskin olmayan iki notları.
    • 1<len(n)orijinal notun keskin olup olmadığını kontrol eder (bu, dizenin uzunluğunu 1'den büyük yapar). Keskin bir şey yoksa, yeni not mektuplarını ayarlamaya gerek olmadığından bu gereklidir.
    • Bu M, ya hesaplamayı sırasıyla ve gibi kullanılabilen ya Trueda değerini ayarlar , bu nedenle ayarlamayı gerçekleştirmek için sadece M'ye M ve modulo'yu 7'ye eklememiz gerekir.False10
  • Nihai ifade nihai sonucu oluşturur ve çıkarır.
    • chr((N+M)%7+65) gerekirse düzeltmeyi ekler, ardından değeri bir dizinden tekrar bir karaktere dönüştürür.
    • +n[1:2-M]hem M=0(ayarlama yapılmadıysa) hem de orijinal değer de keskinse keskin bir sembol ekleyecektir .

1
Üzgünüz, sadece 0 & 1, Truthey & Falsey veya T&B
FantaC

@tfbninja açıklama için teşekkürler
FlipTack

2

Java 8, 119 bayt

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]

Açıklama:

Burada deneyin.

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)

1
99 bayt ile başka bir çözüm:n->b->((char)((n.charAt(0)-(b?0:4))%7+65)+n.substring(1)).replaceAll("B#","C").replaceAll("E#","F")
Nahuel Fouilleul

@NahuelFouilleul Ah güzel! Gerçekten bir karakter kadrosu ile bir şeyler düşünüyordum ve bazı modulolar daha kısa olabilirdi. Ama şu anki cevabımdan biraz farklı olduğundan, ayrı bir cevap olarak göndermekten çekinmeyin. Sen yaparsam benim oyumu aldın. :)
Kevin Cruijssen

0

R , 111 bayt

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])]))

Çevrimiçi deneyin!

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
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.