绘制ASCII密钥签名


22

给定音符输入,输出高音谱号上相应主键的ASCII绘图。

以下是所有主要键(不包括双尖音或双平键)及其对应的键签名:


Wikipedia用户Justin Bill 的五分之三豪华4圈,版权CC BY-SA 3.0

如果输入是带有尖音的键,请使用适当数量的尖音绘制以下ASCII艺术作品:

   #
-#-------
      #
----#----
  #
-------#-
     #
---------

---------

如果输入是带平键的键:

---------
  b
----b----
      b
-b-------
   b
-----b---
       b
---------

以下是可能输入的简要摘要,以及它们使用了多少尖锐或平坦的物体:

   0   1   2   3   4   5   6   7
#  C   G   D   A   E   B   F#  C#
b  C   F   Bb  Eb  Ab  Db  Gb  Cb

必须始终绘制所有五行破折号,但是每行可以有任意数量的破折号,这样,只要每条破折号具有相同的长度,尖锐或平坦的每一侧都具有至少一列填充。例如,这些都是输入的可接受输出Ab

---------   ------   ---------   ----------------
  b           b           b          b
----b----   ----b-   -------b-   ------b---------

-b-------   -b----   ----b----   ---b------------
   b           b           b          b
---------   ------   ---------   ----------------

---------   ------   ---------   ----------------

如果C大调既没有尖头也没有平坦,则每行的破折号可以是正数(甚至一个)。

任何数量的前导或尾随空格都可以,每行上的尾随空格也可以。只要每行上有相同的数字,多余的前导空格是可以的。

如果需要,可以小写输入,也可以要求没有尖锐或平坦的输入包含尾随空格。

由于这是,因此以字节为单位的最短解决方案将获胜。



3
@Neil啊,很抱歉窃取您的挑战> _ <我在发布之前搜索了主站点,但没有想到要检查沙箱。
门把手

Answers:


3

Python 2中206个197 178 175 168 161字节

感谢Xcoder先生提供-12个字节!

这是一个将结果作为二维字符列表返回的函数。如果输入不包含尖锐/平坦,则应在其上填充空格。

def f(k,r=range(10)):n="CGDAEB".find(k[0])+7*' #'.find(k[1]);return[[(' -'[i%2],'b#'[n>0])[0<j<=abs(n)and`i`==(n*"1403625"+"5263748")[j-1]]for j in r]for i in r]

在线尝试!


我认为"FCGDAEB".find(k[0])-1映射F-1其他索引到它们的索引-1,所以我认为n="CGDAEB".find(k[0])+7*('#'in k)-7*('b'in k)可以代替。(175个字节?
Xcoder先生17年

@ Mr.Xcoder太聪明了...谢谢。
FlipTack

3

木炭,60字节

≔⁻⁺⊖﹪⊗℅§θ¬χ⁷×⁷№θ#×⁷№θbθ←UO⁹¦⁹-¶Fθ«Jι⊖﹪⊕׳ι⁷#»F±θ«Jι⊕﹪⁺³×⁴ι⁷b

在线尝试!链接是详细版本的代码。说明:

≔⁻⁺⊖﹪⊗℅§θ¬χ⁷×⁷№θ#×⁷№θbθ

计算密钥签名中的锐器数量。

←UO⁹¦⁹-¶

打印梯级,但在原点左方出一个正方形,以便第一个锐利/平坦的位置在列零中。

Fθ«

绕过任何利器。

Jι⊖﹪⊕׳ι⁷#»

计算锐利笔的行并打印。

F±θ«

圈出任何单位。

Jι⊕﹪⁺³×⁴ι⁷b

计算单位的行并打印。


2

Befunge,139个字节

~9%:4%7*+4/7%~6%1-2/7*+vv\`0:\!-g02+*2g00+1%7+g00*+3g00::<<0+55p02:_@
- b#09p01*-1*2p00:`0:-8<>10g`!**:00g2+*\!20g2%*+1g,1+:8`!#^_>$,:1-\^1

在线尝试!

请注意,预期输入将以换行符终止,这在交互式运行程序时通常会发生。

说明

我们首先从stdin读取两个字符-主音符n和一个偶然的字符a(如果没有偶然的情况,可以换行)。使用这些值,我们计算密钥签名号signum,如下所示:

signum = (n%9 + n%9%4*7)/4%7 + (a%6 - 1)/2*7 - 8

这将返回一个介于-7到7之间的值,其中的符号告诉我们是否需要锐角或扁平(正数或负数),并且绝对值给出了所需的锐角或平坦数。因此,为了以后使用,我们使用以下命令提取符号s和意外计数cnt

s   = (signum > 0)
cnt = abs(signum) 

然后,我们有两个嵌套循环,将行号r从9向下迭代到0,将列号c从0 迭代到8。对于特定的行和列,我们计算在该处是否应该显示偶然事件指向:

accidental = (r == (c*(s+3) + s)%7 + 1 + s*2) and (c > 0) and (c <= cnt)

如果不是偶然的话,我们需要根据行r是奇数还是偶数来输出行或空格。如果是偶然的情况,我们需要根据符号s输出尖锐或平坦的形状。因此,我们评估以下公式:

index = (!accidental * (r%2)) + (accidental * (s+2))

这给了我们0到3范围内的索引,代表一条线,一个空格,一个平面或一个尖锐的区域。我们仅使用该索引从表中查找所需的输出字符,您可以在第二行代码的开头看到嵌入的表。

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.