Faire des boîtes à musique


23

Votre tâche consiste à prendre une séquence de caractères (la musique) en entrée (dans une fonction ou un programme) et à imprimer (ou renvoyer) la musique telle qu'elle apparaîtrait dans une boîte à musique.

Vous ne recevrez que les caractères ABCDEFG.()en entrée et l'entrée ne sera jamais vide. Vous pouvez également recevoir les lettres en minuscules, si vous le souhaitez.

Ceci est une boîte à musique vide, de longueur 3:

.......
.......
.......

Comme vous pouvez le voir, les lignes sont de 7 caractères, et comme la longueur de la boîte à musique est de 3, nous avons 3 lignes. Il n'y en a que .ici, car la boîte à musique est vide. Mettons de la musique dedans!

Tout d'abord, nous créons la boîte à musique. Dans cet exemple, l'entrée sera CDAG.DAG.

La longueur CDAG.DAGest de 8, nous avons donc besoin d'une boîte à musique de longueur 8:

.......
.......
.......
.......
.......
.......
.......
.......

Ensuite, nous lisons l'entrée, un caractère à la fois, et plaçons un Oà sa position respective.

Le premier caractère est C, et l'emplacement de chaque note est équivalent à cela (j'ai ajouté des espaces pour plus de clarté):

 A B C D E F G
 . . . . . . .
 . . . . . . .
 (and so on)

Si le caractère saisi est un ., alors nous imprimons simplement une ligne vide.......

Donc, ce Cserait le 3ème personnage. Mettons-le dans notre boîte à musique en haut:

..O....
.......
.......
.......
.......
.......
.......
.......

Nous répéterons ce processus pour tous les autres caractères (le texte entre parenthèses est juste pour vous montrer la note, vous ne devriez pas le sortir):

..O.... (C)
...O... (D)
O...... (A)
......O (G)
....... (.)
...O... (D)
O...... (A)
......O (G)

En raison du fonctionnement des boîtes à musique, si nous utilisons un caractère autre que O, .et <insert newline here>, comme un espace, dans notre sortie, il ne jouera pas la bonne musique!

Ceci est un accord:

(ACE)

Cet accord nous demande de jouer les notes A, Cet Een même temps. Il n'y aura jamais de pause (ie a .) dans un accord.

Voici comment il serait écrit:

O.O.O...

Et voici comment cela pourrait apparaître dans la musique: B(ACE)D

Vous ne recevrez jamais d'accord dans un accord, c'est-à-dire que ce ne sera pas valide: (AB(CD)EF)ou ceci A(B()):, et l'accord ne sera pas vide, c'est-à-dire que ce ne sera pas valide:A()B

Vous ne recevrez jamais une entrée non valide.

Exemples:

B(ACE)D

.O.....
O.O.O..
...O...

B

.O.....

GGABC

......O
......O
O......
.O.....
..O....

...

.......
.......
.......

A..F.C(DA).

O......
.......
.......
.....O.
.......
..O....
O..O...
.......

.(ABCDEF)

.......
OOOOOO.

Les espaces de fin / de début sur la sortie sont autorisés.

Comme il s'agit de , le code le plus court gagne!


une chaîne musicale peut-elle contenir ()deux fois (par exemple AB(CD)E(FG):) ??
M. Xcoder

@ Mr.Xcoder Oui, c'est possible.
Okx

La sortie peut-elle être une liste / un tableau de caractères?
Rod

@Rod sûr, selon les normes
PPCG

Sommes-nous assurés de ne pas obtenir deux de la même note dans le même accord?
Business Cat

Réponses:


0

Pip , 29 octets

28 octets de code, +1 pour l' -lindicateur.

'.X7RA_'OMz@?a@`\(\w+.|.`@XL

Prend l'entrée en minuscules comme argument de ligne de commande. Essayez-le en ligne!

Explication

                              a is 1st cmdline arg; XL is `[a-z]`; z is lowercase alphabet
             a@`\(\w+.|.`     List of all matches in a of this regex:
                               Either a ( followed by letters followed by another
                               character (i.e. the closing paren), or any one character
                         @XL  For each of those matches, a list of all matches of this
                               regex (effectively, split the match into a list of
                               characters and keep only the lowercase letters)
          z@?                 Find index of each letter in the lowercase alphabet
         M                    To that list of lists of indices, map this function:
'.X7                           Take a string of 7 periods
    RA_                        and replace the characters at all indices in the argument
       'O                      with O
                              Finally, autoprint the resulting list, with each item on
                              its own line (-l flag)

Voici un exemple de la façon dont une entrée est transformée:

"b.(ceg)"
["b" "." "(ceg)"]
[["b"] [] ["c" "e" "g"]]
[[1] [] [2 4 6]]
[".O....." "......." "..O.O.O"]

6

Python 2 , 95 94 octets

-1 octet grâce à Value Ink

x=1
for i in input():
 if x:o=['.']*7
 if'@'<i:o[ord(i)-65]='O'
 if'*'>i:x=i>'('
 if x:print o

Essayez-le en ligne! ou Essayez tous les cas de test

Explication

'@'<iest de vérifier s'il is'agit d'une lettre, en remplaçant le .par Osur la bonne position.
'*'>iest de vérifier si iest une parenthèse, si elle est x=i>'('va mettre 0sur xpour empêcher l'impression / compensation de o, quand i==')', il sera mis 1sur xréactivant l'impression / compensation de o.
Quand i=='.'rien ne sera changé et '.......'sera imprimé.
L'ordre de caractère est donné par leur code ASCII, où'('<')'<'*'<'.'<'@'<'A'


oh j'ai raté ce commentaire. nvm.
quintopie

Fossé de la virgule: ['.']*7. Peut-être que c'est une trace de quand vous utilisiez un tuple, ce qui nécessiterait la virgule. De plus, je peux me tromper, mais cela semble produire un tableau ['O', '.', '.', '.', '.', '.', '.']par ligne, et je ne sais pas si cela est autorisé?
Value Ink

@ValueInk yep, OP autorisé
Rod

Vous avez mentionné le changement d'octet et changé votre lien TIO mais le code répertorié sur votre message est toujours le même: V
Value Ink

1
@ValueInk ¯ \ _ (ツ) _ / ¯
Rod

4

Lot, 209 octets

@set s=%1
@set p=)
@for %%n in (a b c d e f g)do @set %%n=.
:g
@if %s:~,1% lss @ (set "p=%s:~,1%")else set %s:~,1%=O
@set s=%s:~1%
@if %p%==( goto g
@echo %a%%b%%c%%d%%e%%f%%g%
@if not "%s%"=="" %0 %s%

Fonctionne en accumulant des lettres et en sortant la ligne si le dernier symbole vu n'était pas a (.


4

Röda , 97 78 76 octets

{search`\(\w+\)|.`|{|c|seq 65,71|{|l|["O"]if[chr(l)in c]else["."]}_;["
"]}_}

Essayez-le en ligne!

C'est une fonction anonyme qui lit l'entrée du flux. Utilisez comme ceci: main { f={...}; push("ABCD") | f() }. Il utilise l'expression régulière de la réponse d'ETHproductions.

Non golfé:

{
    search(`\(\w+\)|.`) | for chord do
        seq(ord("A"), ord("G")) | for note do
            if [ chr(note) in chord ] do
                push("O")
            else
                push(".")
            done
        done
        push("\n")
    done
}

Réponse précédente:

f s{(s/"(?=([^()]*(\\([^()]*\\))?)*$)")|{|c|seq 65,71|{|l|["O"]if[chr(l)in c]else["."]}_;["
"]}_}

Essayez-le en ligne!

Il fonctionne en divisant la chaîne donnée aux endroits où la chaîne suivante ne contient que des parenthèses correspondantes. Ensuite, pour chaque accord, il parcourt les notes possibles et imprime Osi la note est membre de l'accord ou .non.


4

JavaScript (ES6), 86 85 76 octets

9 octets enregistrés grâce à @Neil

let f =
s=>s.replace(r=/\(\w+\)|./g,x=>`ABCDEFG
`.replace(r,c=>x.match(c)?"O":"."))
<input oninput="if(/^([A-G.]|\([A-G]+\))+$/.test(value))O.textContent=f(value)"><br>
<pre id=O></pre>

Explication

Tout d'abord, nous faisons correspondre ce qui formera chaque ligne de la sortie: les accords et les caractères qui ne font pas partie d'un accord. Ensuite, pour chaque ligne, nous prenons la chaîne ABCDEFG\net remplaçons chaque caractère non nouveau de ligne par un Osi la ligne le contient et un .autre.


Si une nouvelle ligne de fin est acceptable, vous pouvez économiser 8 octets à l'aide de s=>s.replace(r=/\(\w+\)|./g,x=>`ABCDEFG\n`.replace(r,c=>x.match(c)?"O":".")).
Neil

@Neil Wow, c'est incroyable :-)
ETHproductions

Huh, maintenant que je le mesure à nouveau, ça devrait être une économie de 10 octets ...
Neil

Peut- \)être .?
l4m2

2

JavaScript (ES6), 118 116 114 octets

f=([c,...t],s)=>c?((s?0:x=[...'.......'],c='ABCDEFG)('.indexOf(c))>6?c-7:(x[c]='O',s))?f(t,1):x.join``+`
`+f(t):''

Cas de test


2

Rubis, 78 75 71 octets

->x{x.scan(/\(\w+\)|./).map{|x|l=?.*7
x.bytes{|x|x>47?l[x-65]=?O:1};l}}

Renvoie un tableau de chaînes.

Non golfé + explication

def boxes string
  string.scan(/\(\w+\)|./)    # Split the string into an array of chords.
  .map do |chord|             # Replace each chord with...
    line = '.' * 7            # a line, where by default each character is a '.',
    chord.bytes do |note|     # but for each note in the chord...
      if note > '.'.ord       # (if it is in fact a note and not a dot or paren)
        line[note-65] = 'O'   # replace the corresponding dot with an 'O'.
      end
    end
    line               
  end
end

Essayez x.gsub(...){l=?.*7;$&.bytes{...};l+$/}(permutez scanavec gsub, supprimez mapet ignorez le premier |x|car vous pouvez utiliser $&pour accéder à la dernière correspondance d'expressions régulières) pour enregistrer 3 octets et renvoyer une chaîne multiligne à la place. (Correspond également $/à une nouvelle ligne par défaut.)
Value Ink

1

PHP, 171 octets

preg_match_all('#[A-G\.]|\([A-G]+\)#',$argv[1],$m);foreach($m[0]as$l){if($l=='.')echo".......";else foreach([A,B,C,D,E,F,G]as$a)echo strpos($l,$a)!==false?O:'.';echo"\n";}

Panne :

preg_match_all('#[A-G\.]|\([A-G]+\)#',$argv[1],$m); // Matches either one character in the range [A-G.] OR multiple [A-G] characters between parentheses
foreach($m[0]as$l)                                  // For each match :
    if($l=='.')                                     //   If no note is played
        echo".......";                              //     Echo empty music line
    else                                            //   Else
        foreach([A,B,C,D,E,F,G]as$a)                //     For each note in the [A-G] range
            echo strpos($l,$a)!==false?O:'.';       //       Echo O i the note is played, . if not
    echo"\n";                                       //  Echo new line
}

Essayez-le ici!


1

Rétine , 120 octets

O`(?<=\([^)]*)[^)]
T`L.`d
(?<=\([^)]*)\d
$*x 
\)
m¶
+`\b(x+) \1(x+) m
$1 m$2 
 m?x

T`x m(`.\O_
\d
$*.O¶
¶
6$*.¶
%7>`.

Je suis sûr qu'il y a de la place pour le golf, mais cela fonctionne maintenant, alors j'essaierai de le jouer plus tard.

Essayez-le en ligne!

Comment ça marche

Fondamentalement, le programme fonctionne en changeant chaque caractère en un nombre, puis en affectant un Oà cette position sur une ligne. Il correspond ABCDEFG.à 01234569.

Pour générer les lignes de notes simples, tout ce qui doit être fait est de mettre un Oaprès le nombre correspondant de .s, puis de remplir la ligne de 7 caractères.

Cependant, les accords sont un peu plus difficiles à faire. Un processus similaire est utilisé, mais les nombres doivent être traduits en incréments, c'est-à-dire que la première note de l'accord est (peu importe), la seconde est X positions après la première, la troisième est Y positions après cela, etc.

Code

O`(?<=\([^)]*)[^)]

Commencez par trier tous les caractères dans les accords.

T`L.`d

Effectuer la translittération (mappage) des lettres aux chiffres.

(?<=\([^)]*)\d
$*x 

Remplacez tous les chiffres entre parenthèses par une représentation unaire (à l'aide de xs), suivie d'un espace.

\)
m¶

Remplacez tous les crochets de fermeture par msuivi d'une nouvelle ligne. Le msera utilisé comme marqueur de tri pour la boucle à venir:

+`\b(x+) \1(x+) m
$1 m$2 

Il s'agit d'une étape de remplacement qui boucle jusqu'à ce qu'elle ne puisse plus remplacer. Il prend les deux dernières séquences de xs avant un m, et soustrait la première de la seconde, déplaçant l' marrière. Le marqueur mest nécessaire car il doit effectuer cette opération de droite à gauche.

 m?x

Retirez le premier xde chaque séquence, sauf le premier.

T`x m(`.\O_

Transliterate en remplaçant xpar ., espace avec O, et en supprimant met (.

À ce stade, toutes les lignes des accords ont été créées. Maintenant, les lignes de note unique doivent être créées.

\d
$*.O¶

Remplacez chaque chiffre par autant de .s, suivi d'un Oet d'une nouvelle ligne.

¶
6$*.¶
%7>`.

Remplissez chaque ligne à la longueur 7 en ajoutant .s à droite. Cela fonctionne en ajoutant 6 .s à la fin de chaque ligne (chaque ligne aura au moins 1 autre caractère), puis en remplaçant chaque caractère après les 7 premiers de chaque ligne par rien. (Depuis les .cartes à 9, le Osera découpé sur ces lignes)


1

Perl, 87 71 45 + 2 ( -nlindicateur) = 47 octets

#!/usr/bin/env perl -nl
use v5.10;
say map$&=~/$_/i?O:".",a..g while/\(\w+\)|./g

En utilisant:

perl -nlE 'say map$&=~/$_/i?O:".",a..g while/\(\w+\)|./g' <<< "A..F.C(DA)."

Essayez-le sur Ideone.


0

Perl 5-78 + 1 (drapeau) + 2 (devis d'entrée) = 81 octets

for(;/(\([a-g]+\)|[a-g\.])/g;){$i=$1;print$i=~/$_/?'o':'.'for(a..g);print"\n"}

Peut être exécuté comme suit:

perl -n <name of file holding script> <<< <input in quotations>

Ne pensez-vous pas que l'entrée entre guillemets compterait comme 2 octets supplémentaires? Je peux me tromper, car il peut y avoir un méta-consensus sur ce point, autrement.
Okx

@Okx a mis à jour mon bytecount. Je ne savais pas si cela y était ajouté, encore un peu nouveau ici :)
CraigR8806

0

Rubis, 68 octets

->s{w=?.*m=7
s.bytes{|i|i>64?w[i-65]=?O:m=i!=40;m&&(puts w;w=?.*7)}}

L'idée est de modifier la chaîne .......chaque fois que nous trouvons une lettre, puis de la sortir et de la réinitialiser, mais uniquement lorsque nous sommes hors des crochets. (désactive la sortie. )et les .deux commutent / laissent la sortie activée, mais cette dernière est sans conséquence car elle ne sera jamais trouvée à l'intérieur d'un support.

Non testé dans le programme de test

f=->s{w=?.*m=7              #set m to a truthy value (7) and w to seven .'s
  s.bytes{|i|               #for each byte in the string
    i>64?w[i-65]=?O:m=i!=40 #if a letter, modify the appropriate character of w ELSE set m to false if inside brackets, true otherwise.
    m&&(puts w;w=?.*7)      #if m is true, output the contents of w and reset to seven .'s
  }
}

p 1
f["B(ACE)D"]
p 2
f["B"]
p 3
f["GGABC"]
p 4
f["A..F.C(DA)."]
p 5
f[".(ABCDEF)"]

0

Python 3, 94 octets

Une fonction anonyme

import re
lambda s:[''.join('.O'[c in x]for c in'ABCDEFG')for x in re.findall(r'\(\w+\)|.',s)]

0

Haskell , 101 octets

c#s|elem c s=c|1<3='.'
s?r=map(#s)"ABCDEFG":p r
p('(':r)|(x,_:t)<-span(')'<)r=x?t
p(x:r)=[x]?r
p e=[]

Essayez-le en ligne! Usage:p "AB.(CA)D" . Renvoie une liste de chaînes.

Explication:

La fonction previent sur la chaîne. S'il trouve une parenthèse ouvrante, '('puis (x,_:t)<-span(')'<)rpartitionne la chaîne restante ren chaînes xavant l'occurrence de la parenthèse fermante ')'et taprès. Sinon, le caractère actuel xest transformé en chaîne [x]. Dans les deux cas, la fonction ?est appelée avec la chaîne de notes actuelle et la chaîne restante. ?mappe la fonction #sur la chaîne "ABCDEFG", où #remplace tous les caractères qui ne sont pas dans la chaîne de notes actuelle par '.'. La ligne de boîte à musique résultante est ajoutée à l'appel récursif de psur la liste de repos r.


0

Retina 0.8.2 , 52 octets

\(\w+\)|.
abcdefg$&¶
+`([a-g])(.*)\1
O$2
T`().l`___.

Essayez-le en ligne! Prend l'entrée en minuscules. Explication:

\(\w+\)|.
abcdefg$&¶

Divisez la musique en accords ou en notes et commencez à créer la sortie en ajoutant la liste des équivalents de notes.

+`([a-g])(.*)\1
O$2

Pour chaque note de chaque accord, changez la sortie en an Oet supprimez la note de l'accord.

T`().l`___.

Supprimez toute la musique désormais superflue et changez toutes les notes sans correspondance en vides.


0

PHP, 93 octets

for($s=$t="
.......";$c=ord($argn[$i++]);$d||$s=$t.!print$s)$c<65?$c-46&&$d=~$c&1:$s[$c&7]=O;

Exécuter en tant que pipe avec -nRou l' essayer en ligne .

panne

for($s=$t="\n.......";      // init
    $c=ord($argn[$i++]);    // loop through characters
    $d||                        // 2. if chord flag is unset
        $s=$t.!print$s)             // then print and reset chord
    $c<65                       // 1. if not note
        ?$c-46                      // and not dot
            &&$d=~$c&1              // then set or clear chord flag
        :$s[$c&7]=O             // else set note in chord
    ;
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.