Temukan pola yang optimal

33

Diberi string yang terdiri dari huruf kecil, seperti

aabaaababbbbaaba

dan bilangan bulat positif n , seperti 4, menghasilkan panjang- n string t sehingga ketika t diulangi dengan panjang s , mereka memiliki banyak karakter yang sama. Untuk contoh yang diberikan, output optimal adalah aaba, karena memiliki tiga belas karakter yang sama dengan string target:

s: aabaaababbbbaaba
t: aabaaabaaabaaaba (aaba)
   ^^^^^^^^  ^ ^^^^

dan t tidak mungkin memiliki lebih. Namun, untuk aaaaaab, ada dua kemungkinan keluaran: aaaadan aaba, yang masing-masing memiliki 6 karakter yang sama dengan string target:

s: aaaaaab
t: aaaaaaaa (aaaa)
   ^^^^^^ 

s: aaaaaab
t: aabaaaba (aaba)
   ^^ ^^^^

Baik aaaaatau aabadapat di-output, atau keduanya jika Anda mau. Perhatikan bahwa s tidak pernah diulang; jejak adi kedua nilai yang diulang t hanya diabaikan.

Uji kasus

Inputs -> Valid outputs
1 a -> a
1 aa -> a
2 aa -> aa
1 ab -> a b
2 ab -> ab
1 abb -> b
2 abb -> ab bb
2 ababa -> ab
2 abcba -> ab
2 aabbbbb -> bb  (ab is not a valid output here)
3 aababba -> aab abb
3 aababbaa -> aab
3 asdasfadf -> asf
3 asdasfadfsdf -> asf adf
2 abcdefghijklmnopqrstuvwxyzyx -> yx
2 supercalifragilisticexpialidocious -> ic ii
3 supercalifragilisticexpialidocious -> iri ili ioi
4 supercalifragilisticexpialidocious -> scii
5 supercalifragilisticexpialidocious -> iapic
2 eeeebaadbaecaebbbbbebbbbeecacebdccaecadbbbaceebedbbbddadebeddedbcedeaadcabdeccceccaeaadbbaecbbcbcbea -> bb be
10 bbbbacacbcedecdbbbdebdaedcecdabcebddbdcecebbeeaacdebdbebaebcecddadeeedbbdbbaeaaeebbedbeeaeedadeecbcd -> ebbbdbeece ebdbdbeece
20 aabbbaaabaaabaaaabbbbabbbbabbbabbbbbabbaaaababbbaababbbaababaaaabbaaabbaabbbabaaabbabbaaabbaaaaaaaba -> aabbbbaaabbabbbaabba

Aturan

  • Anda dapat berasumsi bahwa input hanya akan berupa string huruf kecil yang tidak kosong dan bilangan bulat positif tidak lebih besar dari panjang string.
  • Anda dapat mengambil input dalam format standar apa pun dan dalam urutan apa pun.
  • Anda dapat menampilkan string tunggal, atau lebih dari satu dalam bentuk array, dipisahkan oleh baris baru atau spasi, dll.
  • Kode Anda harus selesai untuk setiap test case dalam waktu kurang dari 1 menit pada komputer yang cukup modern.
  • Ini , jadi buat kode Anda sesingkat mungkin.
Produksi ETH
sumber
2
Tantangan ini adalah kualitas Zgarb. Kerja bagus!
Martin Ender
Saya mengasumsikan hanya karakter tambahan yang diabaikan? Jadi, Anda tidak boleh mengabaikan karakter utama seperti ini: di 2 abb -> bamana ia dibangun sebagai (b)[ab]a: pemimpin (b)diabaikan, [ab]cocok.
Kevin Cruijssen
@KevinCruijssen Benar, polanya harus mulai berulang di awal.
ETHproduk

Jawaban:

11

Jelly , 11 byte

sZµṢŒrUṀṪµ€

Cobalah online!

Tidak mengharapkan untuk mengalahkan Dennis pada yang satu ini, jadi cobalah untuk FGITW itu (setelah mencoba beberapa kemungkinan; ada lebih dari satu cara untuk membuat 11). Saya datang lebih pendek, sangat mengejutkan saya.

Mengambil string lalu menghitung sebagai argumen baris perintah. Output pada stdout.

Penjelasan

sZµṢŒrUṀṪµ€
s            Split {the first input} into {the second input}-sized groups
 Z           Transpose
  µ      µ€  On each of the transposed groups:
   Ṣ           Sort it;
    Œr         Run-length encode it;
      U        Rearrange it to the form {count, letter};
       Ṁ       Take the largest element (i.e. largest count)
        Ṫ      Take the second element of the pair (i.e. just the letter)

Ini menggunakan wawasan bahwa huruf di setiap posisi pola harus merupakan huruf paling umum yang sesuai dengan posisi itu. Kita dapat menemukan huruf-huruf yang sesuai dengan pola tertentu melalui pemisahan menjadi kelompok-kelompok berukuran pola, dan transposing. Alasan utama solusi ini begitu lama adalah karena Jelly tampaknya tidak memiliki cara pendek untuk menemukan mode daftar (saya telah melakukan beberapa upaya, tetapi mereka semua setidaknya sepanjang enam byte).

Jelly , 10 byte, berdasarkan solusi @Dennis

⁸ċ$ÞṪ
sZÇ€

Cobalah online!

Ini adalah kombinasi dari solusi @Dennis dan solusi saya sendiri; ada mode lima byte dalam solusi itu, yang saya curi untuk solusi ini. (Saya sudah memiliki solusi berdasarkan ⁸ċ, tetapi tidak bisa mendapatkan di bawah enam byte dengan itu; Saya belum berpikir untuk menggunakan Þ.)

Penjelasan

µ…µ€dan Ç€(dengan pada baris sebelumnya) panjangnya tiga byte (yang terakhir membutuhkan baris baru), dan setara. Biasanya saya menggunakan yang pertama, tetapi yang terakhir lebih fleksibel, karena memungkinkan Anda untuk menggunakan untuk menyebutkan argumen.

Ini memungkinkan untuk mengurutkan ( Þ) berdasarkan jumlah kemunculan dalam ( ⁸ċ), lalu mengambil elemen terakhir ( ), untuk menemukan mode hanya dalam lima karakter.


sumber
5
Pekerjaan bagus mengalahkan Dennis dengan bahasanya sendiri! : P
HyperNeutrino
10

Mathematica, 51 byte

#&@@@Commonest/@(PadRight@Partition[#2,UpTo@#])&

Input dan output adalah daftar karakter.

Juga didasarkan pada mode garis transpos. Saya percaya mereka disebut built-in untuk mode daftar Commonest semata - mata untuk pegolf kode.

Martin Ender
sumber
Paling tidak satu byte lebih pendek dari MostCommon...
ETHproduk
7

Python 3, 99, 73 61 byte

-12, thx ke @Rod

lambda s,n:''.join(max(s,key=s[i::n].count)for i in range(n))

Gagasan yang sama, tetapi menulis ulang untuk menghilangkan pernyataan impor.

lambda s,n:''.join(max(s,key=lambda c:s[i::n].count(c))for i in range(n))

Asli

from collections import*
lambda s,n:''.join(Counter(s[i::n]).most_common(1)[0][0]for i in range(n))

Penjelasan:

s[i::n]                  a slice of every nth character of s, starting at position i

Counter(s[i::n])         counts the characters in the slice
  .most_common()         returns a list of (character, count) pairs, sorted by decreasing count
    [0][0]               grabs the letter from the first pair (i.e., the most common letter
      for i in range(n)  repeat for all starting positions

''.join                  combines the most common letters into a single string
RootTwo
sumber
Anda dapat beralih ke python2.7 dan menjatuhkannya ''.join()untuk mengembalikan daftar string
Rod
@Rod Dropping ''.join(...)akan mengembalikan generator, tidak yakin apakah itu diizinkan output.
L3viathan
@ L3viathan itu harus python2.7 untuk bekerja, ditambahkan ke komentar lain
Rod
Bisakah Anda menulis beberapa penjelasan tentang cara kerjanya?
Dead Possum
2
@Rod Daftar string hanya diperbolehkan dalam pertanyaan jika Anda mengembalikan semua solusi yang mungkin. Itu yang saya maksudkan.
mbomb007
5

Python 2, 106

Sekarang ini jawaban yang berbeda! Saya sedang memikirkan satu (hampir) -lantai dari awal. Sekarang bahkan lebih pendek, berdasarkan penggunaan zip oleh @Rod.

Terima kasih kepada @ L3viathan dan @Rod untuk klarifikasi tentang penggunaan lambdas sebagai jawaban

Cobalah online

lambda S,N:max(combinations(S,N),key=lambda s:sum(x==y for x,y in zip(S,s*len(S))))
from itertools import*

Penjelasan:

combinations(S,N) membuat semua kombinasi panjang N dari karakter S

max()memiliki argumen keyyang digunakan sebagai fungsi input untuk digunakan untuk membandingkan elemen

lambda s:sum(x==y for x,y in zip(S,s*len(S))) disahkan sebagai fungsi seperti itu

Lambda ini menghitung jumlah karakter yang cocok dalam daftar tupel, hasilkan oleh zip(S,s*len(S))

s- salah satu kombinasi dan dikalikan untuk len(S)membuat string yang dijamin lebih lama dari S

zipmembuat tupel karakter dari setiap string Sdan s*len(S)dan mengabaikan semua karakter yang tidak dapat dicocokkan (dalam kasus satu string lebih lama dari yang lain)

Jadi maxpilih kombinasi, yang menghasilkan jumlah maksimum

Possum Mati
sumber
1
Anda tidak perlu menggunakan []fungsi daftar pemahaman di dalam, juga Anda menggunakan 1 for ... if <cond>Anda dapat menggunakan secara langsung <cond> for ...karena akan digunakan pada sum, python akan mengambil Truesebagai 1dan Falsesebagai0
Rod
@Rod, terima kasih! Jika saya akan memperbesar jawaban saya, itu akan berubah menjadi jawaban Anda, pendekatannya sama: D Jadi saya sedang mencoba sesuatu yang berbeda sekarang
Dead Possum
Yap, katakan saja agar Anda bisa menggunakan jawaban Anda di masa depan: 3
Rod
1
Beralih ke lambda akan menghemat 7 byte.
L3viathan
1
@DeadPossum Dia maksudkan ini (perhatikan footer dan header) dan ya, fungsi adalah jawaban yang valid , jika itu lambda Anda bahkan tidak memerlukanf= (kecuali itu rekursif)
Rod
5

JavaScript (ES6), 104 101 94 byte

(n,s)=>s.replace(/./g,(_,i)=>[...s].map((c,j,a)=>j%n-i||(a[c]=-~a[c])>m&&(m++,r=c),m=r=``)&&r)

Disimpan 3 byte dua kali berkat @Arnauld. Solusi 97 byte yang bekerja dengan semua karakter non-baris baru:

(n,s)=>s.replace(/./g,(_,i)=>[...s].map((c,j)=>j%n-i||(o[c]=-~o[c])>m&&(m++,r=c),m=r=``,o={})&&r)

Solusi 104-byte sebelumnya juga berfungsi dengan karakter baris baru:

(n,s)=>[...Array(n)].map((_,i)=>[...s].map((c,j)=>j%n-i||(o[c]=-~o[c])>m&&(m++,r=c),m=0,o={})&&r).join``
Neil
sumber
Sangat bagus. Saya menggunakan solusi untuk referensi ketika menambahkan test case dan muncul pada 122 byte, mengulangi setiap char, menyimpan hitungan dalam array objek, kemudian membangun string dari array itu.
ETHproduk
Daripada menginisialisasi oke objek baru, bisakah Anda menggunakan kembali array yang diteruskan mapdengan menggunakan parameter ke-3?
Arnauld
@Arnauld Hmm, saya kira itu berhasil karena pertanyaannya menjamin huruf kecil, jadi saya tidak akan mengacaukan elemen array dengan jumlah ...
Neil
Saya pikir (n,s)=>s.replace(/./g,(_,i)=>i<n?[...s].map((c,j,a)=>j%n-i||(a[c]=-~a[c])>m&&(m++,r=c),m=0)&&r:'')harus menyimpan 3 byte lagi. (Atau 4 byte dengan menggunakan sintaks currying.)
Arnauld
@Arnauld Tidak buruk, tapi saya mencukur dua byte lebih jauh. (Dan juga memperbaiki jumlah byte saya; sebuah baris baru membuntuti mereka.)
Neil
3

Jelly , 12 11 byte

s@ZċþZMḢ$€ị

Cobalah online!

Bagaimana itu bekerja

s@ZċþZMḢ$€ị  Main link. Arguments: n (integer), s (string)

s@           Split swapped; split s into chunks of length n.
  Z          Zip/transpose, grouping characters that correspond to repetitions.
   ċþ        Count table; for each slice in the previous result, and each character
             in s, count the occurrences of the character in the group.
             This groups by character.
     Z       Zip/transpose to group by slice.
        $€   Map the two-link chain to the left over the groups.
      M        Find all maximal indices.
       Ḣ       Head; pick the first.
          ị  Index into s to retrieve the corresponding characters.
Dennis
sumber
Apakah Jelly punya komentar?
caird coinheringaahing
Tidak.
Dennis
2

Pyth, 11 byte

meo/dNd.TcF

Mengambil input sebagai s,ndan output sebagai daftar karakter.

Penjelasan

meo/dNd.TcF
         cFQ   Split s into chunks of length n.
       .T      Transpose.
m o/dNd        Sort characters in each string by frequency.
 e             Take the most common.

sumber
2

Japt , 16 15 byte

Disimpan 1 byte berkat @obarakon

Ç=VëUZ)¬ñ!èZ o

14 byte kode + 1 byte untuk -Pbendera. Cobalah online!

Tidak terseret dan penjelasan

 Ç   =VëUZ)¬ ñ!èZ o
UoZ{Z=VëUZ)q ñ!èZ o}
                          Implicit: U = input number, V = input string
Uo                        Create the range [0...U).
  Z{               }      Map each item Z by this function:
      VëUZ                  Take every U'th char of V, starting at index Z.
    Z=    )                 Call the result Z.
           q                Split the result into chars.
             ñ!èZ           Sort each char X by the number of occurrences of X in Z.
                  o         Pop; grab the last item (the most common char).
                      -P  Join the results (array of most common chars) into a string.
Produksi ETH
sumber
Saya pikir Anda dapat menggantikan gJdengano
Oliver
@obarakon Itu jenius, terima kasih!
ETHproduk
1

Python 2 , 132 byte

from itertools import*
p,k=input()
b=l=len(p)
for i in combinations(p,k):
 x=sum(x!=y for x,y in zip(p,i*l))
 if x<b:b,o=x,i
print o

Cobalah online!

tongkat
sumber
1

05AB1E , 17 byte

Iôð«øvy{.¡é®èÙJðÜ

Cobalah online!

Penjelasan

Iô                 # split 2nd input in chunks of 1st input size
  ð«               # append a space to each
    ø              # zip
     vy            # for each y in the zipped list
       {           # sort the string
        .¡         # group into chunks of consecutive equal elements
          é        # sort by length
           ®è      # pop the last element (the longest)
             Ù     # remove duplicate characters from the string
              J    # join the stack into one string
               ðÜ  # remove any trailing spaces
Emigna
sumber
1

PHP, 245 Bytes

function p($c,$s,$r=""){global$a;if(($c-strlen($r)))foreach(str_split(count_chars($s,3))as$l)p($c,$s,$r.$l);else{for($v=str_pad("",$w=strlen($s),$r);$z<$w;)$t+=$v[$z]==$s[$z++];$a[$t][]=$r;}}p($argv[1],$argv[2]);ksort($a);echo join(" ",end($a));

Versi Online

Kerusakan

function p($c,$s,$r=""){
    global$a;
    if(($c-strlen($r)))  # make permutation
        foreach(str_split(count_chars($s,3))as$l)
            p($c,$s,$r.$l); #recursive
    else{
        for($v=str_pad("",$w=strlen($s),$r);$z<$w;) 
        $t+=$v[$z]==$s[$z++]; #compare strings
        $a[$t][]=$r; # insert value in array
    }
}
p($argv[1],$argv[2]); #start function with the input parameter
ksort($a); # sort result array 
echo join(" ",end($a)); #Output
Jörg Hülsermann
sumber
1

Haskell, 84 byte

import Data.Lists
f n=map(argmax=<<(length.).flip(filter.(==))).transpose.chunksOf n

Contoh penggunaan:

f 10 "bbbbacacbcedecdbbbdebdaedcecdabcebddbdcecebbeeaacdebdbebaebcecddadeeedbbdbbaeaaeebbedbeeaeedadeecbcd"
"ebbbdbeece"

Pisahkan string input menjadi potongan-potongan yang panjang n, transpos dan temukan untuk setiap sublist elemen yang paling sering.

nimi
sumber
1

Röda , 68 byte

f s,n{seq 0,n-1|{|i|sort s/"",key={|c|x=s[i::n]x~=c,"";[#x]}|head}_}

Cobalah online!

Ini adalah fungsi yang mencetak output tanpa tertinggal baris baru.

Ini terinspirasi oleh jawaban ini .

fergusq
sumber