Trova la sincronizzazione


33

Dato un input di una stringa costituita interamente da qs che rappresentano le note da un quarto e es che rappresentano le note da un quarto, producono gli indici delle note da un quarto sincronizzate.

La sincronizzazione è complessa, ma ai fini di questa sfida, la nostra definizione di "sincopato" sarà molto semplice: una nota da un quarto che inizia sul "fuori battito", ovvero i battiti contati come "e" in n / 4 tempo.

In alternativa, questo può essere definito come qualsiasi nota da un quarto preceduta da un numero dispari di ottava nota. Ad esempio, le note contrassegnate con *sotto sono considerate sincopate e anche i loro indici sono mostrati:

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

L'input consisterà sempre in un numero intero di misure in 4/4 volte (una nota da un quarto è un quarto di misura e un'ottava nota è un ottavo di misura). (Anche l'input non sarà mai vuoto.) L'output può essere una singola stringa con elementi separati da qualsiasi delimitatore che non contiene numeri o un array / elenco / ecc. L'output può essere basato su 1 (ovvero, se lo si desidera, il primo indice è 1 anziché 0) e può anche trovarsi in qualsiasi base numerica (unaria, decimale, ecc.).

Dato che si tratta di , vince il codice più breve in byte.

Casi 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>

1
L'output può essere basato su 1?
Luis Mendo,

1
Potresti fare un esempio funzionante per mostrare come funzionano gli indici?
Peter Taylor,

1
@LuisMendo Certo, se accorcia il tuo codice.
Maniglia della porta

@PeterTaylor Okay, è qualcosa di simile a quello a cui stavi pensando?
Maniglia della porta

L'input può essere una stringa che include i segni di virgolette? 'eqqqe'anzichéeqqqe
Luis Mendo il

Risposte:


12

Gelatina , 12 9 byte

=“e”µ<^\O

Come programma, il codice sopra richiede virgolette attorno all'input. Poiché ciò non è consentito, si tratta di un invio di funzione. L'output è basato su 1. Provalo online!

Come funziona

=“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.

Aggiornare

Il codice sopra non funziona più nell'ultima versione di Jelly, poiché abbiamo bisogno di un carattere e , ma “e”produce una stringa. Correzione che salva un byte, per un totale di 8 byte .

=”eµ<^\O

Funziona come un programma completo. Provalo online!


7

Ruby, 46

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

Ingresso in stdin. Uscita su stdout, newline separato.

Commentate

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

6

JavaScript ES7, 50 48 byte

Abbastanza corto per JS, se me lo chiedi. [for...of]la sintassi, fondamentalmente combinata mappa e filtro, è utile per questa sfida.

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

Definisce una funzione anonima che genera un array con 1 indice.

Snippet di prova

Questo utilizza una versione non modificata, non ES7 del codice.

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 />


3
Ottima spiegazione! E anche un ottimo esempio di come usare il nuovo ES7 [For ... of] 👍
Aᴄʜᴇʀᴏɴғᴀɪʟ

Quindi, abbiamo bisogno di una nuova domanda, "Suggerimenti per giocare a golf in ECMAScript 7"?
Neil,

@Neil Ho provato ad aggiornare il post ES6 su ES6 / 7, ma l'OP ha ripristinato la modifica. Nel frattempo, c'è questo: codegolf.stackexchange.com/a/61489/42545
ETHproductions

5

J, 20 19 17 byte

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

Grazie a randomra per aver salvato un byte ea Dennis per averne salvato due. Questo è un verbo monadico senza nome, usato come segue:

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

Provalo qui.

Spiegazione

=&'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

5

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

Il programma richiede le opzioni boP. Il codice è

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

Salvalo come synco, quindi esegui come grep -boPf synco.

Il separatore di output è :qseguito da una nuova riga. Ad esempio, l'output per eqqqeè

1:q
2:q
3:q

I significati delle bandiere sono:

  • P: Usa regex PCRE.
  • o: Questo significa stampare solo la parte della riga che corrisponde all'espressione regolare, ma non è per questo che è importante. oviene utilizzato perché ha l'effetto di consentire più corrispondenze per riga.
  • b: Stampa l'offset in byte dell'inizio di ogni corrispondenza dall'inizio del file.

Il modello verifica che non vi sia un numero pari di ottave note dopo una nota da un quarto.


Si grepqualifica come lingua a sé stante? Indipendentemente da ciò, +1 per un'ottima risposta
Digital Trauma,

@DigitalTrauma Non vedo perché no ... Può usare regex PCRE, quindi dovrebbe essere almeno Turing completo e può eseguire il codice da un file come mostrato qui.
feersum

Ho avuto l'impressione che PCRE non abbia dimostrato di essere Turing completo. Indipendentemente da ciò, la tua espressione soddisfa i requisiti, quindi sono d'accordo, ma ci possono essere altri con lamentele per motivi teorici.
Trauma digitale

@DigitalTrauma Huh, sembra che mi sia illuso per la completezza di Turing.
feersum

5

MATL , 12 14 16 byte

j101=tYs2\<f

Grazie a Dennis per aver rimosso 2 byte (e per aver ospitato MATL nella sua fantastica piattaforma online!)

Questo utilizza la versione corrente (9.3.0) del linguaggio / compilatore.

L'input e l'output sono tramite stdin e stdout. Il risultato è basato su 1.

Esempio :

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

Oppure provalo online!

Spiegazione

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

3

Python 2, 94 85 79 75 66 byte

EDIT: Grazie Doorknob e Alex A.

EDIT: Grazie Alex A.

EDIT: Ora usando input () quindi l'input deve essere una stringa con le virgolette.

EDIT: Grazie Zgarb per avermi consigliato di usare enumerate.

Conta semplicemente il numero di e e, se q, controlla se il conteggio è dispari, quindi stampa l'indice.

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

Provalo qui


È possibile sostituire il secondo if ...con solo un elseper salvare 8 byte.
Maniglia della porta

Puoi anche rimuovere lo spazio dopo printper 1 byte
Alex A.

Penso che tu possa cambiare else: if e%2:in solo elif e%2:.
Alex A.

È possibile salvare un altro byte selezionando i[j]<"q"anziché i[j]=="e".
Alex A.

2
@TanMath ho chiesto a Doorknob perché mi risparmierebbe 2 byte per inserire un input tra virgolette. Ma non si può fare
Luis Mendo il

3

Haskell, 58 51 byte

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

Esempio di utilizzo: f "eeeeeqeeqeeqqqqeqeqeeqe"-> [5,8,11,12,13,14,18,21].

Scorri l'elenco e visualizza l'indice corrente iper ogni carattere 'q'se c'è un numero dispari di 'e's prima di esso.


2

Minkolang 0,15 , 28 byte

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

Provalo qui.

Spiegazione

(                        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.

2

C (funzione), 65

Grazie a @Dennis per il golf extra!

i,n;f(char*m){for(i=n=0;*m;i++)*m++&4?++n:n%2?printf("%d ",i):0;}

1
Penso che i,n;f(char*m){for(i=n=0;*m;m++,i++)*m&4?++n:n%2?printf("%d ",i):0;}dovrebbe funzionare.
Dennis,

2

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

Conta il numero di qs e es e aggiunge l'indice della corrente qse il numero di precedentie s è dispari.

Modifica: ora stampa un elenco degli indici di s che sono qe hanno un numero dispari di es che li precede. Otto byte salvati grazie a Doorknob e altri due grazie a 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

1
Non potresti renderlo un lambda per rendere inutili le dichiarazioni inpute print?
Maniglia della porta

Dovrebbe essere più breve da usare enumeratepiuttosto che range(len(....
febbraio

2

JavaScript ES6, 63 60 58 byte

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

Funzione anonima che genera un array. Grazie a user81655 per il salvataggio di due byte. Ecco una versione non golfata che utilizza una sintassi supportata meglio.

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>


0

Mathematica, 76 byte

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

Qualcosa di interessante che ho notato. Tutte le parti sincopate sono di forma eqqq..qqe, quindi le rilevo e fornisco gli indici della qs.


0

Japt, 29 23 21 byte

Non più in competizione!

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

Provalo online!

Come funziona

         // 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]

Versione non competitiva, 18 byte

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

Provalo online!


0

Befunge, 43 byte

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

Provalo online!

Spiegazione

Iniziamo con due zeri impliciti nello stack: il numero della nota e un conteggio dei battiti.

:               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.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.