Giúp tôi chơi Harmonica của tôi


8

Hôm qua, tôi đã mua một cây kèn kèn:

hòa âm của tôi Hình 1: Bản hòa âm.

Tuy nhiên, giấc mơ của tôi về việc có thể chơi những bản hòa tấu blues có hồn khiến mọi người cảm động và khiến một người đàn ông trưởng thành khóc nhanh chóng bị hai vấn đề:

  1. Bản hòa âm chỉ có thể chơi một số nốt nhất định;
  2. Tôi rất tệ khi chơi kèn harmonica.

Mặc dù tôi không có kỹ năng về hòa âm, nhưng vẫn có một số bài hát mà tôi có thể chơi trên đó. Tuy nhiên, không rõ ràng ngay lập tức nếu tôi có thể chơi một số bản nhạc trên bản hòa âm hay không. Đưa ra các nốt nhạc của một bản nhạc, viết một chương trình để xác định xem tôi có thể chơi nó trên bản hòa âm của mình hay không.

Như hình trên cho thấy, bản hòa âm của tôi có mười lỗ. Với mỗi lỗ, tôi có thể thở ra hoặc hít vào nó - lỗ mà tôi chọn, và liệu tôi hít vào hay thở ra vào nó sẽ thay đổi cao độ của âm thanh phát ra. Mỗi lỗ có một mức độ khác nhau khi thở ra và hít vào, nhưng có một số kết hợp dẫn đến cùng một lưu ý. Nhìn chung, kèn kèn của tôi có thể chơi 19 nốt khác nhau. Các nốt nhạc được trình bày trong ký hiệu khoa học âm nhạc - chữ cái đại diện cho nốt nhạc, và con số đại diện cho quãng tám của nó.

 Hole   Breathing   Note  
 1      Exhale      C4    
 1      Inhale      D4    
 2      Exhale      E4    
 2      Inhale      G4    
 3      Exhale      G4
 3      Inhale      B4
 4      Exhale      C5    
 4      Inhale      D5    
 5      Exhale      E5    
 5      Inhale      F5    
 6      Exhale      G5    
 6      Inhale      A5    
 7      Exhale      C6    
 7      Inhale      B5    
 8      Exhale      E6    
 8      Inhale      D6    
 9      Exhale      G6    
 9      Inhale      F6    
 10     Exhale      C7    
 10     Inhale      A6    

Ví dụ, nếu tôi thở ra ở lỗ 3, tôi sẽ nhận được một G4ghi chú. Nếu tôi hít vào lỗ 2, tôi cũng sẽ nhận được một G4ghi chú. Nếu tôi thở ra ở hố số 7, tôi sẽ nhận được a C6.

Khi tôi thở vào harmonica, ngoài việc thở ra hoặc hít vào, tôi cũng có thể chọn để thở mỏng hoặc rộng rãi . Hít thở mỏng chỉ khiến một lỗ phát ra âm thanh, trong khi thở rộng gây ra một lỗ và cả hai lỗ ở hai bên của lỗ đó phát ra âm thanh. Tôi không có kỹ năng đắp nổi để thổi vào hai lỗ - đó là một hoặc ba.

Ví dụ, nếu tôi thở ra một cách mỏng manh vào lỗ 4, chỉ có lỗ 4 sẽ phát ra âm thanh, vì vậy tôi sẽ có được âm thanh C5. Nếu tôi thở ra rộng rãi vào lỗ 4, lỗ 3, 4 và 5 sẽ phát ra âm thanh và tôi sẽ nhận được hợp âm G4, C5, E5. Nếu tôi hít vào lỗ 4, lỗ 3, 4 và 5 sẽ phát ra âm thanh nhưng thay vào đó họ sẽ chơi các nốt hít, dẫn đến hợp âm B4, D5, F5. Lưu ý rằng đối với các lỗ ở hai đầu, nếu tôi thở rộng vào chúng chỉ có hai lỗ sẽ phát ra (vì không có lỗ 0 hoặc lỗ 11).

Tuy nhiên, tôi không thể hít vào và thở ra cùng một lúc. Chẳng hạn, tôi có thể thở ra các lỗ 4, 5 và 6 để tạo ra các nốt C5, E5 và G5 cùng lúc, tạo thành một hợp âm. Tuy nhiên, tôi không thể hít vào và thở ra cùng một lúc, vì vậy tôi không thể chơi hợp âm C5, F5, A5 vì tôi phải thở ra bằng cách nào đó ở lỗ 4 và hít vào lỗ 5 và 6. Nếu Điều này vẫn chưa rõ ràng, chủ đề bình luận này có thể hữu ích.

Đầu vào là các ghi chú của âm nhạc. Các ghi chú được ký hiệu giống như cách chúng ở trên bảng và chúng được phân tách bằng dấu phẩy. Ghi chú được bọc trong dấu ngoặc nhọn đại diện cho một hợp âm. Ví dụ:

C4,D4,G4,{D5,F5,A5},B5

Điều này có nghĩa là, "C4, rồi D4, rồi G4, rồi D5, F5 và A5 cùng một lúc, rồi B5." Chương trình của bạn sẽ lấy một chuỗi ở định dạng này làm đầu vào và đầu ra Truenếu tôi có thể phát nhạc trên bản hòa âm của mình, hoặc Falsenếu không. Đối với đầu vào và đầu ra mẫu, ví dụ trên nên xuất ra True. Mặt khác, đầu {C5,F5,A5}vào sẽ xuất ra False.

Đây là mã golf, vì vậy mục ngắn nhất sẽ thắng.

Dưới đây là một số trường hợp thử nghiệm:

Đầu vào (AC Major scale):

C4,D4,E4,F4,G4,A4,B4,C5

Đầu ra:

False

(vì hòa âm không thể chơi F4 hoặc A4)

Đầu vào (2 thanh mở của Let It Go ):

E6,F6,A5,E6,F6,F6,E6,A5,F6,E6

Đầu ra:

True

Đầu vào:

{E6,G6,F6}

Đầu ra:

False

Đầu vào:

{G4,C5,E5},{F5,A5,B5}

Đầu ra:

True

Bạn có thể cho rằng các hợp âm sẽ đến theo thứ tự cao hơn đến cao hơn.


2
Bạn có phải thay thế thở ra và hít vào di chuyển từ ghi chú sang ghi chú?
COTO

1
@COTO Không. Giả sử tôi có khả năng thở vô hạn.
absinthe

các liên kết chủ đề bình luận tham khảo không làm việc cho tôi. cái này hiệu quả với tôi: meta.codegolf.stackexchange.com/a/2149/3348
ardew

Bạn có một bộ các trường hợp thử nghiệm chúng ta có thể sử dụng?
ardew

4
Tôi CÓ THỂ chơi bluesharp (Richter điều chỉnh giai điệu), nhưng tôi chỉ chơi blues trên nó. Lỗ 7 với C6 chuyển xuống B5 trông lạ nhưng đúng. Bạn có hai giải pháp: mua một bản hòa âm cao cấp hơn với cách điều chỉnh khác nhau hoặc học cách uốn cong các nốt (nếu bạn có thể uốn cong, bạn VẪN sẽ không thể chơi tất cả các nốt, nhưng bạn có thể chơi một bản nhạc hú để thể hiện sự thất vọng của mình .) Quy tắc về việc chỉ có thể chơi 1 hoặc 3 nốt là khá chính xác. Đây là một đại diện tốt đẹp của điều chỉnh Richter: en.wikipedia.org/wiki/Richter-tuned_harmonica . Phần trên các phím khác nhau cũng thú vị về mặt âm nhạc
Level River St

Câu trả lời:


2

Python - 218 209 189 ký tự

Tối thiểu:

def t(s):from re import sub as r;exec('l=bool([x for x in['+r('"{','("',r('}"','")',r(',','","','"'+s+'"')))+']if"".join(x)not in"C4E4G4C5E5G5C6E6G6C7|D4G4B4D5F5A5B5D6F6A6"])');return not l

Để dễ đọc:

def t(s):
    from re import sub as r
    exec('l=bool([x for x in'
         ' [' + r( '"{' , '("' ,
                  r( '}"' , '")' , 
                    r( ',' , '","' , '"' + s + '"' ))) +
         ']'
         ' if "".join(x) not in "C4E4G4C5E5G5C6E6G6C7|D4G4B4D5F5A5B5D6F6A6"])')
    return not l

Đưa ra một chuỗi được hình thành như trong mô tả vấn đề, ttrả về Truenếu chuỗi có thể phát trên giai điệu được mô tả và Falsenếu không.

Không có kiểm tra thứ tự của các nốt trong hợp âm. Trừ khi được nói khác, tôi tin rằng điều này là đủ vì điều đó không có trong báo cáo vấn đề và nó vượt qua tất cả các thử nghiệm đã cho trong:

assert not t("C4,D4,E4,F4,G4,A4,B4,C5")
assert t("E6,F6,A5,E6,F6,F6,E6,A5,F6,E6")
assert not t("{E6,G6,F6}")
assert t("{G4,C5,E5},{F5,A5,B5}")

Bạn có thể xóa rất nhiều khoảng trắng: ] if "".join(x) not-> ]if"".join(x)notTừ khóa có thể liền kề với chuỗi vì vậy "and"là chính xác.
Bakuriu

Mã golf đầu tiên ở đây vì vậy tôi nghĩ rằng tôi đã bỏ lỡ một cái gì đó. Cảm ơn!
Poik

1

Javascript - 245 243 ký tự

Giảm thiểu:

function p(s){function f(s){s=s.replace(/\W/g,'');l=s.length;return((l-6)*(l-2)?l-4?'':'C4E4 G6C7 D4G4 F6A6':'C4E4G4C5E5G5C6E6G6C7 D4G4B4D5F5A5B5D6F6A6').indexOf(s)<0?0:''}return s.replace(/{.*?}/g,f).split(',').map(f).join('')?'False':'True'}

Và mở rộng:

function p(s) {
    function f(s) {
        s = s.replace( /\W/g, '' );
        l = s.length;
        return ( (l-6)*(l-2) ? ( (l-4) ? '' : 'C4E4 G6C7 D4G4 F6A6' ) : 'C4E4G4C5E5G5C6E6G6C7 D4G4B4D5F5A5B5D6F6A6' ).
            indexOf( s ) < 0 ? 0 : ''
    }
    return s.replace( /{.*?}/g, f ).split( ',' ).map( f ).join( '' ) ? 'False' : 'True'
}

Hàm pchấp nhận một chuỗi làm đầu vào và trả về Truenếu chuỗi ghi chú / hợp âm có thể phát được, Falsenếu không. Nó trả về kết quả không xác định nếu đầu vào không hợp lệ về mặt cú pháp.

Nó cũng mạnh dạn giả định rằng các nốt hợp âm được nhập theo thứ tự lỗ tăng dần (chẳng hạn như trong ví dụ).

Số lượng ký tự có thể giảm 14 nếu hàm được phép trả về logic truefalsethay vì tương đương chuỗi của chúng.


1

JavaScript (ES6), 230

Chỉ là phiên bản viết lại của câu trả lời của @ COTO:

f=s=>{s=s.replace(/\W/g,'');l=s.length;return((l-6)*(l-2)?(l-4?'':'C4E4 G6C7 D4G4 F6A6'):'C4E4G4C5E5G5C6E6G6C7 D4G4B4D5F5A5B5D6F6A6').indexOf(s)<0?0:''};p=s=>{return s.replace(/{.*?}/g,f).split(',').map(f).join('')?'False':'True'}

Tôi sẽ đánh giá cao bất kỳ lời khuyên nào về việc chơi gôn này hơn nữa khi tôi bắt đầu học ES6! :-)


1

Scala 178

print(readLine./:(""){(a,c)=>if("..C4E4G4C5E5G5C6E6G6C7...D4G4B4D5F5A5B5D6F6A6...."sliding(6)flatMap(y=>Seq("{"+y.diff("..")+"}",y take 2))contains a+c)""else a+c diff ","}=="")

Ung dung:

print(
  readLine.foldLeft(""){(a,c)=>                             # loop through the input
    if("..C4E4G4C5E5G5C6E6G6C7...D4G4B4D5F5A5B5D6F6A6...."  # from the harmonica
      .sliding(6)                                     # take 6 at a time
      .flatMap(y=>Seq("{"+y.diff("..")+"}",y take 2)) # chords + single notes     
      .contains(a+c)) ""                              # clear matches
    else a+c diff ","                                 # drop commas
  }==""                                               # did everything match?
)

Lưu ý rằng đầu vào không đúng định dạng được xử lý kém - bất kỳ chuỗi nào được chấp nhận và nhiều chuỗi không đúng định dạng trả về đúng, ví dụ:

{C,7.D}.C

in đúng.


1

Nổi loạn - 188

t: func[s][trim/with s ","h: next split n:"C4E4G4C5E5G5C6E6G6C7..D4G4B4D5F5A5B5D6F6A6"2 forskip h 2[i

Ung dung:

t: func [s] [
    trim/with s ","
    h: next split n: "C4E4G4C5E5G5C6E6G6C7..D4G4B4D5F5A5B5D6F6A6" 2
    forskip h 2 [insert h '|]
    h: head h

    parse s [
        any [
            h | "{" x: copy c to "}" (unless find n c [c: n])
            :x c "}"
        ]
    ]
]

Ví dụ sử dụng (trong bảng điều khiển Rebol):

>> t "C4,D4,G4,{D5,F5,A5},B5"
== true

>> t "{C5,F5,A5}"
== false

>> t "C4,D4,E4,F4,G4,A4,B4,C5"
== false

>> t "E6,F6,A5,E6,F6,F6,E6,A5,F6,E6"
== true

>> t "{E6,G6,F6}"
== false

>> t "{G4,C5,E5},{F5,A5,B5}"
== true

Trong khi mã này sẽ bắt được tiếng vô nghĩa như thế này:

>> t "{C,7.D}.C"
== false

Tuy nhiên, nó sẽ cho phép những thứ như thế này thông qua:

>> t "C,4,D4"
== true

Bởi vì nó phân tích cú pháp của nó là "C4, D4".

Đây là phiên bản mã chặt chẽ hơn:

t: func [s] [
    h: next split n: "C4E4G4C5E5G5C6E6G6C7..D4G4B4D5F5A5B5D6F6A6" 2
    forskip h 2 [insert h '|]
    h: head h
    d: ["," | end]

    parse s [
      any [
            [
                h | "{" x: copy c to "}" (
                    unless all [
                        parse c [any [h d]]
                        find n trim/with copy c ","
                    ] [c: n]
                )
                :x c "}"
            ]
            d
      ]
    ]
]

Golf này giảm xuống còn 228 ký tự và bây giờ trở lại false...

>> t "C,4,D4"
== false

1

JavaScript ES6, 211 209 190 ký tự

Tôi biết điều này có thể được chơi golf hơn nữa. Tôi sẽ cố gắng làm như vậy trong một vài giờ;

Chạy mã này trong Bảng điều khiển web mới nhất của Firefox, bạn sẽ nhận được một phương thức có tên Cmà sau đó bạn có thể gọi như thế C("{G4,C5,E5},{F5,A5,B5}")và nó sẽ trả về Truehoặc Falsetheo đó.

C=n=>(s='D4G4D5F5A5B5D6F6A6,C4E4G4C5E5G5C6E6G6C7',n.split(/[,}{]/g).some(a=>a&&!~s.search(a))||(m=n.match(/{[^}]+/g))&&m.some(a=>a.length!=9|!~s.search(a.replace(/{|,/g,"")))?'False':'True')

Tôi giả sử một đầu vào hợp lệ cú pháp.

EDIT : Đơn giản hóa regex và kiểm tra độ dài.

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.