Trouver la syncope

33

Étant donné l'entrée d'une chaîne composée entièrement de qs représentant des noires et de 8 quarts e, sortez les indices des noires qui sont syncopés.

La syncopation est complexe, mais pour les besoins de ce défi, notre définition de "syncopé" sera très simple: un quart de note qui commence sur "décalé", c’est-à-dire que les temps comptés sont comptés comme "et" dans n / 4 temps.

Cela peut également être défini comme toute note de quart précédée d'un nombre impair de croche. Par exemple, les notes marquées avec *ci-dessous sont considérées comme syncopées et leurs indices sont également affichés:

eqqeqqeqqe
 **    **
 12    78
Output: 1 2 7 8

L'entrée consistera toujours en un nombre entier de mesures en 4/4 de temps (une note de quart correspond à un quart de mesure et une croche à un huitième de mesure). (L'entrée ne sera jamais non plus vide.) La sortie peut être une chaîne unique avec des éléments séparés par un délimiteur ne contenant pas de chiffres ou un tableau / liste / etc. La sortie peut être basée sur 1 (le premier index est 1 au lieu de 0) si vous le souhaitez, et elle peut également figurer dans n’importe quelle base numérique (unaire, décimale, etc.).

Puisqu'il s'agit de , le code le plus court en octets gagne.

Cas de test:

In                        Out
-----------------------------------------------
eqqqe                     1 2 3
qeqeq                     2
qqqeqqeeeeqeqeqeqqeqqeqq  4 5 10 14 19 20
eeeeeqeeqeeqqqqeqeqeeqe   5 8 11 12 13 14 18 21
qqqq                      <none>
eeeeeeee                  <none>
Poignée de porte
la source
1
La sortie peut-elle être basée sur 1?
Luis Mendo
1
Pourriez-vous faire un exemple concret pour montrer comment fonctionnent les indices?
Peter Taylor
1
@ LuisMendo Bien sûr, si cela raccourcit votre code.
Poignée de porte
@PeterTaylor D'accord, est-ce que tu pensais à quelque chose comme ça?
Poignée de porte
L'entrée peut-elle être une chaîne comprenant les guillemets? 'eqqqe'au lieu deeqqqe
Luis Mendo

Réponses:

12

Gelée , 12 à 9 octets

=“e”µ<^\O

En tant que programme, le code ci-dessus nécessite des guillemets autour de l'entrée. Comme cela n'est pas autorisé, il s'agit d'une soumission de fonction. La sortie est basée sur 1. Essayez-le en ligne!

Comment ça marche

=“e”µ<^\O    Monadic link. Argument: s (string)

=“e”         Check each character for equality with 'e'. Yields a Boolean array.
    µ        Start a new, monadic chain.
      ^\     Compute the array of partial reductions by XOR, i. e., the parities
             of all prefixes of the Boolean array.
     <       Check if the Booleans are strictly smaller than the parities.
             A truthy outcome indicates an off-beat quarter note.
        O    Yield all indices of 1's.

Mise à jour

Le code ci-dessus ne fonctionne plus dans la dernière version de Jelly, car nous avons besoin d'un caractère e , mais “e”donne une chaîne. Une fixation qui enregistre un octet, pour un total de 8 octets .

=”eµ<^\O

Cela fonctionne comme un programme complet. Essayez-le en ligne!

Dennis
la source
7

Ruby, 46 ans

i=e=0
gets.bytes{|n|e^=n
e&4|n>114&&p(i)
i+=1}

Entrée dans stdin. Sortie sur la sortie standard, séparés par une nouvelle ligne.

Commenté

i=e=0               #i keeps index, e keeps track of 8ths.
gets.bytes{|n|      #iterate through bytes in the input
e^=n                #xor e with input. We're interested in the 4's bit, which is only affected by ascii e, not ascii q
e&4|n>114&&p(i)     #e&4 evaluates to 4 or 0. OR with n and if the value is greater than ascii code for q, print index
i+=1}               #increment index
Level River St
la source
6

JavaScript ES7, 50 48 octets

Assez court pour JS, si vous me demandez. [for...of]La syntaxe, qui combine essentiellement la carte et le filtre, est très utile pour relever ce défi.

s=>[for(c of(i=f=0,s))if(++i&&c>'e'?f%2:f++&0)i]

Définit une fonction anonyme qui génère un tableau à 1 index.

Extrait de test

Ceci utilise une version du code non golfée et non-ES7.

a = function(s) {   // Create a function a that takes in a parameter s and does these things:
  var r = [],       // Set variable r to an empty array,
  i = 0, f = 0;     // i to 0, and f to 0.
  for(c of s) {     // For each character c in s:
    i++;            //  Increment i by 1.
    if(             //  If
      c == 'q' ?    //   if c == 'q',
      f%2 === 1 :   //    f is even; otherwise,
      f++ && false) //    increment f and don't execute this:
      r.push(i);    //   Add i to the end of r.
  } return r;       // Return r.
}
<input type="text" value="eqqqe" id=O />
<button onclick="P.innerHTML='['+a(O.value)+']'">Try it</button>
<p id=P />

ETHproductions
la source
3
Très bonne explication! Et aussi un excellent exemple d'utilisation du nouveau [For ... of] de
ES7
Alors, avons-nous besoin d'une nouvelle question, "Conseils pour le golf dans ECMAScript 7"?
Neil
@Neil J'ai essayé de mettre à jour la publication ES6 vers ES6 / 7, mais l'OP a annulé la modification. En attendant, voici
ETHproductions
5

J, 20 19 17 octets

=&'e'(I.@:<~:/\@)

Merci à randomra pour la sauvegarde d’un octet et à Dennis pour la sauvegarde de deux. Ceci est un verbe monadique sans nom, utilisé comme suit:

  f =: =&'e'(I.@:<~:/\@)
  f 'eqqqe'
1 2 3

Essayez ici.

Explication

=&'e'(I.@:<~:/\@)
=&'e'               Replace every 'e' with 1, other chars with 0
     (         @)   Apply the verb in parentheses to the resulting 0-1 vector
           ~:/\     Cumulative reduce with XOR (parity of 'e'-chars to the left)
          <         Element-wise less-than with original vector
      I.@:          Positions of 1s in that vector
Zgarb
la source
5

GNU grep, 3 + 17 = 20 3 + 15 = 18 octets

Le programme nécessite les options boP. Le code est

q(?!(q|eq*e)*$)

Enregistrez-le sous synco, puis exécutez-le grep -boPf synco.

Le séparateur de sortie est :qsuivi d'une nouvelle ligne. Par exemple, la sortie pour eqqqeest

1:q
2:q
3:q

Les significations des drapeaux sont:

  • P: Utilisez les expressions rationnelles PCRE.
  • o: Cela signifie d’imprimer uniquement la partie de la ligne qui correspond à l’expression régulière, mais ce n’est pas pour cela que c’est important. oest utilisé car il a pour effet de permettre plusieurs correspondances par ligne.
  • b: Imprimer le décalage en octets du début de chaque correspondance depuis le début du fichier.

Le modèle vérifie qu'il n'y a pas un nombre pair de croche après une noire.

feersum
la source
Est-ce grepque cette langue est une langue à part entière? Quoi qu'il en soit, +1 pour une bonne réponse
Digital Trauma
@ DigitalTrauma Je ne vois pas pourquoi pas ... Il peut utiliser des regex PCRE, il devrait donc au moins être complet et peut exécuter du code à partir d'un fichier, comme illustré ici.
Feersum
J'avais l'impression qu'il n'était pas prouvé que PCRE était complet à Turing. Quoi qu'il en soit, votre expression répond à l'exigence, donc ça me convient, mais il peut y avoir d'autres personnes avec des plaintes pour des raisons théoriques.
Digital Trauma
@ DigitalTrauma Huh, semble avoir été trompé par la question de la complétude de Turing.
Feersum
5

MATL , 12 14 16 octets

j101=tYs2\<f

Merci à Dennis d'avoir supprimé 2 octets (et d'avoir hébergé MATL sur sa formidable plate-forme en ligne!)

Ceci utilise la version actuelle (9.3.0) du langage / compilateur.

Les entrées et sorties se font par stdin et stdout. Le résultat est 1 basé.

Exemple :

>> matl j101=tYs2\<f
> eeeeeqeeqeeqqqqeqeqeeqe
6  9 12 13 14 15 19 22

Ou essayez-le en ligne!

Explication

j             % input string
101=          % vector that equals 1 at 'e' characters and 0 otherwise
t             % duplicate
Ys2\          % cumulative sum modulo 2
<             % detect where first vector is 0 and second is 1
f             % find (1-based) indices of nonzero values
Luis Mendo
la source
3

Python 2, 94 85 79 75 66 octets

EDIT: Merci Doorknob et Alex A.

EDIT: Merci Alex A.

EDIT: Maintenant, en utilisant input (), l’entrée doit donc être une chaîne avec les guillemets.

EDIT: Merci Zgarb de me recommander d’utiliser énumérer.

Compte simplement le nombre de e et si q, vérifie si e compte est impair, puis affiche index.

e=0
for j,k in enumerate(input()):
 if"q">k:e+=1
 elif e%2:print j

Essayez-le ici

TanMath
la source
Vous pouvez remplacer le second if ...par un seul elsepour économiser 8 octets.
Poignée de porte
Vous pouvez également supprimer l'espace après print1 octet
Alex A.
Je pense que vous pouvez changer le else: if e%2:juste elif e%2:.
Alex A.
Vous pouvez sauvegarder un octet supplémentaire en cochant i[j]<"q"plutôt que i[j]=="e".
Alex A.
2
@TanMath J'ai demandé à Doorknob, car cela me ferait économiser 2 octets de prendre une entrée avec des guillemets. Mais cela ne peut pas être fait
Luis Mendo le
3

Haskell, 58 51 octets

f x=[i|(i,'q')<-zip[0..]x,odd$sum[1|'e'<-take i x]]

Exemple d'utilisation: f "eeeeeqeeqeeqqqqeqeqeeqe"-> [5,8,11,12,13,14,18,21].

Parcourez la liste et affichez l'index en cours ipour chaque caractère 'q's'il y a un nombre impair de 'e'secondes devant lui.

nimi
la source
2

Minkolang 0,15 , 28 octets

(o"q"=7&z1+$z8!z2%,2&iN$I$).

Essayez ici.

Explication

(                        Open while loop
 o                       Read in character from input
  "q"                    Push the character "q"
     =                   1 if the top two items on stack are equal, 0 otherwise
      7&                 Pop and jump 7 spaces if truthy

        z                Push register value on stack
         1+              Add one
           $z            Pop top of stack and store in register
             8!          Jump eight spaces

        z                Push register value on stack
         2%              Modulo by 2
           ,             boolean not
            2&           Pop and jump two spaces if truthy
              i          Push loop counter
               N         Output as number

                $I       Push length of input
                  $).    Close while loop when top of stack is 0 and stop.
El'endia Starman
la source
2

C (fonction), 65

Merci à Dennis pour le golf supplémentaire!

i,n;f(char*m){for(i=n=0;*m;i++)*m++&4?++n:n%2?printf("%d ",i):0;}
Trauma numérique
la source
1
Je pense que ça i,n;f(char*m){for(i=n=0;*m;m++,i++)*m&4?++n:n%2?printf("%d ",i):0;}devrait marcher.
Dennis
2

Python 3, 109 95 80 90 88 76 68 67 66 64 octets

Compte le nombre de qs et es et ajoute l'index du courant qsi le nombre de es précédents est impair.

Éditer: Maintenant, il affiche une liste des indices de s qui sont qprécédés d’un nombre impair de es. Huit octets économisés grâce à Doorknob et deux autres grâce à feersum .

lambda s:[x for x,m in enumerate(s)if("e"<m)*s[:x].count("e")%2]

Ungolfed:

def f(s):
    c = []
    for index, item in enumerate(s):
        if item == "q":
            if s[:index].count("e")%2 == 1:
                c.append(index)
    return c
Sherlock9
la source
1
Ne pourriez-vous pas en faire un lambda pour rendre les déclarations inputet printinutiles?
Poignée de porte
Il devrait être plus court à utiliser enumerateque range(len(....
Feersum
2

JavaScript ES6, 63 60 58 octets

x=>[...x].map((e,i)=>e>'e'?n%2&&a.push(i):n++,a=[],n=0)&&a

Fonction anonyme qui sort un tableau. Merci à user81655 d’avoir économisé deux octets. Voici une version non golfée qui utilise une syntaxe mieux supportée.

f=function(x) {
  a=[] // Indeces of syncopated notes
  n=0 // Number of e's encountered so far
  x.split('').map(function(e,i) { // For each letter...
    e>'e'? // If the letter is q...
      n%2&& // ...and the number of e's is odd...
        a.push(i): // ...add the current index to the array
      n++ // Otherwise, it is e so increment the counter
  })
  return a
}

run=function(){document.getElementById('output').textContent=f(document.getElementById('input').value)};document.getElementById('run').onclick=run;run()
<input type="text" id="input" value="qqqeqqeeeeqeqeqeqqeqqeqq" /><button id="run">Run</button><br />
<samp id="output"></samp>

NinjaBearMonkey
la source
0

Mathematica, 76 octets

Flatten[Range[#+1,#2-1]&@@@StringPosition[#,"e"~~"q"..~~"e",Overlaps->1<0]]&

Quelque chose d'intéressant j'ai remarqué. Toutes les parties syncopées sont de forme eqqq..qqe, je les détecte donc et donne les indices du qs.

LegionMammal978
la source
0

Japt, 29 23 21 octets

Non plus en compétition!

0+U ¬®¥'e} å^ ä© m© f

Essayez-le en ligne!

Comment ça marche

         // Implicit: U = input string, e.g.    "eqqeqeq"
0+U      // Add a 0 to the beginning.           "0eqqeqeq"
¬        // Split into chars.                   ['0,'e,'q,'q,'e,'q,'e,'q]
®¥'e}    // Map each item X to (X == 'e).       [F, T, F, F, T, F, T, F]
å^       // Cumulative reduce by XOR'ing.       [0, 1, 1, 1, 0, 0, 1, 1]
ä©       // Map each consecutive pair with &&.  [0, 1, 1, 0, 0, 0, 1]
m©       // Map each item with &&. This performs (item && index):
         //                                     [0, 1, 2, 0, 0, 0, 6]
f        // Filter out the falsy items.         [   1, 2,          6]
         // Implicit output                     [1,2,6]

Version non concurrente, 18 octets

U¬m¥'e å^ ä©0 m© f

Essayez-le en ligne!

ETHproductions
la source
0

Befunge, 43 octets

:~:0\`#@_5%2/:99p1++\>2%#<9#\9#.g#:*#\_\1+\

Essayez-le en ligne!

Explication

Nous commençons avec deux zéros implicites sur la pile: le numéro de note et un nombre de temps.

:               Make a duplicate of the beat count.
~               Read a character from stdin.
:0\`#@_         Exit if it's less than zero (i.e. end-of-file).
5%2/            Take the ASCII value mod 5, div 2, translating q to 1 and e to 0.
:99p            Save a copy in memory for later use.
1+              Add 1, so q maps to 2 and e to 1.
+               Then add that number to our beat count.
\               Get the original beat count that we duplicated at the start.
2%              Mod 2 to check if it's an off-beat.
99g*            Multiply with the previously saved note number (1 for q, 0 for e).
_               Essentially testing if it's a quarter note on an off-beat.
       \.:\     If true, we go turn back left, get the beat count, and output it.
         >2     Then push 2 onto the stack, and turn right again.
2%              That 2 modulo 2 is just zero.
99g*            Then multiplied by the saved note number is still zero.
_               And thus we branch right on the second pass.
\1+\            Finally we increment the note number and wrap around to the start again.
James Holderness
la source