Dychotomia Major-Minor

15

Biorąc pod uwagę listę akordów oznacz je jako „Major” lub „Minor”.

Wejście

Wejście będzie listą akordów, po jednej w wierszu, złożoną z 3 nut oddzielonych spacją. Każda nuta będzie się składać z nazwy nuty pisanej wielkimi literami ( A- G) i opcjonalnego przypadkowego ( #lub b). Akordy mogą być w dowolnej inwersji (tzn. Nuty mogą być w dowolnej kolejności).

Wynik

Jeśli akord jest major, wyślij „Major”. Jeśli akord jest niewielki, wypisz „Minor”. Jeśli akord nie jest ani większy ani mniejszy, wypisz pusty wiersz.

Przykład

Wejście

C E G
F Ab C
C Eb Gb
E G B
Db F Ab
Bb G D
D A Gb

Wynik

Major
Minor

Minor
Major
Minor
Major

Skrypty testowe

Podobnie jak w niektórych moich poprzednich pytaniach, po raz kolejny opracowałem skrypty testowe pierwotnie stworzone przez Joeya i Ventero, aby zapewnić kilka przypadków testowych dla tego pytania:

Stosowanie: ./test [your program and its arguments]

Nagrody

Każdy wpis, który mogę zweryfikować, który spełnia specyfikację, przechodzi testy i oczywiście miał pewne próby gry w golfa, otrzyma ode mnie opinię (więc proszę o podanie instrukcji użytkowania wraz z odpowiedzią). Najkrótsze rozwiązanie do końca 13.10.2012 zostanie zaakceptowane jako zwycięzca.

Trochę teorii

Dla tych z was, którzy nie znają teorii muzyki, oto wystarczająca ilość informacji, aby móc konkurować.

Akord główny lub podrzędny składa się z trzech nut oddzielonych określonym wzorem półtonów. Jeśli weźmiemy pod uwagę rdzeń (dolną nutę) akordu jako 0, to główny akord jest wzorem 0-4-7, a mniejszy akord jest wzorem 0-3-7. Sprawa jest jeszcze bardziej niezręczna z powodu faktu, że niektóre nuty są oddzielone półtonem, a niektóre tonem. Rozpiętość półtonów od Ab- G#jest następująca:

G#/Ab A A#/Bb B/Cb B#/C C#/Db D D#/Eb E/Fb E#/F F#/Gb G G#/Ab
  0   1   2    3     4    5   6   7    8     9    10  11  12

G#/Aboznacza, że G#jest to ta sama uwaga co Ab. Z tego wynika, że ​​akord Ab C Ebjest akordem głównym, a to Ab Cb Ebjest niewielkie.

Aby skomplikować sprawy dalej, akord Eb Cb Abjest uważany za tak samo jak Ab Cb Eb, Cb Eb Aba Cb Ab Ebi tak dalej. Każda z tych odmian jest wciąż niewielkim akordem.

Gareth
źródło
2
Myślę, że twój tester bash potrzebuje danych wejściowych i oczekiwanych odpowiedzi zamienionych.
flodel
@flodel Tak, masz rację. Przepraszam za to, poprawiłem to teraz. Muszę sprawdzić, czy skrypt testowy Powershell również nie ma tego samego problemu.
Gareth

Odpowiedzi:

3

GolfScript, 83 znaki

n%{' '%{1\{'A#BC D EF G'?+}/.}%$(+2/{~- 12%}%.(+.(+]$0=.$]10,7>?'MMaijnoorr

'>2%}%

To szybkie pierwsze rozwiązanie; Jestem pewien, że można dalej grać w golfa. Przechodzi pakiet testowy bash, po naprawieniu błędu wskazanego przez flodel w komentarzach.

Edycja 1: Zapisano 5 znaków w krótszym sposobie rozpoznawania kanonizowanych wzorów akordów głównych i mniejszych.

Edycja 2: Zapisano 2 dodatkowe znaki z bardziej kompaktowym kodowaniem wyjściowym inspirowanym rozwiązaniem grc. (Dzięki!) Jako efekt uboczny, kod wypisuje teraz dodatkową pustą linię po wyjściu, ale uprząż testowa wydaje się to akceptować, więc myślę, że jest OK. :)

Oto jak to działa:

  • Zewnętrzna pętla n%{ }%n*dzieli tylko dane wejściowe na linie, uruchamia kod w nawiasach klamrowych dla każdej linii i łączy wyniki z nowymi liniami.

  • ' '%dzieli każdą linię na tablicę notatek. Dla każdej z tych nut 1\{'A#BC D EF G'?+}/następnie konwertuje tę notatkę na liczbę półtonową, wyszukując każdy z jej znaków w ciągu 'A#BC D EF G'i sumując pozycje (które będą równe -1 dla każdego znaku nie znalezionego w ciągu, w tym w szczególności b). (Jestem pewien , że widziałem już tę sztuczkę.) Wreszcie. powiela każdy numer, tak, że na końcu pętli, np wejście F Ab Czostało przekształcone [9 9 0 0 4 4].

  • Następnie sortujemy nuty za pomocą $, przenosimy pierwszą nutę na koniec za pomocą (+i dzielimy tablicę na pary za pomocą 2/, aby teraz wyglądało np [[9 0] [0 4] [4 9]]. Jak . Następnie{~- 12%}% odwzorowuje każdą parę nut w jej różnicy modulo 12, zamieniając naszą przykładową tablicę [9 8 7].

  • Kolejny, .(+ tworzy kopię tablicy i obraca elementy w lewo o jedną pozycję. Robimy to dwa razy i zbieramy kopie w tablicę ], dzięki czemu nasz przykład wygląda teraz [[9 8 7] [8 7 9] [7 9 8]].

  • Następnie sortujemy tablicę za pomocą $i bierzemy pierwszy element - w tym przypadku [7 9 8]- za pomocą 0=. Następnie tworzymy kopię tej tablicy ( .), sortujemy ją ( $), zbieramy zarówno nieposortowaną, jak i nieposortowaną tablicę do innej tablicy tablic ( ]) i szukamy pierwszego wystąpienia tablicy[7 8 9] (zapisanej jako 10,7>zapisanie dwóch znaków ) w tym.

  • To daje nam albo 0(jeśli nieposortowana tablica była [7 8 9], a zatem akord jest główny), 1(jeśli nieposortowana tablica była permutacją [7 8 9], która, biorąc pod uwagę, że jej pierwszy element musi być najmniejszy, może być tylko [7 9 8], czyniąc akord mniejszym) lub -1(jeśli nawet posortowana tablica nie jest równa [7 8 9]).

  • Liczba ta jest następnie używana jako indeks początkowy w ciągu znaków "MMaijnoorr\n\n"(gdzie \ns są podawane jako rzeczywiste linie w kodzie), z którego bierzemy ten znak, a co drugi kolejny jako wynik. Jeśli indeks wynosi -1, zaczynamy od ostatniego znaku ciągu, który jest po prostu wierszem.

Ilmari Karonen
źródło
Ładne wyjaśnienie. Mam taką samą trudność, jaką zawsze mam z GolfScript - mogę wywoływać wiersz w celu przetestowania, echo "G# B# Eb" | ruby golfscript.rb ilmari.gsale jak uruchomić na nim skrypt testowy? Próbowałem, ./test ruby golfscript.rb ilmari.gsale nic z tego nie miało. (Już dałem ci +1, ponieważ to oczywiście działa, ale jestem po prostu ciekawy)
Gareth
1
@Gareth: Wygląda na to, że to błąd w skrypcie testowym bash - nie obsługuje wielu argumentów. Aby to naprawić, wymienić args="$@"się args=("$@")i got=$("$cmd" "$args")z got=$("$cmd" "${args[@]}"). (Lub po prostu wykonaj golfscript.rbplik wykonywalny i uruchom go jako ./test ./golfscript.rb chords.gs.)
Ilmari Karonen
4

Python, 160

f='A#BC D EF G3453543'.find
try:
 while 1:x,y,z=sorted(map(lambda x:f(x[0])+f(x[1:])+1,raw_input().split()));print'MMianjoorrr'[f(`y-x`+`z-y`)/14:-1:2]
except:0
grc
źródło