Étant donné une liste d'accords, étiquetez-les comme «majeurs» ou «mineurs».
Contribution
L'entrée sera une liste d'accords, un par ligne, composé de 3 notes séparées par un espace. Chaque note se composera du nom de la note en majuscule (A
- G
) et d'un accidentel ( #
ou b
) facultatif . Les accords peuvent être dans n'importe quelle inversion (c'est-à-dire que les notes peuvent être dans n'importe quel ordre).
Production
Si l'accord est majeur, sortez «Major». Si l'accord est mineur, sortez «Minor». Si l'accord n'est ni majeur ni mineur, sortez une ligne vierge.
Exemple
Contribution
C E G
F Ab C
C Eb Gb
E G B
Db F Ab
Bb G D
D A Gb
Production
Major
Minor
Minor
Major
Minor
Major
Scripts de test
Comme dans certaines de mes questions précédentes, j'ai une fois de plus massacré des scripts de test créés à l'origine par Joey et Ventero pour fournir des cas de test pour cette question:
Usage: ./test [your program and its arguments]
Récompenses
Chaque entrée dont je peux vérifier qu'elle répond aux spécifications, réussit les tests et a évidemment eu une tentative de golf recevra un vote positif de ma part (veuillez donc fournir des instructions d'utilisation avec votre réponse). La solution la plus courte d'ici la fin du 13/10/2012 sera acceptée comme gagnante.
Un peu de théorie
Pour ceux d'entre vous qui n'ont aucune connaissance de la théorie musicale, voici suffisamment d'informations pour pouvoir participer.
Un accord majeur ou mineur est composé de trois notes séparées par un motif spécifique de demi-tons. Si nous considérons la racine (note du bas) de l'accord comme étant 0, alors un accord majeur est le motif 0-4-7 et un accord mineur est le motif 0-3-7. Les choses sont rendues plus gênantes par le fait que certaines notes sont séparées par un demi-ton et d'autres par un ton différent. La répartition des demi-tons de Ab
- G#
est la suivante:
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#/Ab
signifie que c'est G#
la même note que Ab
. De cela, nous pouvons voir que l'accord Ab C Eb
est un accord majeur, et c'est Ab Cb Eb
mineur.
Pour compliquer encore les choses, l'accord Eb Cb Ab
est considéré comme le même que Ab Cb Eb
, Cb Eb Ab
et Cb Ab Eb
et ainsi de suite. Chacune de ces variations est encore un accord mineur.
Réponses:
GolfScript, 83 caractères
Ceci est une première solution rapide; Je suis sûr que cela peut être approfondi. Réussit la suite de tests bash, après avoir corrigé le bogue signalé par flodel dans les commentaires.
Modifier 1: 5 caractères enregistrés avec un moyen plus court de reconnaître les modèles d'accords majeurs et mineurs canonisés.
Édition 2: enregistrement de 2 caractères supplémentaires avec un encodage de sortie plus compact inspiré de la solution de grc. (Merci!) Comme effet secondaire, le code imprime maintenant une ligne vierge supplémentaire après la sortie, mais le faisceau de test semble accepter cela, donc je suppose que c'est OK. :)
Voici comment ça fonctionne:
La boucle externe
n%{ }%n*
divise simplement l'entrée en lignes, exécute le code à l'intérieur des accolades pour chaque ligne et joint les résultats avec des sauts de ligne.' '%
divise chaque ligne en un tableau de notes. Pour chacune de ces notes,1\{'A#BC D EF G'?+}/
convertit ensuite cette note en un demi-ton en recherchant chacun de ses caractères dans la chaîne'A#BC D EF G'
et en additionnant les positions (qui seront -1 pour tout caractère non trouvé dans la chaîne, y compris notammentb
). (Je suis sûr que j'ai déjà utilisé cette astuce auparavant.) Enfin, le.
double chaque numéro, de sorte qu'à la fin de la boucle, par exemple, l'entréeF Ab C
a été transformée en[9 9 0 0 4 4]
.Nous trions ensuite les notes avec
$
, déplaçons la première note à la fin avec(+
et divisons le tableau en paires avec2/
, de sorte qu'il ressemble maintenant, par exemple[[9 0] [0 4] [4 9]]
. Puis{~- 12%}%
mappe chaque paire de notes dans sa différence modulo 12, transformant notre exemple de tableau en[9 8 7]
.Ensuite,
.(+
fait une copie du tableau et fait pivoter ses éléments vers la gauche d'une position. Nous faisons cela deux fois et collectons les copies dans un tableau avec]
, de sorte que notre exemple ressemble maintenant[[9 8 7] [8 7 9] [7 9 8]]
.Nous trions ensuite ce tableau de tableaux avec
$
et prenons le premier élément - dans ce cas[7 9 8]
- avec0=
. Nous faisons ensuite une copie de ce tableau (.
), le trions ($
), collectons à la fois le tableau non trié et le tableau non trié dans un autre tableau de tableaux (]
), et recherchons la première occurrence du tableau[7 8 9]
(qui est écrite10,7>
pour enregistrer deux caractères ) en elle.Cela nous donne soit
0
(si le tableau non trié était[7 8 9]
, et donc l'accord est majeur),1
(si le tableau non trié était une permutation de[7 8 9]
, qui, étant donné que son premier élément doit être le plus petit, ne peut l'être que[7 9 8]
, ce qui rend l'accord mineur) ou-1
(si même le tableau trié n'est pas égal[7 8 9]
).Ce nombre est ensuite utilisé comme index de départ dans la chaîne
"MMaijnoorr\n\n"
(où le\n
s sont donnés en tant que sauts de ligne réels dans le code), dont nous prenons ce caractère et chaque seconde suivante comme sortie. Si l'index est -1, nous partons du dernier caractère de la chaîne, qui n'est qu'un saut de ligne.la source
echo "G# B# Eb" | ruby golfscript.rb ilmari.gs
mais comment exécuter le script de test dessus? J'ai essayé./test ruby golfscript.rb ilmari.gs
mais ça n'en avait pas. (Je vous ai déjà donné un +1 car cela fonctionne évidemment, mais je suis juste curieux)args="$@"
parargs=("$@")
etgot=$("$cmd" "$args")
pargot=$("$cmd" "${args[@]}")
. (Ou tout simplement rendregolfscript.rb
exécutable et l'exécuter comme./test ./golfscript.rb chords.gs
.)Python, 160
la source