Tìm mô hình tối ưu


33

Cho một xâu s gồm chữ thường, chẳng hạn như

aabaaababbbbaaba

và một số nguyên dương n , chẳng hạn như 4, xuất ra một chuỗi t dài n sao cho khi t được lặp lại với độ dài của s , chúng có càng nhiều ký tự chung càng tốt. Đối với ví dụ đã cho, đầu ra tối ưu sẽ là bởi vì nó có mười ba ký tự chung với chuỗi đích:aaba

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

và không có khả năng t có nhiều hơn. Tuy nhiên, đối với aaaaaab, có hai đầu ra có thể: aaaaaaba, mỗi đầu ra có 6 ký tự chung với chuỗi đích:

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

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

Hoặc là aaaahoặc aabacó thể xuất ra, hoặc cả hai nếu bạn muốn. Lưu ý rằng s không bao giờ lặp lại; dấu vết atrong cả hai giá trị lặp lại của t chỉ đơn giản là bị bỏ qua.

Các trường hợp thử nghiệm

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

Quy tắc

  • Bạn có thể giả sử đầu vào sẽ chỉ là một chuỗi các chữ cái thường không trống và một số nguyên dương không lớn hơn độ dài của chuỗi.
  • Bạn có thể lấy đầu vào ở bất kỳ định dạng tiêu chuẩn nào và theo thứ tự.
  • Bạn có thể xuất ra một chuỗi hoặc nhiều chuỗi dưới dạng một mảng, được phân tách bằng các dòng mới hoặc dấu cách, v.v.
  • Mã của bạn phải hoàn thành cho mỗi trường hợp thử nghiệm trong vòng chưa đầy 1 phút trên bất kỳ máy tính khá hiện đại nào.
  • Đây là , vì vậy hãy làm cho mã của bạn càng ngắn càng tốt.

2
Thách thức này là chất lượng Zgarb. Công việc tốt đẹp!
Martin Ender

Tôi đang giả sử chỉ có các ký tự dấu được bỏ qua? Vì vậy, bạn không được phép bỏ qua các nhân vật hàng đầu như thế này: 2 abb -> banơi mà nó được xây dựng như (b)[ab]a: hàng đầu (b)bị bỏ qua, [ab]phù hợp.
Kevin Cruijssen

@KevinCruijssen Phải, mô hình phải bắt đầu lặp lại từ đầu.
Sản phẩm ETH

Câu trả lời:


11

Thạch , 11 byte

sZµṢŒrUṀṪµ€

Hãy thử trực tuyến!

Không mong đợi đánh bại Dennis về điều này, vì vậy đã cố gắng FGITW nó (sau khi thử một vài khả năng; có nhiều hơn một cách để thực hiện 11). Tôi đến ngắn hơn, nhiều đến ngạc nhiên.

Lấy chuỗi sau đó tính là đối số dòng lệnh. Đầu ra trên thiết bị xuất chuẩn.

Giải trình

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)

Điều này sử dụng cái nhìn sâu sắc rằng chữ cái ở mỗi vị trí của mẫu phải là chữ cái phổ biến nhất tương ứng với vị trí đó. Chúng ta có thể tìm thấy các chữ cái tương ứng với một mẫu cụ thể thông qua việc chia thành các nhóm có kích thước mẫu và hoán vị. Lý do chính khiến giải pháp này quá dài là vì Jelly dường như không có cách nào ngắn để tìm chế độ của danh sách (Tôi đã thực hiện một số lần thử, nhưng tất cả chúng đều dài ít nhất sáu byte).

Jelly , 10 byte, dựa trên giải pháp @Dennis '

⁸ċ$ÞṪ
sZÇ€

Hãy thử trực tuyến!

Đây là sự kết hợp giữa giải pháp của @Dennis và của riêng tôi; có một chế độ năm byte trong giải pháp đó, mà tôi đã đánh cắp cho giải pháp này. (Tôi đã có các giải pháp dựa trên ⁸ċ, nhưng không thể có dưới sáu byte với nó; tôi đã không nghĩ đến việc sử dụng Þ.)

Giải trình

µ…µ€Ç€(với dòng trên dòng trước) đều dài ba byte (cái sau cần một dòng mới) và tương đương. Thông thường tôi sử dụng cái trước, nhưng cái sau linh hoạt hơn, vì nó cho phép bạn sử dụng để đề cập đến đối số.

Điều này cho phép sắp xếp ( Þ) theo số lần xuất hiện trong ( ⁸ċ), sau đó lấy phần tử cuối cùng ( ), để tìm chế độ chỉ trong năm ký tự.


5
Công việc tuyệt vời vượt xa Dennis bằng ngôn ngữ của chính mình! : P
HyperNeutrino

10

Toán học, 51 byte

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

Đầu vào và đầu ra là danh sách các ký tự.

Cũng dựa trên các chế độ của các đường chuyển vị. Tôi tin rằng họ đã gọi tích hợp sẵn cho chế độ của một danh sách Commonest chỉ để kích thích những người chơi gôn.


Ít nhất đó là một byte ngắn hơn MostCommon...
ETHproductions

7

Python 3, 99, 73 61 byte

-12, thx đến @Rod

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

Cùng một ý tưởng, nhưng viết lại nó để loại bỏ câu lệnh nhập.

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

Nguyên

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

Giải trình:

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

bạn có thể chuyển sang python2.7 và thả xuống ''.join()để trả về danh sách các chuỗi
Rod

@Rod Droppping ''.join(...)sẽ khiến nó trả về một trình tạo, không chắc chắn nếu đó là đầu ra được phép.
L3viathan

@ L3viathan cần phải là python2.7 để hoạt động, được thêm vào nhận xét khác
Rod

Bạn có thể viết một số lời giải thích về cách thức này hoạt động?
Dead Possum

2
@Rod Một danh sách các chuỗi chỉ được phép trong câu hỏi nếu bạn trả về tất cả các giải pháp có thể. Đó là những gì tôi muốn nói.
mbomb007

5

Con trăn 2, 106

Bây giờ là một câu trả lời khác nhau! Tôi đã suy nghĩ về một (gần như) người di chuyển từ ăn xin. Bây giờ thậm chí còn ngắn hơn, dựa trên việc sử dụng zip của @Rod.

Cảm ơn @ L3viathan và @Rod đã làm rõ về việc sử dụng lambdas làm câu trả lời

Dùng thử trực tuyến

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*

Giải trình:

combinations(S,N) tạo tất cả các kết hợp độ dài N từ các ký tự của S

max()có đối số keydùng làm hàm đầu vào để sử dụng để so sánh các phần tử

lambda s:sum(x==y for x,y in zip(S,s*len(S))) thông qua chức năng như vậy

Lambda này đếm số lượng ký tự trùng khớp trong danh sách các bộ dữ liệu, được tạo bởi zip(S,s*len(S))

s- một trong những kết hợp và nó được nhân lên len(S)để tạo ra chuỗi được đảm bảo dài hơn S

ziptạo các bộ ký tự của mỗi chuỗi Ss*len(S)bỏ qua tất cả các ký tự không thể khớp (trong trường hợp một chuỗi dài hơn chuỗi khác)

Vì vậy, maxchọn kết hợp, tạo ra tổng tối đa


1
bạn không cần phải sử dụng []trong danh sách hiểu bên trong chức năng, cũng có thể bạn đang sử dụng 1 for ... if <cond>bạn có thể sử dụng trực tiếp <cond> for ...vì nó sẽ được sử dụng trên sum, trăn sẽ mất Truenhư 1Falsenhư0
Rod

@Rod Cảm ơn bạn! Nếu tôi trả lời câu trả lời của mình nhiều hơn, nó sẽ chuyển thành câu trả lời của bạn, cách tiếp cận cũng vậy: D Vì vậy, tôi đang thử một thứ gì đó khác biệt ngay bây giờ
Dead Possum

Đúng, chỉ cần nói để bạn có thể sử dụng cho câu trả lời trong tương lai của mình: 3
Rod

1
Chuyển sang lambda sẽ tiết kiệm 7 byte.
L3viathan

1
@DeadPossum Ông có ý này (lưu ý chân trang và tiêu đề) và vâng, một hàm là một câu trả lời hợp lệ , nếu đó là lambda bạn thậm chí không cầnf= (trừ khi nó được đệ quy)
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)

Đã lưu 3 byte hai lần nhờ @Arnauld. Giải pháp 97 byte hoạt động với tất cả các ký tự không phải dòng mới:

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

Giải pháp 104 byte trước đây cũng hoạt động với các ký tự dòng mới:

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

Rất đẹp. Tôi đã đưa ra một giải pháp để tham khảo khi thêm các trường hợp thử nghiệm và đưa ra 122 byte, lặp qua từng char, lưu số đếm trong một mảng các đối tượng, sau đó xây dựng chuỗi từ mảng đó.
Sản xuất ETH

Thay vì khởi tạo omột đối tượng mới, bạn có thể sử dụng lại mảng được truyền mapbằng cách sử dụng tham số thứ 3 của nó không?
Arnauld

@Arnauld Hmm, tôi đoán rằng nó hoạt động vì câu hỏi đảm bảo các chữ cái viết thường, vì vậy tôi sẽ không nhầm lẫn các yếu tố mảng với số đếm ...
Neil

Tôi nghĩ (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:'')nên tiết kiệm thêm 3 byte. (Hoặc 4 byte bằng cách sử dụng cú pháp currying.)
Arnauld

@Arnauld Không tệ, nhưng tôi đã cạo thêm hai byte. (Và cũng đã sửa số byte của tôi; một dòng mới đang bị loại bỏ.)
Neil

3

Thạch , 12 11 byte

s@ZċþZMḢ$€ị

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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.

Jelly có ý kiến ​​gì không?
caird coinheringaahing

Không nó không.
Dennis

2

Bình thường, 11 byte

meo/dNd.TcF

Lấy đầu vào là s,nvà đầu ra dưới dạng một danh sách các ký tự.

Giải trình

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.

2

Japt , 16 15 byte

Đã lưu 1 byte nhờ @obarakon

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

14 byte mã + 1 byte cho -Pcờ. Hãy thử trực tuyến!

Ung dung và giải thích

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

Tôi nghĩ bạn có thể thay thế gJbằngo
Oliver

@obarakon Đó là thiên tài, cảm ơn!
Sản xuất ETH


1

05AB1E , 17 byte

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

Hãy thử trực tuyến!

Giải trình

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

1

PHP, 245 byte

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));

Phiên bản trực tuyến

Phá vỡ

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

1

Haskell, 84 byte

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

Ví dụ sử dụng:

f 10 "bbbbacacbcedecdbbbdebdaedcecdabcebddbdcecebbeeaacdebdbebaebcecddadeeedbbdbbaeaaeebbedbeeaeedadeecbcd"
"ebbbdbeece"

Chia chuỗi đầu vào thành các đoạn có độ dài n, hoán vị và tìm kiếm cho mỗi danh sách con thành phần thường xuyên nhất.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.