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!

Okx
la source
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"]
DLosc
la source
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'

Barre
la source
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 (.

Neil
la source
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.

fergusq
la source
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.

ETHproductions
la source
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

Arnauld
la source
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
m-chrzan
la source
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!

roberto06
la source
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)

Chat d'affaires
la source
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.

Denis Ibaev
la source
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>
CraigR8806
la source
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)"]
Level River St
la source
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)]
RootTwo
la source
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.

Laikoni
la source
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.

Neil
la source
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
    ;
Titus
la source