Chuyển đổi giữa các bản nhạc


12

Trước khi bạn rời đi, bạn không cần phải hiểu nhiều ký hiệu âm nhạc để thực hiện thử thách này.

GIẢI TRÌNH

Trong bản nhạc tiêu chuẩn, các dấu ngoặc kép đi ngang qua trang phục vụ như các điểm tham chiếu đến các ghi chú, cho bạn biết những nốt nào nên được phát. Nếu bạn chưa quen thuộc với âm treble và bass, đây là một mô tả từ Wikipedia:

Khóa của âm nhạc là một biểu tượng âm nhạc được sử dụng để biểu thị cao độ của các ghi chú bằng văn bản. Được đặt trên một trong những dòng ở đầu của stave, nó cho biết tên và cao độ của các ghi chú trên dòng đó. Dòng này đóng vai trò là điểm tham chiếu theo đó tên của các ghi chú trên bất kỳ dòng hoặc không gian nào khác của stave có thể được xác định.

Bản nhạc

Trong hình trên, nửa trên của dòng là khóa của Treble, ký hiệu là Khóa kéo

Nửa dưới là khóa của Bass, ký hiệu là Âm bass

Như bạn có thể nhìn thấy trên treble khóa của âm nhạc một lưu ý trên hầu hết đáy dòng là một E . (Tôi không đếm các ghi chú bên ngoài các dòng khóa của thử thách này) Trên khóa của âm trầm, dòng thấp nhất là G . Để hoàn thành thử thách này, bạn phải làm như sau:

THỬ THÁCH

Đưa ra một đầu vào theo một trong các hình thức sau (sự lựa chọn của bạn), chuyển đổi nó sang khóa đối diện. Cho dù đó là khóa của Treble hay Bass có thể là giá trị Truthey / Falsey trong ngôn ngữ của bạn (không chỉ là hai giá trị), vd

F # T hoặc F # Đúng hoặc F # Treble

nhưng không

F # -1 hoặc F # 4

Không gian và viết hoa là tùy chọn, Căn hộ sẽ không xuất hiện và khoảng trắng theo dõi không được phép.

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#

Được cảnh báo trước, đây không phải là một thách thức khác biệt tầm thường. Nhìn kỹ vào đầu vào và đầu ra. Nếu bạn nhìn vào một cây đàn piano,

Đàn piano

các phím màu đen là sắc nét, ký hiệu là #. Lưu ý rằng không có E # hoặc B #. Điều này có nghĩa là nếu bạn được cấp G # trên khóa của Bass, thay vì trả lại E # , bạn cần trả về F

Đây là , vì vậy số byte nhỏ nhất sẽ thắng.


1
Chúng ta có phải lo lắng về căn hộ? Làm thế nào về căn hộ đôi / sắc nét?
mypetlion

1
Vui lòng không tạo thẻ cho các chủ đề không đảm bảo chúng.
Jonathan Allan

3
Là khoảng trắng dấu vết (trở lại C thay vì C) được không?
Lynn

2
Việc sử dụng 1-1(hoặc thậm chí nói, 4-4) cho đầu vào chỉ báo khóa được phép hay điều này chỉ được chấp nhận nếu chúng là giá trị trung thực / falsey trong ngôn ngữ của chúng tôi?
Jonathan Allan

1
Đây là một thử thách hay và được trình bày tốt, nhưng nó thậm chí còn tốt hơn IMO với các định dạng đầu vào / đầu ra hơi thoải mái.
Arnauld

Câu trả lời:


5

Thạch ,  35  34 byte

Tôi có cảm giác một số số học có thể chiến thắng phương pháp này.

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

Hãy thử trực tuyến!

Một chương trình đầy đủ lấy 1) chỉ báo khóa của âm nhạc 0hoặc 1cho Bass hoặc Treble tương ứng và 2) ghi chú; và in ghi chú kết quả.

Sẽ là 31 byte nếu -44được chấp nhận làm giá trị đầu vào của chỉ báo khóa (sau đó Ñi+_⁸?4ị¢có thể trở thành Ñi+⁸ị¢) nhưng điều này đã được làm rõ là không được phép trừ khi -4 là falsey và 4 là sự thật, đó không phải là trường hợp của Jelly.

Làm sao?

Xây dựng một bàn phím có ảo B#E#các phím, tìm chỉ mục của đầu vào, bù 4lại theo hướng yêu cầu, lập chỉ mục lại vào bàn phím với các phím ảo đó được thay thế bằng các kết quả được yêu cầu (phím phía trên chúng):

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

Kiểm tra màu xanh lá cây: Hmm, vì vậy chưa có ai đánh bại số điểm này - tôi khá sốc.
Jonathan Allan

9

Befunge, 70 64 byte

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

Hãy thử trực tuyến!

Đầu vào phải ở dạng C# Treblehoặc F Bass, mặc dù khóa chỉ có thể là chữ cái đầu tiên (nghĩa là Thoặc B), vì phần còn lại của đầu vào bị bỏ qua.

Giải trình

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

Do sửa đổi mã này, chuỗi hướng dẫn tiếp theo sẽ có một trong hai dạng:

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

Tại thời điểm này, ngăn xếp có chứa note,0,sharp,spacehoặc 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.

Tại thời điểm này, ngăn xếp có chứa note,0 hoặc chỉ note(với số 0 ẩn bên dưới).

+         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 byte

Đưa đầu vào trong cú pháp currying (note)(clef)nơi clef0cho âm bass1cho treble .

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

Bản giới thiệu

Làm sao?

Điều này thực sự ít thú vị hơn so với phiên bản trước của tôi, nhưng bảng tra cứu cơ bản hiện đang F#,C#,(unused),D#,A#,F,C,G,D,A,E,B,Fcho phép rút ngắn điều kiện # trong khi tránh thủ thuật ký tự NUL - đó là một đường viền bit, tôi cho rằng.


Phiên bản trước 76 75 byte

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

Bản giới thiệu

Làm sao?

Đầu vào (n, c) được xử lý qua các bước sau:

  1. Trước tiên, chúng tôi đánh giá 4 * !!n[1] + c + nnơi nào !!n[1]đúng (bị ép buộc thành 1 ) nếu ghi chú chứa #sai (bị ép thành 0 ) nếu không. Biểu thức 4 * !!n[1] + cdẫn đến một giá trị số được thêm vào trước chuỗi n .

  2. Bước ngầm định: các số 0 đứng đầu và dấu # được bỏ qua bởi parseInt(). Ví dụ, "5G#"thực sự được phân tích cú pháp như "5G".

  3. Chúng tôi chuyển đổi chuỗi mới thành giá trị thập phân bằng cách phân tích chuỗi dưới dạng số lượng cơ sở 21.

  4. Chúng tôi áp dụng modulo 24.

  5. Chúng tôi áp dụng modulo 17.

Dưới đây là bảng tóm tắt cho tất cả các cặp đầu vào có thể, cùng với đầu ra dự kiến. Lưu ý rằng # phải được thêm vào đầu ra nếu kết quả cuối cùng là 0 , 2 , 3 hoặc 5 . Do đó việc sử dụng mặt nạ nhị phân 101101 ( 45 trong số thập phân).

 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

Con trăn 2 , 77 byte

Chức năng in ra STDOUT. Truechuyển đổi âm trầm thành âm bổng, và Falsechuyển đổi âm bổng thành âm trầm.

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]

Hãy thử trực tuyến!

Giải trình:

  • Câu lệnh đầu tiên N=ord(n[0])-63-4*c;, tính toán chỉ số (0 đến 7) của chữ cái ghi chú mới, bỏ qua các phần sắc nét.
    • ord(N[0])-63-4*clấy chỉ mục của chữ cái hiện tại và cộng hoặc trừ 2 tùy thuộc vào giá trị của c(biến để chuyển đổi hướng chuyển đổi)
  • Câu lệnh tiếp theo, M=-~N%3<1<len(n);tính toán xem có cần điều chỉnh biến này hay không. Ví dụ: nếu ghi chú mới là Evà ghi chú ban đầu có độ sắc nét, thì điều này sẽ cần phải được điều chỉnh thành một F. Bất đẳng thức chuỗi hoạt động như sau:
    • -~N%3<1kiểm tra xem chỉ số của ghi chú mới có trong chuỗi hay không 3n-1. Điều này sẽ chỉ mang lại đúng cho EB, hai lưu ý không có sắc nét.
    • 1<len(n)kiểm tra xem ghi chú ban đầu có sắc nét không (điều này sẽ làm cho độ dài của chuỗi lớn hơn 1). Điều này là cần thiết vì, nếu không có sắc nét, không cần phải điều chỉnh các chữ cái ghi chú mới.
    • Bộ này giá trị của Mmột trong hai Truehoặc False, có thể được sử dụng trong tính toán như 10tương ứng, vì vậy để thực hiện việc điều chỉnh, chúng tôi chỉ cần thêm M đến N và modulo 7.
  • Tuyên bố cuối cùng tạo ra và đưa ra kết quả cuối cùng.
    • chr((N+M)%7+65) thêm điều chỉnh nếu cần thiết, sau đó chuyển đổi giá trị từ chỉ mục trở lại thành ký tự.
    • +n[1:2-M]sẽ nối thêm một biểu tượng sắc nét nếu cả hai M=0(không thực hiện điều chỉnh) và giá trị ban đầu cũng có độ sắc nét.

1
Xin lỗi, chỉ 0 & 1, Truthey & Falsey hoặc T & B
FantaC

@tfbninja cảm ơn bạn đã làm rõ
FlipTack

2

Java 8, 119 byte

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]

Giải trình:

Hãy thử nó ở đây.

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
một giải pháp khác với 99 byte:n->b->((char)((n.charAt(0)-(b?0:4))%7+65)+n.substring(1)).replaceAll("B#","C").replaceAll("E#","F")
Nahuel Fouilleul

@NahuelFouilleul À! Tôi thực sự đã suy nghĩ điều gì đó với dàn diễn viên và một số modulo có thể ngắn hơn. Nhưng vì nó hơi khác so với câu trả lời hiện tại của tôi, vui lòng đăng nó dưới dạng một câu trả lời riêng biệt. Bạn đã có upvote của tôi nếu bạn làm. :)
Kevin Cruijssen

0

R , 111 byte

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

Hãy thử trực tuyến!

Ung dung:

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
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.