Temukan sinkopasinya


33

Diberikan input dari string yang seluruhnya terdiri dari qs yang mewakili not seperempat dan es yang mewakili not seperdelapan, menampilkan indeks not seperempat yang disinkronkan.

Sinkronisasi itu rumit, tetapi untuk tujuan tantangan ini, definisi kami tentang "disinkronkan" akan sangat sederhana: seperempat not yang dimulai pada "off-beat" —yaitu, ketukan dihitung sebagai "dan" dalam n / 4 waktu.

Sebagai alternatif, ini dapat didefinisikan sebagai setiap not seperempat yang didahului dengan jumlah ganjil nota kedelapan. Misalnya, catatan yang ditandai dengan di *bawah ini dianggap sinkop, dan indeksnya juga ditampilkan:

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

Masukan akan selalu terdiri dari seluruh jumlah pengukuran dalam waktu 4/4 (not seperempat adalah seperempat ukuran, dan not kedelapan adalah kedelapan ukuran). (Input juga tidak akan pernah kosong.) Output dapat berupa string tunggal dengan elemen yang dipisahkan oleh pembatas yang tidak mengandung angka atau array / daftar / dll. Output mungkin berbasis 1 (yaitu indeks pertama adalah 1 bukan 0) jika Anda inginkan, dan mungkin juga dalam basis numerik apa pun (unary, desimal, dll.).

Karena ini adalah , kode terpendek dalam byte akan menang.

Kasus uji:

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
Bisakah output berbasis 1?
Luis Mendo

1
Bisakah Anda melakukan contoh yang berfungsi untuk menunjukkan bagaimana indeks bekerja?
Peter Taylor

1
@LuisMendo Tentu, jika itu membuat kode Anda lebih pendek.
Gagang Pintu

@PeterTaylor Oke, apakah itu yang Anda pikirkan?
Gagang Pintu

Bisakah input menjadi string termasuk tanda kutip? 'eqqqe'alih-aliheqqqe
Luis Mendo

Jawaban:


12

Jelly , 12 9 byte

=“e”µ<^\O

Sebagai sebuah program, kode di atas membutuhkan tanda kutip di sekitar input. Karena itu tidak diizinkan, ini adalah pengiriman fungsi. Outputnya berbasis 1. Cobalah online!

Bagaimana itu bekerja

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

Memperbarui

Kode di atas tidak berfungsi lagi dalam versi terbaru Jelly, karena kita memerlukan karakter e , tetapi “e”menghasilkan string. Memperbaiki itu menghemat satu byte, dengan total 8 byte .

=”eµ<^\O

Ini berfungsi sebagai program lengkap. Cobalah online!


7

Ruby, 46

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

Masukan ke stdin. Output ke stdout, baris baru dipisahkan.

Berkomentar

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

Cukup singkat untuk JS, jika Anda bertanya kepada saya. [for...of]sintaksis, pada dasarnya gabungan peta dan filter, berguna untuk tantangan ini.

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

Menentukan fungsi anonim yang menghasilkan array 1-diindeks.

Cuplikan tes

Ini menggunakan versi kode yang ungolfed, un-ES7'd.

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
Penjelasan yang sangat bagus! Dan juga contoh yang bagus tentang bagaimana menggunakan ES7 baru [Untuk ... dari] 👍
Aᴄʜᴇʀᴏɴғᴀɪʟ

Jadi, apakah kita memerlukan pertanyaan baru, "Kiat untuk Bermain Golf di ECMAScript 7"?
Neil

@Neil Saya mencoba memperbarui posting ES6 ke ES6 / 7, tetapi OP memutar kembali hasil edit. Sementara itu, ada ini: codegolf.stackexchange.com/a/61489/42545
ETHproductions

5

J, 20 19 17 byte

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

Terima kasih kepada randomra untuk menyimpan satu byte, dan untuk Dennis karena menyimpan dua byte. Ini adalah kata kerja monadik tanpa nama, digunakan sebagai berikut:

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

Coba di sini.

Penjelasan

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

Program ini membutuhkan opsi boP. Kodenya adalah

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

Simpan sebagai synco, lalu jalankan sebagaigrep -boPf synco .

Pemisah output :qdiikuti oleh baris baru. Misalnya output untuk eqqqeis

1:q
2:q
3:q

Arti dari bendera adalah:

  • P: Gunakan regre PCRE.
  • o: Ini berarti untuk mencetak hanya bagian dari garis yang cocok dengan ekspresi reguler, tetapi bukan itu yang penting. odigunakan karena memiliki efek memungkinkan beberapa pertandingan per baris.
  • b: Cetak offset dalam byte dari awal setiap pertandingan dari awal file.

Pola memeriksa bahwa tidak ada jumlah genap dari not kedelapan setelah not seperempat.


Apakah grepmemenuhi syarat sebagai bahasa sendiri? Apapun, +1 untuk jawaban yang bagus
Digital Trauma

@DigitalTrauma Saya tidak melihat mengapa tidak ... Itu dapat menggunakan regre PCRE, jadi setidaknya Turing-complete, dan dapat menjalankan kode dari file seperti yang ditunjukkan di sini.
feersum

Saya mendapat kesan bahwa PCRE tidak terbukti Turing lengkap. Apapun, ekspresi Anda memenuhi persyaratan, jadi saya setuju dengan itu, tetapi mungkin ada yang lain dengan alasan teoritis.
Digital Trauma

@DigitalTrauma Huh, sepertinya saya tertipu tentang hal kelengkapan Turing.
feersum

5

MATL , 12 14 16 byte

j101=tYs2\<f

Terima kasih kepada Dennis karena telah menghapus 2 byte (dan untuk hosting MATL di platform daringnya yang mengagumkan!)

Ini menggunakan versi saat ini (9.3.0) dari bahasa / kompiler.

Input dan output melalui stdin dan stdout. Hasilnya berbasis 1.

Contoh :

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

Atau coba online!

Penjelasan

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: Terima kasih Doorknob dan Alex A.

EDIT: Terima kasih Alex A.

EDIT: Sekarang menggunakan input () sehingga input harus berupa string dengan tanda kutip.

EDIT: Terima kasih Zgarb karena merekomendasikan saya untuk menggunakan penghitungan.

Cukup hitung jumlah e dan jika q, periksa apakah e ganjil, lalu cetak indeks.

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

Coba di sini


Anda dapat mengganti yang kedua if ...hanya elsedengan menyimpan 8 byte.
Gagang Pintu

Anda juga dapat menghapus spasi setelah printuntuk 1 byte
Alex A.

Saya pikir Anda bisa mengubahnya else: if e%2:menjadi adil elif e%2:.
Alex A.

Anda dapat menyimpan satu byte lagi dengan mencentang i[j]<"q"daripada i[j]=="e".
Alex A.

2
@TanMath saya bertanya Doorknob karena itu akan menyelamatkan saya 2 byte untuk mengambil input dengan tanda kutip. Tapi itu tidak bisa dilakukan
Luis Mendo

3

Haskell, 58 51 byte

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

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

Pergi melalui daftar dan output indeks saat ini iuntuk setiap karakter 'q'jika ada jumlah ganjil dari 'e'sebelumnya.


2

Minkolang 0,15 , 28 byte

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

Coba di sini.

Penjelasan

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

Thanks to @Dennis for the extra golfing!

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

1
I think i,n;f(char*m){for(i=n=0;*m;m++,i++)*m&4?++n:n%2?printf("%d ",i):0;} should work.
Dennis

2

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

Counts the number of qs and es and adds the index of the current q if the number of preceding es is odd.

Edit: Now it prints a list of the indices of s that are q and have an odd number of es preceding them. Eight bytes saved thanks to Doorknob and two more thanks to 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
Couldn't you make this a lambda to make the input and print statements unnecessary?
Doorknob

It should be shorter to use enumerate rather than 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

Anonymous function that outputs an array. Thanks to user81655 for saving two bytes. Here is an ungolfed version that uses better supported syntax.

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

Something interesting I noticed. All of the syncopated parts are of form eqqq..qqe, so I just detect those and give the indices of the qs.


0

Japt, 29 23 21 bytes

Not non-competing anymore!

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

Try it online!

How it works

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

Non-competing version, 18 bytes

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

Try it online!


0

Befunge, 43 bytes

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

Try it online!

Explanation

We start with two implicit zeros on the stack: the note number, and a beat count.

:               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.
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.