在音乐谱号之间转换


12

离开之前,您无需了解太多的乐谱即可完成此挑战。

说明

在标准活页乐谱中,双谱号跨过页面,用作音符的参考点,让您知道应该演奏哪个音符。如果您还不熟悉高音谱号和低音谱号,请参阅Wikipedia中的说明

谱号是一种音乐符号,用于指示音符的音高。放在五线谱开始处的其中一行上,它指示该行上音符的名称和音高。该线用作参考点,通过该参考点可以确定五线谱的任何其他线或空间上的音符名称。

乐谱

在上图中,线条的上半部分是高音谱号,用a表示 高音谱号

下半部分是低音谱号,用 低音谱号

正如你可以在高音谱号看到一张纸条上的最底部线是Ë。(我不是外面计数谱号线这一挑战的笔记)在低音谱号,最低线是。要完成此挑战,您必须执行以下操作:

挑战

给定以下形式之一的输入(您的选择),请将其转换为相反的谱号。无论是高音谱号还是低音谱号,在您的语言中都可以是Truthey / Falsey值(不仅是两个值),例如

F#TF#TrueF#高音

但不是

F#-1F#4

空格和大写字母是可选的,不显示单位,并且不允许尾随空格。

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#

请注意,这不是一个琐碎的常数差挑战。仔细观察输入和输出。如果你看钢琴,

钢琴

黑色键是尖锐符号,用#表示。请注意,没有E#或B#。这意味着如果您在低音谱号上获得G#,而不是返回E#,则需要返回F

这是,因此最小的字节数为准。


1
我们是否需要担心公寓?双层/竖琴怎么样?
mypetlion

1
请不要为不需要保证的主题创建标签。
乔纳森·艾伦

3
尾随空格(返回C 而不是C)可以吗?
林恩

2
是否允许1-1(或什至说4-4)用作谱号指示符输入,或者仅当它们是我们语言中的真/假值时才可接受吗?
乔纳森·艾伦

1
这是一个很好且很好呈现的挑战,但如果输入/输出格式稍微宽松一点,它将是更好的IMO。
Arnauld

Answers:


5

果冻 35  34 字节

我觉得有些算术可能会胜过这种方法。

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

在线尝试!

一个完整的程序,包括:1)谱号指示符01分别针对低音或高音的指示; 2)音符;并打印结果便笺。

如果-44可以用作谱号指示符输入值(则Ñi+_⁸?4ị¢变为Ñi+⁸ị¢),则将为31个字节(但是变为),但除非-4为false和4为true,否则已被澄清为不允许,对于Jelly而言并非如此。

怎么样?

用幻像B#E#键构建键盘,找到输入的索引,4在所需方向上偏移,再索引回键盘,其中那些幻像键替换为其所需的结果(它们上方的键):

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

绿色检查:嗯,所以没人能超过这个分数-我很震惊。
乔纳森·艾伦

9

Befunge,70 64字节

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

在线尝试!

输入应在形式C# TrebleF Bass,虽然谱号可以简单地是第一个字母(即TB)中,由于输入的其余部分被反正忽略。

说明

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

由于此代码修改,下一个指令序列将采用以下两种形式之一:

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

此时,堆栈包含note,0,sharp,spacenote,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.

此时,堆栈要么包含要么包含(note,0或仅包含note一个)(下面有一个隐式零)。

+         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字节

发生在钻营语法输入(note)(clef)其中,clef0低音1用于高音

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

演示版

怎么样?

这实际上比我以前的版本好玩一点,但是底层的查找表现在F#,C#,(unused),D#,A#,F,C,G,D,A,E,B,F可以缩短条件,同时避免了NUL字符欺骗-我想这有点边界。


先前版本76 75字节

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

演示版

怎么样?

通过以下步骤处理输入(n,c)

  1. 我们首先评估如果注释包含,则4 * !!n[1] + c + nwhere !!n[1]true(强制为1),否则为false(强制为0)。该表达式产生一个数值,该数值被添加到字符串n的前面。4 * !!n[1] + c

  2. 隐式步骤:忽略前导零和尾随parseInt()。例如,"5G#"实际上被解析为"5G"

  3. 通过将新字符串解析为以21为底的数量,我们将其转换为十进制值。

  4. 我们应用模24。

  5. 我们应用模17。

以下是所有可能的输入对的汇总表以及预期的输出。注意,必须被添加到输出,如果最后的结果是0235。因此,使用二进制掩码101101(十进制为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个字节

打印到的功能STDOUTTrue将低音转换为高音,False并将高音转换为低音。

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]

在线尝试!

说明:

  • 第一个语句,N=ord(n[0])-63-4*c;计算新笔记字母的索引(0到7),不考虑尖音。
    • ord(N[0])-63-4*c获取当前字母的索引,并根据的值加或减2 c(可用于转换转换方向)
  • 下一条语句M=-~N%3<1<len(n);计算是否需要调整此变量。例如,如果新音符为E,并且原始音符带有尖锐音符,则需要将其调整为F。连锁不平等的工作原理如下:
    • -~N%3<1检查新笔记的索引是否在sequence中3n-1。这只会对E和产生真值,而B这两个音符没有尖音。
    • 1<len(n)检查原始音符是否尖锐(这会使字符串的长度大于1)。这是必要的,因为如果没有锋利的声音,则无需调整新的备忘字母。
    • 这会将的值设置MTrueFalse,可以分别使用as 1和来计算0,因此要进行调整,我们只需要将M加到N并以7为模。
  • final语句创建并输出最终结果。
    • chr((N+M)%7+65) 根据需要添加调整,然后将值从索引转换回字符。
    • +n[1:2-M]如果M=0(未进行任何调整)并且原始值也都带有尖锐字符,则将附加一个尖锐的符号。

1
抱歉,只有01,Truthey&Falsey或T&B
FantaC '17

@tfbninja感谢您的澄清
FlipTack

2

Java 8,119字节

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]

说明:

在这里尝试。

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个字节的解决方案:n->b->((char)((n.charAt(0)-(b?0:4))%7+65)+n.substring(1)).replaceAll("B#","C").replaceAll("E#","F")
Nahuel Fouilleul

@NahuelFouilleul很好啊!我的确在想一些带有字符转换的内容,并且一些模可能更短。但是,由于它与我当前的答案有些不同,请随时将其作为单独的答案发布。如果您愿意,您将得到我的支持。:)
Kevin Cruijssen

0

R,111字节

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

在线尝试!

取消高尔夫:

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
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.