คอร์ดเปียโนบนคีย์สีขาว


9

Backstory [ซึ่งไม่เป็นความจริง]

มีการตั้งเปียโนดังนี้:

[http://www.piano-lessons-made-simple.com/images/2-Octave-Labled.gif

อย่างไรก็ตามบนเปียโนของฉันปุ่มสีดำทั้งหมดเสีย!

ฉันยังต้องการที่จะเล่นคอร์ดบางอย่างบนเปียโนที่หักของฉัน

ในดนตรีคอร์ดคือกลุ่มของโน้ตที่เล่นด้วยกัน เพื่อให้สามารถป้อนข้อมูลของคอร์ดฉันจะกำหนดสิ่งที่เป็นเสียงดนตรี

semitone คืออะไร?

semitone เป็นระยะทางที่เล็กที่สุดในดนตรีตะวันตก หากคุณดูที่ส่วนบนของเปียโนคุณจะเห็นว่าโดยปกติคุณสามารถย้ายจากคีย์สีดำไปเป็นคีย์สีขาวหรือในทางกลับกัน อย่างไรก็ตามระหว่างBและCกับEและFไม่มีคีย์สีดำ

คอร์ดคืออะไร

สำหรับจุดประสงค์ของการท้าทายนี้เราได้กำหนดคอร์ดให้เป็นโน้ตซึ่งมีเซมิโคลอนจำนวนหนึ่งคั่นอยู่ ตัวอย่างเช่นลองเอา4-3-3คอร์ดเริ่มต้นที่C(สำหรับคนดนตรีนี่คือ V 7 chord ใน F major) Cเราเริ่มต้นที่ เรานับเพิ่มขึ้น 4 C#semitones: D, D#, E, ทราบต่อไปคือEและเรานับ 3 semitones Fขึ้นหลังจากที่: F#, G, ทราบต่อไปคือGและเรานับ 3 semitones G#ขึ้นหลังจากที่: A, Bb, C-E-G-Bbดังนั้นเราจะได้รับ เย้! แต่เดี๋ยวก่อน ... Bbเป็นกุญแจดำและมันก็พัง ... อย่างไรก็ตามถ้าเราเริ่มต้นGเราจะได้G-B-D-F! เย้!

อินพุต

อินพุตถูกกำหนดเป็นรายการของจำนวนเต็มในรูปแบบที่สมเหตุสมผล นี่แสดงถึงคอร์ดตามที่อธิบายไว้ข้างต้น

เอาท์พุต

ผลลัพธ์ควรเป็นรายการบันทึกย่อที่ฉันสามารถเริ่มใช้เพียงต้องใช้คีย์สีขาว นี่อาจเป็นสตริงของบันทึกย่อสูงสุด 7 รายการเนื่องจากชื่อคีย์ทั้งหมดจะเป็นอักขระหนึ่งตัว คุณจะต้องสามารถจัดการกับการมีผลผลิตว่างเปล่าเช่นกัน

กรณีทดสอบ

input -> output // comments
4 3 -> C F G // this is a major triad
3 4 -> D E A // this is a minor triad
4 3 3 -> G // this is the major-minor seventh chord
3 3 3 -> [empty output] // this is the diminished-diminished seventh chord. All of them use black keys
4 4 -> [empty output] // this is an augmented triad
3 3 -> B // this is a diminished triad
1 -> B E // this is just a minor second
11 -> C F // this is just a major seventh

รายละเอียดอื่น ๆ

  • ห้ามมีช่องโหว่มาตรฐาน
  • คุณอาจคิดว่าอินพุตมีจำนวนเต็มอย่างน้อยหนึ่งตัว
  • คุณอาจคิดว่าจำนวนเต็มทั้งหมดไม่เป็นลบและน้อยกว่า 12 (เพราะเปียโนทำซ้ำทุก ๆ 12 โน้ต)
  • ผลลัพธ์อาจอยู่ในลำดับใดก็ได้

เกณฑ์การชนะ

การส่งที่ถูกต้องสั้นที่สุด ณ วันที่ 15 เมษายนจะได้รับการยอมรับ


เราอาจสมมติว่า "ไม่เป็นลบและน้อยกว่า 12" - ควรจะไม่ "เป็นบวกและน้อยกว่าหรือเท่ากับ 12"
Jonathan Allan

@JonathanAllan พื้นฐานไม่มีความแตกต่าง; วิธีการของฉันอนุญาตให้ใช้กับ Perfect Unison แต่ไม่ใช่ Perfect Octave; ในทางกลับกันคุณ ในทางทฤษฎีข้อ จำกัด ของคุณอาจมีเหตุผลมากกว่า แต่ฉันคิดว่าฉันไม่ควรเปลี่ยนเพราะมีคำตอบอยู่แล้วและไม่เปลี่ยนความท้าทายพื้นฐาน
HyperNeutrino

คำตอบ:


3

เยลลี่ 25 ไบต์

236ḃ2ṙЀ7+\€Ṭ
+\ịþ¢Ạ€TịØA

ลองออนไลน์! หรือดูชุดทดสอบ

อย่างไร?

236ḃ2ṙЀ7+\€Ṭ - Link 1, white-note-offsets: no arguments
236ḃ2         - 236 in bijective base 2 [2, 2, 1, 2, 2, 1, 2] - semitones G->A, A->B ...
     ṙЀ7     - rotate left by, mapped over [1,2,3,4,5,6,7] - i.e. as above for each
                    starting white key (1st one A->B,B->C,...; 2nd B->C,C->D,...; etc)
         +\€  - reduce €ach with addition - i.e. absolute number of semitones: [[2,3,5,7,8,10,12],[1,3,5,6,8,10,12],[2,4,5,7,9,11,12],[2,3,5,7,9,10,12],[1,3,5,7,8,10,12],[2,4,6,7,9,11,12],[2,4,5,7,9,10,12]]
            Ṭ - untruth (vectorises) - make lists with 1s at those indexes: [[0,1,1,0,1,0,1,1,0,1,0,1],[1,0,1,0,1,1,0,1,0,1,0,1],[0,1,0,1,1,0,1,0,1,0,1,1],[0,1,1,0,1,0,1,0,1,1,0,1],[1,0,1,0,1,0,1,1,0,1,0,1],[0,1,0,1,0,1,1,0,1,0,1,1],[0,1,0,1,1,0,1,0,1,1,0,1]]

+\ịþ¢Ạ€TịØA - Main link: list of semitone gap integers (even negatives will work)
+\          - reduce by addition - gets the absolute semitone offsets needed
    ¢       - last link (1) as a nilad
   þ        - outer product with:
  ị         -     index into - 7 lists, each with 1s for white and 0s for black keys hit
                      note that indexing is modular and all the lists are length 12
                      so any integer is a valid absolute offset, not just 0-11 inclusive
     Ạ€     - all truthy for €ach - for each get a 1 if all keys are white ones, else 0
       T    - truthy indexes - get the valid starting white keys as numbers from 1 to 7
        ị   - index into:
         ØA -     the uppercase alphabet

6

MATL , 31 ไบต์

ขอบคุณJonathan Allanสำหรับการแก้ไข

'BAGFEDC'"GYs12X\110BQX@YSYsm?@

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย

รูปแบบ2 2 1 2 2 2 1ระบุช่วงเวลาระหว่างปุ่มสีขาวต่อเนื่องกัน โปรแกรมใช้การวนซ้ำที่ใช้การเลื่อนแบบวนกับรูปแบบพื้นฐานนี้เพื่อทดสอบแต่ละคีย์เป็นโน้ตต่ำสุดที่เป็นไปได้ของคอร์ดอินพุต สำหรับการเลื่อนแต่ละครั้งจะได้รับผลรวมสะสมของรูปแบบ ตัวอย่างเช่นสำหรับBศักยภาพโน้ตต่ำสุดรูปแบบที่ได้รับการขยับตัวไปและผลรวมสะสมของมันคือ1 2 2 1 2 2 21 3 5 6 8 10 12

ทีนี้เพื่อดูว่าสิ่งนี้สามารถรองรับ4 3 3คอร์ดได้หรือไม่เราคำนวณผลรวมสะสมของช่วงคอร์ดซึ่งก็คือ4 7 10; ลดผ่านโมดูโล 1 ที่ใช้พื้นฐาน 12 (ช่วงเวลา14จะให้2); และตรวจสอบว่าตัวเลขเหล่านั้นเป็นสมาชิกทั้งหมดของค่าที่อนุญาต1 3 5 6 8 10 12หรือไม่ นี่ไม่ใช่กรณีในตัวอย่างนี้ Bมันได้รับกรณีที่เราจะส่งออกจดหมาย

'BAGFEDC'จดหมายระหว่างกะวงจรและตัวอักษรที่ส่งออกจะถูกกำหนดโดยสตริง สิ่งนี้บ่งชี้ว่า'B'(ตัวอักษรตัวแรก) สอดคล้องกับการเปลี่ยนแปลงแบบวงกลมโดย1; 'A'(ตัวละครตัวที่สอง) สอดคล้องกับการเปลี่ยนแปลงแบบวงกลมโดย2เป็นต้น

'BAGFEDC'  % Push this string
"          % For each character from the string
  G        %   Push input array
  Ys       %   Cumulative sum
  12X\     %   1-based modulo 12, element-wise (1,12,13,14 respectively give 1,12,1,2)
  110BQ    %   Push 110, convert to binary, add 1 element-wise: gives [2 2 1 2 2 2 1]
  X@       %   Push current iteration index, starting at 1
  YS       %   Cyclic shift to the right by that amount
  Ys       %   Cumulative sum
  m        %   Ismember. Gives an array of true of false entries
  ?        %   If all true
    @      %     Push current character
           %   End (implicit)
           % End (implicit)
           % Display (implicit)

5

Mathematica, 110 ไบต์ (การเข้ารหัส ISO 8859-1)

±i_:=#&@@@Select["A#BC#D#EF#G#"~StringTake~{Mod[#,12,1]}&/@#&/@(Accumulate[i~Prepend~#]&/@Range@12),FreeQ@"#"]

นิยามฟังก์ชัน unary ±รับรายการจำนวนเต็มเป็นอินพุต (ไม่ จำกัด ขนาดหรือเครื่องหมายของจำนวนเต็มจริง ๆ ) และส่งกลับรายการของสตริงหนึ่งอักขระ ตัวอย่างเช่นผลตอบแทน±{3,4}{"A","D","E"}

"A#BC#D#EF#G#"~StringTake~{Mod[#,12,1]}&/@#เป็นฟังก์ชันที่เปลี่ยนรายการจำนวนเต็มเป็นชื่อบันทึกย่อที่สอดคล้องกันยกเว้นว่า#ย่อมาจากคีย์สีดำใด ๆ สิ่งนี้จะใช้กับแต่ละองค์ประกอบของAccumulate[i~Prepend~#]&/@Range@12ซึ่งสร้างรายการค่าบันทึกจากรายการอินพุตรายการของช่วงเวลาบันทึกย่อเริ่มต้นด้วยแต่ละบันทึกย่อที่เป็นไปได้ตั้งแต่ 1 ถึง 12 เรากรองรายการบันทึกย่อทั้งหมดที่มีการ"#"ใช้Select[...,FreeQ@"#"]แล้ว #&@@@กลับโน้ตตัวแรกในแต่ละรายการที่เหลือโดยใช้


ส่งดี!
HyperNeutrino

คำถาม: Mathematica ใช้ระบบ byte ของตัวเองหรือไม่? นี่คือ 110 ตัวอักษร แต่ใน UTF-8 คือ 111 ไบต์เนื่องจาก+/-สัญลักษณ์
HyperNeutrino

คุณสามารถปลดการมอบหมายอย่างสมบูรณ์และเพียงแค่ "ส่งคืนโดยปริยาย" ฟังก์ชั่น
wizzwizz4

@ wizzwizz4: ฉันพบว่าฉันต้องตั้งชื่อตัวแปรAccumulate[i~Prepend~#]&เพราะไม่เช่นนั้นจะมีการปะทะกันของคำสาป อย่าลังเลที่จะหาวิธีแก้ปัญหา!
Greg Martin

@HyperNeutrino: คุณพูดถูกว่า UTF-8 เป็นมาตรฐานการเข้ารหัส แต่ฟังก์ชัน Mathematica สามารถ (ปกติ) ในการเข้ารหัส ISO 8859-1 ได้เช่นกัน ฉันตั้งข้อสังเกตว่าในโพสต์
Greg Martin

3

Python 2, 159 155 ไบต์

(โพสต์สิ่งนี้หลังจากตรวจสอบให้แน่ใจว่ามีการส่งที่ถูกต้องซึ่งสั้นกว่าอันนี้)

import numpy
s='C.D.EF.G.A.B'
def k(y):return lambda x:s[(x+y)%12]
for i in range(12):
    if s[i]!='.'and'.'not in map(k(i),numpy.cumsum(input())):print s[i]

ค่อนข้างเป็นเพียงวิธีแก้ปัญหาเล็กน้อย อินพุตเป็นรายการของจำนวนเต็มและเอาต์พุตที่มีอักขระแต่ละตัวในแต่ละบรรทัด

-4 ไบต์โดยการลบตัวแปรที่ไม่จำเป็นออก


3

JavaScript (ES6), 72 71 68 ไบต์

a=>[..."C1D1EF1G1A1B"].filter((c,i,b)=>!+c>a.some(e=>+b[i+=e,i%12]))

วนซ้ำแต่ละคีย์ที่ละเว้นคีย์ดำจากนั้นตรวจสอบว่ายอดรวมของเซมิโคลอนไม่เคยปรากฏบนคีย์ดำ

แก้ไข: บันทึกแล้ว 3 ไบต์ขอบคุณ @Arnauld


4
การอ่าน ?! คุณแน่ใจหรือว่าคุณอยู่ในเว็บไซต์ที่ถูกต้อง? :-)
wizzwizz4
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.