Finde die Synkopierung


33

Bei einer Eingabe einer Zeichenfolge, die ausschließlich aus qs für Viertelnoten und es für Achtelnoten besteht, werden die Indizes der synchronisierten Viertelnoten ausgegeben.

Die Synchronisation ist komplex, aber für die Zwecke dieser Herausforderung wird unsere Definition von "synchronisiert" sehr einfach sein: Eine Viertelnote, die mit dem "Off-Beat" beginnt - das heißt, die Beats werden in n / 4 als "und" gezählt Zeit.

Dies kann alternativ als jede Viertelnote definiert werden, der eine ungerade Anzahl von Achtelnoten vorausgeht. Beispielsweise werden die mit gekennzeichneten Noten *als synchronisiert betrachtet und ihre Indizes werden ebenfalls angezeigt:

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

Die Eingabe besteht immer aus einer ganzen Anzahl von Takten im 4/4-Takt (eine Viertelnote ist ein Viertel eines Takts und eine Achtelnote ist ein Achtel eines Takts). (Die Eingabe ist auch niemals leer.) Die Ausgabe kann entweder eine einzelne Zeichenfolge mit durch Trennzeichen getrennten Elementen sein, die keine Zahlen enthalten, oder ein Array / eine Liste / usw. Die Ausgabe kann auf 1 basieren (dh der erste Index ist 1 anstelle von 0), und sie kann auch auf einer beliebigen numerischen Basis (unär, dezimal usw.) erfolgen.

Da es sich um , der kürzeste Code in Bytes gewinnt.

Testfälle:

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
Kann die Ausgabe 1-basiert sein?
Luis Mendo

1
Können Sie anhand eines Beispiels zeigen, wie die Indizes funktionieren?
Peter Taylor

1
@ LuisMendo Sicher, wenn es Ihren Code kürzer macht.
Türklinke

@PeterTaylor Okay, ist so etwas wie das, woran du gedacht hast?
Türklinke

Kann die Eingabe eine Zeichenfolge sein, die die Anführungszeichen enthält? 'eqqqe'statteqqqe
Luis Mendo

Antworten:


12

Gelee , 12 9 Bytes

=“e”µ<^\O

Als Programm erfordert der obige Code Anführungszeichen um die Eingabe. Da dies nicht zulässig ist, handelt es sich um eine Funktionsübermittlung. Die Ausgabe ist 1-basiert. Probieren Sie es online!

Wie es funktioniert

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

Aktualisieren

Der obige Code funktioniert in der neuesten Version von Jelly nicht mehr, da wir ein Zeichen e benötigen , aber “e”einen String liefern. Behebung, die ein Byte für insgesamt 8 Bytes spart .

=”eµ<^\O

Dies funktioniert als vollständiges Programm. Probieren Sie es online!


7

Rubin, 46

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

Eingabe in stdin. Ausgabe auf Standardausgabe, Zeilenvorschub getrennt.

Kommentiert

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 Bytes

Ziemlich kurz für JS, wenn Sie mich fragen. [for...of]Die Syntax, im Grunde genommen eine Kombination aus Karte und Filter, ist für diese Herausforderung praktisch.

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

Definiert eine anonyme Funktion, die ein Array mit einem Index ausgibt.

Testschnipsel

Dies verwendet eine ungolfed, un-ES7-Version des Codes.

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
Sehr gute Erklärung! Und auch ein großartiges Beispiel für die Verwendung von ES7's neuem [For ... of] 👍
Aᴄʜᴇʀᴏɴғᴀɪʟ

Brauchen wir also eine neue Frage, "Tipps zum Golfen in ECMAScript 7"?
Neil

@Neil Ich habe versucht, den ES6-Beitrag auf ES6 / 7 zu aktualisieren, aber das OP hat die Bearbeitung zurückgesetzt. In der Zwischenzeit gibt es folgendes: codegolf.stackexchange.com/a/61489/42545
ETHproductions

5

J, 20 - 19 - 17 Bytes

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

Dank an randomra für das Speichern eines Bytes und an Dennis für das Speichern von zwei Bytes. Dies ist ein unbenanntes monadisches Verb, das wie folgt verwendet wird:

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

Probieren Sie es hier aus.

Erläuterung

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

Das Programm benötigt die Optionen boP. Der Code ist

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

Speichern Sie es als synco, und führen Sie es als aus grep -boPf synco.

Auf das Ausgabetrennzeichen :qfolgt eine neue Zeile. ZB die Ausgabe für eqqqeIS

1:q
2:q
3:q

Die Bedeutungen der Flags sind:

  • P: Verwenden Sie PCRE-reguläre Ausdrücke.
  • o: Dies bedeutet, dass nur der Teil der Zeile gedruckt wird, der mit dem regulären Ausdruck übereinstimmt, dies ist jedoch nicht wichtig. owird verwendet, weil dadurch mehrere Übereinstimmungen pro Zeile zugelassen werden.
  • b: Gibt den Versatz des Anfangs jeder Übereinstimmung vom Anfang der Datei an in Bytes aus.

Das Muster prüft, ob nach einer Viertelnote keine gerade Zahl von Achtelnoten vorhanden ist.


Ist es grepeine eigenständige Sprache? Unabhängig davon, +1 für eine gute Antwort
Digital Trauma

@DigitalTrauma Ich verstehe nicht, warum nicht ... Es kann PCRE-Regexes verwenden, sollte also mindestens Turing-complete sein und kann Code aus einer Datei wie hier gezeigt ausführen.
Feersum

Ich hatte den Eindruck, dass PCRE nachweislich nicht vollständig ist. Ungeachtet dessen erfüllt Ihr Ausdruck die Anforderung, sodass ich damit einverstanden bin. Es kann jedoch auch andere geben, die aus theoretischen Gründen Beschwerden haben.
Digital Trauma

@DigitalTrauma Huh, anscheinend war ich über die Turing-Vollständigkeitssache getäuscht.
Feersum

5

MATL , 12 14 16 Bytes

j101=tYs2\<f

Vielen Dank an Dennis für das Entfernen von 2 Bytes (und für das Hosten von MATL auf seiner großartigen Online-Plattform!)

Dies verwendet die aktuelle Version (9.3.0) der Sprache / des Compilers.

Ein- und Ausgabe erfolgen über stdin und stdout. Das Ergebnis ist 1-basiert.

Beispiel :

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

Oder versuchen Sie es online!

Erläuterung

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 Bytes

EDIT: Danke Doorknob und Alex A.

EDIT: Danke Alex A.

BEARBEITEN: Verwenden Sie jetzt input (), sodass die Eingabe eine Zeichenfolge mit Anführungszeichen sein muss.

BEARBEITEN : Danke Zgarb für die Empfehlung, Aufzählung zu verwenden.

Zählt einfach die Anzahl der e, und wenn q, prüft, ob die Anzahl der e ungerade ist, und druckt den Index.

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

Probieren Sie es hier aus


Sie können die Sekunde if ...durch eine ersetzen else, um 8 Bytes zu sparen.
Türklinke

Sie können auch das Leerzeichen nach printfür 1 Byte entfernen
Alex A.

Ich denke du kannst das else: if e%2:einfach ändern elif e%2:.
Alex A.

Sie können ein weiteres Byte speichern, indem Sie die Option i[j]<"q"aktivieren i[j]=="e".
Alex A.

2
@ TanMath Ich fragte Doorknob, weil es mir 2 Bytes ersparen würde, eine Eingabe mit Anführungszeichen zu machen. Aber es geht nicht
Luis Mendo

3

Haskell, 58 51 Bytes

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

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

Gehen Sie die Liste durch und geben Sie den aktuellen Index ifür jedes Zeichen aus, 'q'wenn eine ungerade Anzahl von 'e's davor steht.


2

Minkolang 0,15 , 28 Bytes

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

Probieren Sie es hier aus.

Erläuterung

(                        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 (Funktion), 65

Vielen Dank an @Dennis für das zusätzliche Golfen!

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

1
Ich denke i,n;f(char*m){for(i=n=0;*m;m++,i++)*m&4?++n:n%2?printf("%d ",i):0;}sollte funktionieren.
Dennis

2

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

Zählt die Anzahl von qs und es und addiert den Index des aktuellen Werts, qwenn die Anzahl der vorangegangenen es ungerade ist.

Bearbeiten: Jetzt wird eine Liste der Indizes von s gedruckt, qdenen eine ungerade Anzahl von es vorangestellt ist. Acht Bytes gespart dank Doorknob und zwei weitere dank 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
Könnten Sie das nicht zu einem Lambda machen, um die Aussagen inputund printunnötig zu machen ?
Türklinke

Es sollte kürzer sein zu verwenden , enumeratestatt range(len(....
Feersum

2

JavaScript ES6, 63 60 58 Bytes

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

Anonyme Funktion, die ein Array ausgibt. Vielen Dank an user81655 für das Speichern von zwei Bytes. Hier ist eine ungolfed Version, die eine besser unterstützte Syntax verwendet.

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 Bytes

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

Etwas interessantes ist mir aufgefallen. Alle synkopierten Teile sind von Form eqqq..qqe, also erkenne ich sie einfach und gebe die Indizes der qs an.


0

Japt, 29 23 21 Bytes

Nicht mehr konkurrierend!

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

Probieren Sie es online!

Wie es funktioniert

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

Nicht konkurrierende Version, 18 Bytes

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

Probieren Sie es online!


0

Befunge, 43 Bytes

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

Probieren Sie es online!

Erläuterung

Wir beginnen mit zwei impliziten Nullen auf dem Stapel: der Notennummer und einer Schlagzahl.

:               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.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.