Historia [co nie jest prawdą]
Fortepian jest skonfigurowany w następujący sposób:
Jednak na moim pianinie wszystkie czarne klawisze są zepsute!
Nadal chcę jednak móc grać akordy na moim złamanym pianinie.
W muzyce akord to grupa nut granych razem. Aby umożliwić wprowadzanie akordów, najpierw zdefiniuję, czym jest półton.
Co to jest półton?
Półton to najmniejsza odległość w muzyce zachodniej. Jeśli spojrzysz na górną część fortepianu, zobaczysz, że zazwyczaj możesz przejść z czarnego klawisza na biały klawisz lub odwrotnie; Jednak między B
i C
a E
i F
nie ma czarny klucz.
Co to jest akord?
Na potrzeby tego wyzwania definiujemy akord jako wiązkę nut z pewną liczbą półtonów między nimi. Na przykład weźmy 4-3-3
akord od początku C
(dla muzyków jest to akord V 7 F-dur). Zaczynamy o C
. Liczymy się 4 półtony: C#
, D
, D#
, E
. Kolejna uwaga to E
i liczymy 3 półtony w górę po tym: F
, F#
, G
. Kolejna uwaga to G
i liczymy 3 półtony w górę po tym: G#
, A
, Bb
. Więc rozumiemy C-E-G-Bb
. Tak! Ale czekaj ... Bb
to czarny klucz, a te są zepsute ... Jednak jeśli zaczniemy G
, dostaniemy G-B-D-F
! Tak!
Wejście
Dane wejściowe podano jako listę liczb całkowitych w dowolnym rozsądnym formacie. To reprezentuje akord, jak opisano powyżej.
Wynik
Wyjście powinno być listą notatek, na których mogę zacząć używać tylko białych klawiszy. Może to być również ciąg wszystkich maksymalnie 7 nut, ponieważ wszystkie nazwy kluczy będą jednym znakiem. Musisz być w stanie poradzić sobie z pustym wyjściem.
Przypadki testowe
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
Inne specyfikacje
- Standardowe luki zabronione
- Możesz założyć, że wejście ma co najmniej jedną liczbę całkowitą
- Możesz założyć, że wszystkie liczby całkowite są nieujemne i mniejsze niż 12 (ponieważ fortepian powtarza się co 12 nut)
- Dane wyjściowe mogą być w dowolnej kolejności
Zwycięskie kryteria
Najkrótsze ważne zgłoszenie do 15 kwietnia zostanie zaakceptowane.
Odpowiedzi:
Galaretka , 25 bajtów
Wypróbuj online! lub zobacz pakiet testowy
W jaki sposób?
źródło
MATL , 31 bajtów
Dzięki Jonathanowi Allanowi za korektę.
Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .
Wyjaśnienie
Wzór
2 2 1 2 2 2 1
określa odstępy między kolejnymi białymi klawiszami. Program wykorzystuje pętlę, która stosuje wszystkie cykliczne przesunięcia do tego podstawowego wzorca, w celu przetestowania każdego klawisza jako potencjalnie najniższej nuty akordu wejściowego. Dla każdej zmiany uzyskiwana jest skumulowana suma wzoru. Na przykład dlaB
potencjalnie najniższej nuty wzorzec został przesunięty do,1 2 2 1 2 2 2
a jego łączna suma to1 3 5 6 8 10 12
.Teraz, aby sprawdzić, czy może to obsługiwać
4 3 3
akord, obliczamy skumulowaną sumę interwałów akordu, która jest4 7 10
; zredukuj to za pomocą modulo 12 opartego na 1 (interwał14
dałby2
); i sprawdź, czy wszystkie te liczby są członkami dozwolonych wartości1 3 5 6 8 10 12
. W tym przykładzie tak nie jest. Gdyby tak było, wysłalibyśmy listB
.Zależność między przesunięciami cyklicznymi a literami wyjściowymi jest zdefiniowana przez ciąg
'BAGFEDC'
. Oznacza to, że'B'
(pierwszy znak) odpowiada cyklicznemu przesunięciu o1
;'A'
(drugi znak) odpowiada cyklicznemu przesunięciu przez2
itp.źródło
Mathematica, 110 bajtów (kodowanie ISO 8859-1)
Definiuje jednoargumentową funkcję,
±
przyjmującą listę liczb całkowitych jako dane wejściowe (w rzeczywistości nie ma ograniczeń co do rozmiaru lub znaków liczb całkowitych) i zwraca listę ciągów jednoznakowych. Na przykład±{3,4}
zwraca{"A","D","E"}
."A#BC#D#EF#G#"~StringTake~{Mod[#,12,1]}&/@#
to funkcja, która zamienia listę liczb całkowitych w odpowiadające im nazwy nut, z wyjątkiem tego, że#
oznacza dowolny czarny klawisz. Odnosi się to do każdego elementuAccumulate[i~Prepend~#]&/@Range@12
, który tworzy listę wartości nut z listy wejściowej listy przedziałów notatek, zaczynając od każdej możliwej nuty od 1 do 12. Odfiltrowujemy wszystkie takie listy nazw notatek, które zawierają"#"
użycieSelect[...,FreeQ@"#"]
, a następnie zwróć pierwszą notatkę z każdej pozostałej listy za pomocą#&@@@
.źródło
+/-
symbolu.Accumulate[i~Prepend~#]&
ponieważ w przeciwnym razie doszłoby do starcia curry. Znajdź jednak obejście!Python 2,
159155 bajtów(Opublikowanie tego po upewnieniu się, że istnieje poprawne zgłoszenie, które jest krótsze od tego)
Prawie tylko trywialne rozwiązanie. Wejścia jako lista liczb całkowitych i wyjścia z każdym znakiem w osobnym wierszu.
-4 bajty przez usunięcie niepotrzebnej zmiennej
źródło
JavaScript (ES6),
727168 bajtówPętle przechodzą przez każdy klawisz, pomijając czarne klawisze, a następnie sprawdzają, czy skumulowana suma półtonów nigdy nie wyląduje na czarnym klawiszu.
Edycja: Zapisano 3 bajty dzięki @Arnauld.
źródło