แปลงระหว่าง Music clefs


12

ก่อนออกเดินทางคุณไม่จำเป็นต้องเข้าใจสัญลักษณ์ทางดนตรีมากมายในการทำสิ่งนี้

คำอธิบาย

ในแผ่นโน้ตเพลงมาตรฐาน clefs สองครั้งจะข้ามหน้าที่ทำหน้าที่เป็นจุดอ้างอิงไปยังโน้ตทำให้คุณรู้ว่าควรเล่นโน้ตใด หากคุณยังไม่คุ้นเคยกับเสียงแหลมและเสียงแหลม clef นี่คือคำอธิบายจากWikipedia:

clef เป็นสัญลักษณ์ดนตรีที่ใช้เพื่อระบุระดับเสียงของโน้ตที่เขียน วางอยู่บนหนึ่งในบรรทัดที่จุดเริ่มต้นของขั้นบันไดก็ระบุชื่อและระดับเสียงของบันทึกในบรรทัดนั้น บรรทัดนี้ทำหน้าที่เป็นจุดอ้างอิงที่อาจมีการกำหนดชื่อของบันทึกย่อในบรรทัดหรือช่องว่างอื่นของเสา

โน้ตเพลง

ในภาพด้านบนครึ่งบนของเส้นคือ Treble clef ซึ่งแสดงด้วย Treble Clef

ครึ่งล่างคือเบสกุญแจเสียงเขียนด้วย Bass Clef

ที่คุณสามารถดูได้ที่เสียงแหลมโน๊ตโน้ตที่ด้านล่างสุดบรรทัดเป็นE (ผมไม่ได้นับบันทึกนอกของเส้นโน๊ตสำหรับความท้าทายนี้) เมื่อวันที่โน๊ตเบสสายต่ำสุดเป็นG เพื่อให้การท้าทายนี้คุณต้องทำสิ่งต่อไปนี้:

ท้าทาย

ให้ข้อมูลในรูปแบบใดรูปแบบหนึ่งต่อไปนี้ (ตัวเลือกของคุณ) ให้แปลงเป็นรูปตัวโน๊ตตรงกันข้าม ไม่ว่าจะเป็น Treble หรือ Bass clef สามารถเป็นค่า Truthey / Falsey ในภาษาของคุณ (ไม่ใช่แค่สองค่าใด ๆ ) เช่น

F # T หรือ F # True หรือ F # Treble

แต่ไม่

F # -1 หรือ F # 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 #ใน Bass clef แทนที่จะส่งคืนE #คุณจะต้องส่งคืนF

นี่คือดังนั้นการนับไบต์ที่เล็กที่สุดชนะ


1
เราต้องกังวลเรื่องแฟลตไหม? คู่แฟลต / ชาร์ทล่ะ?
mypetlion

1
โปรดอย่าสร้างแท็กสำหรับหัวข้อที่ไม่รับประกัน
Jonathan Allan

3
ช่องว่างต่อท้าย (ส่งคืนC แทนC) ใช้ได้ไหม
ลินน์

2
การใช้1และ-1(หรือแม้กระทั่งพูด4และ-4) สำหรับการป้อนข้อมูลตัวบ่งชี้ clef ได้รับอนุญาตหรือจะเป็นสิ่งที่ยอมรับได้หากพวกเขาเป็นค่าความจริง / เท็จในภาษาของเรา?
Jonathan Allan

1
นี่เป็นความท้าทายที่ดีและนำเสนอได้ดี แต่น่าจะเป็น IMO ที่ดียิ่งขึ้นด้วยรูปแบบอินพุต / เอาท์พุตที่ผ่อนคลายเล็กน้อย
Arnauld

คำตอบ:


5

เยลลี่ ,  35  34 ไบต์

ฉันมีความรู้สึกว่าเลขคณิตอาจชนะได้มากกว่าวิธีนี้

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

ลองออนไลน์!

โปรแกรมเต็มรูปแบบรับ 1) ตัวบ่งชี้ที่สำคัญ0หรือ1สำหรับเบสหรือเสียงแหลมตามลำดับและ 2) บันทึก; และการพิมพ์บันทึกผลลัพธ์

จะเป็น 31 ไบต์หาก-4และ4ยอมรับได้เนื่องจากค่าอินพุตตัวบ่งชี้ clef (จากนั้นÑi+_⁸?4ị¢สามารถกลายเป็นได้Ñi+⁸ị¢) แต่สิ่งนี้ได้รับการชี้แจงอย่างชัดเจนเนื่องจากไม่อนุญาตเว้นแต่ว่า -4 จะเป็นเท็จและ 4 เป็นความจริงซึ่งไม่ใช่กรณีของ Jelly

อย่างไร?

สร้างแป้นพิมพ์ด้วย phantom B#และE#แป้นค้นหาดัชนีของอินพุตชดเชยโดย4ในทิศทางที่ต้องการดัชนีกลับเข้าไปในแป้นพิมพ์ด้วยแป้น phantom เหล่านั้นที่ถูกแทนที่ด้วยผลลัพธ์ที่ต้องการ (ปุ่มด้านบน)

Ø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

9

Befunge, 70 64 ไบต์

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

ลองออนไลน์!

อินพุตควรอยู่ในรูปแบบC# TrebleหรือF Bassแม้ว่าตัวโน๊ตสามารถเป็นตัวอักษรตัวแรกได้ (เช่นTหรือB) เนื่องจากส่วนที่เหลือของอินพุตจะถูกละเว้นอยู่ดี

คำอธิบาย

~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

Perl 5, 56 ไบต์

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

อ่าน note และ clef เป็นสองบรรทัดจาก STDIN และพิมพ์บันทึกย่อใหม่ไปที่ STDOUT กุญแจเสียง0สำหรับเสียงแหลมและ1เบส


1
สามารถบันทึก 11 ไบต์โดยใช้-pแฟล็กtio.run/##K0gtyjH9/79YX08/OaNIwcxUW0PXRMvGTju/KEVFTVPVXD/…
Nahuel Fouilleul

3

JavaScript (ES6) 74 ไบต์

จะเข้าในไวยากรณ์ currying (note)(clef)ที่clefเป็น0สำหรับเบสและ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 + nว่า!!n[1]เป็นความจริง (coerced ถึง1 ) ถ้าบันทึกมี#และfalse (coerced เป็น0 ) เป็นอย่างอื่น การแสดงออก4 * !!n[1] + cผลลัพธ์ในค่าตัวเลขที่จะถูกเพิ่มในด้านหน้าของสตริงn

  2. ขั้นตอนโดยปริยาย: ศูนย์ชั้นนำและต่อท้าย#parseInt()จะถูกละเลยโดย ยกตัวอย่างเช่นจะแยกเป็นจริง"5G#""5G"

  3. เราแปลงสตริงใหม่เป็นค่าทศนิยมโดยแยกวิเคราะห์เป็นปริมาณฐาน 21

  4. เราใช้โมดูโล 24

  5. เราใช้โมดูโล 17

ด้านล่างเป็นตารางสรุปสำหรับคู่อินพุตที่เป็นไปได้ทั้งหมดพร้อมกับเอาต์พุตที่คาดหวัง โปรดทราบว่า#ต้องเพิ่มการส่งออกถ้าผลสุดท้ายคือ0 , 2 , 3หรือ5 ดังนั้นการใช้ binary mask 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 ไบต์

STDOUTฟังก์ชั่นที่พิมพ์ไป Trueแปลงเสียงเบสเป็นเสียงแหลมและ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<13n-1ตรวจสอบว่าดัชนีบันทึกใหม่อยู่ในลำดับ สิ่งนี้จะให้ผลจริงสำหรับEและBโน้ตสองตัวที่ไม่มีความคมชัด
    • 1<len(n)ตรวจสอบว่าบันทึกย่อต้นฉบับมีความคมชัดหรือไม่ (นี่จะทำให้ความยาวของสตริงใหญ่กว่า 1) นี่เป็นสิ่งจำเป็นเนื่องจากหากไม่มีความคมชัดไม่จำเป็นต้องปรับเปลี่ยนตัวอักษรใหม่
    • ค่านี้ตั้งค่าMเป็นTrueหรือFalseซึ่งสามารถใช้ในการคำนวณตาม1และ0ตามลำดับดังนั้นเพื่อทำการปรับเราต้องเพิ่ม M ถึง N และโมดูโลตาม 7 เท่านั้น
  • คำสั่งสุดท้ายสร้างและส่งออกผลลัพธ์สุดท้าย
    • chr((N+M)%7+65) เพิ่มการปรับหากจำเป็นจากนั้นแปลงค่าจากดัชนีกลับเป็นอักขระ
    • +n[1:2-M]จะต่อท้ายสัญญลักษณ์คมชัดหากทั้งคู่M=0(ไม่มีการปรับแต่ง) และค่าดั้งเดิมก็มีความคมชัดเช่นกัน

1
ขออภัยเฉพาะ 0 & 1, Truthey & Falsey หรือ T&B
FantaC

@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 อ่า! ฉันกำลังคิดอะไรบางอย่างกับตัวละครและโมดูโลบางตัวอาจสั้นกว่านี้ แต่เนื่องจากมันแตกต่างจากคำตอบปัจจุบันของฉันมากเกินไปโปรดโพสต์เป็นคำตอบแยกต่างหาก คุณมี upvote ของฉันถ้าคุณทำ :)
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])]))

ลองออนไลน์!

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
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.