최적의 패턴 찾기


33

주어진 문자열 s의 같은 소문자로 구성

aabaaababbbbaaba

ts 의 길이로 반복 될 때 가능한 한 많은 문자를 갖도록 길이 n 스트링 t를 출력하는 것과 같은 양의 정수 n . 주어진 예제의 경우 대상 문자열과 공통으로 13 개의 문자가 있기 때문에 최적 출력은입니다 .4aaba

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

그리고 가능한 t 는 더 이상 없습니다 . 그러나 대해 aaaaaab:가 두 개의 가능한 출력은 다음 aaaaaaba각 대상 문자열 6 개 공통 문자를 갖는 :

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

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

하나 aaaa또는 aaba출력, 또는 둘 모두 당신이 원하는 경우에 할 수있다. 참고 이야 지금까지 반복하지 않는다; t의a 반복되는 두 값의 후행 은 단순히 무시됩니다.

테스트 사례

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

규칙

  • 입력이 비어 있지 않은 소문자 문자열이고 문자열 길이보다 크지 않은 양의 정수라고 가정 할 수 있습니다.
  • 표준 형식과 순서에 상관없이 입력을받을 수 있습니다.
  • 줄 바꿈 또는 공백 등으로 구분하여 단일 문자열 또는 하나 이상의 배열 형태로 출력 할 수 있습니다.
  • 코드는 최신 컴퓨터에서 1 분 이내에 각 테스트 사례마다 완료해야합니다.
  • 이것은 이므로 가능한 한 코드를 짧게 만드십시오.

2
이 도전은 Zgarb 품질입니다. 잘 하셨어요!
Martin Ender

후행 문자 만 무시된다고 가정합니다. 따라서 다음과 같이 선행 문자를 무시할 수 없습니다. 다음과 같이 2 abb -> ba구성됩니다 (b)[ab]a. 선행 (b)은 무시 [ab]되고 일치합니다.
케빈 크루이 센

@KevinCruijssen 맞습니다. 패턴은 처음부터 반복되어야합니다.
ETHproductions

답변:


11

젤리 , 11 바이트

sZµṢŒrUṀṪµ€

온라인으로 사용해보십시오!

이것에 대해 Dennis를 이길 것으로 기대하지 않았으므로 FGITW를 시도했습니다 (여러 가지 가능성을 시도한 후 11 가지 방법이 있습니다). 놀랍게도 짧아졌습니다.

문자열을 가져온 다음 개수를 명령 줄 인수로 사용합니다. stdout에서 출력합니다.

설명

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)

패턴의 각 위치에있는 문자가 해당 위치에 해당하는 가장 일반적인 문자 여야한다는 통찰력을 사용합니다. 패턴 크기 그룹으로 분할하고 조옮김을 통해 특정 패턴에 해당하는 문자를 찾을 수 있습니다. 이 솔루션이 너무 긴 주된 이유는 Jelly가 목록 모드를 찾는 짧은 방법이없는 것 같습니다 (여러 시도했지만 6 바이트 이상입니다).

@Dennis '솔루션을 기반으로하는 Jelly , 10 바이트

⁸ċ$ÞṪ
sZÇ€

온라인으로 사용해보십시오!

이것은 @Dennis의 솔루션과 내 자신의 조합입니다. 이 솔루션에는 5 바이트 모드가 있었고이 솔루션을 훔쳤습니다. (나는 이미을 기반으로 한 솔루션을 가지고 ⁸ċ있었지만 6 바이트 이하로는 얻을 수 없었습니다 Þ.

설명

µ…µ€그리고 Ç€( 이전 줄에서) 3 바이트 길이 (후자는 줄 바꾸기가 필요함)이며 이에 상응하는 것입니다. 일반적으로 전자를 사용하지만 후자를 더 유연하게 사용할 수 있으므로 인수를 언급하는 데 사용할 수 있습니다 .

이로써 (분류 할 수 Þ있는 발생의 숫자로) ( ⁸ċ(마지막 요소를 가지고 다음) 불과 5 문자 모드를 찾기 위해).


5
자신의 언어로 데니스를 아웃 고프 닝하는 것이 좋습니다! : P
HyperNeutrino

10

수학, 51 바이트

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

입력 및 출력은 문자 목록입니다.

또한 조옮김 선의 모드를 기반으로합니다. 나는 그들이 코드 골퍼를 뱉을 Commonest 목적 으로 목록 모드로 내장 기능을 호출했다고 생각 합니다.


적어도 그것은 바이트보다 짧습니다 MostCommon...
ETHproductions

7

파이썬 3, 99, 73 61 바이트

-12, @Rod까지

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

같은 생각이지만 import 문을 제거하기 위해 다시 작성했습니다.

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

기발한

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

설명:

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

python2.7로 전환하여 ''.join()문자열 목록을 반환하도록 드롭 다운을 할 수 있습니다
Rod

@Rod Dropping ''.join(...)은 생성기를 반환하므로 출력이 허용되는지 확실하지 않습니다.
L3viathan

@ L3viathan python2.7이어야 작동하고 다른 의견에 추가
Rod

이것이 어떻게 작동하는지에 대한 설명을 쓸 수 있습니까?
Dead Possum

2
@Rod 문자열 목록은 가능한 모든 솔루션을 반환하는 경우에만 질문에 허용됩니다. 그것이 내가 의미 한 바입니다.
mbomb007

5

파이썬 2, 106

이제는 다른 대답입니다! 나는 구걸에서 하나 (거의) 라이너에 대해 생각하고있었습니다. @Rod의 zip 사용량을 기준으로 더 짧아졌습니다.

람다를 답변으로 사용하는 것에 대한 설명을 @@ L3viathan 및 @Rod에게 감사합니다

온라인으로 사용해보십시오

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*

설명:

combinations(S,N) S의 문자에서 길이 N의 모든 조합을 만듭니다.

max()key요소를 비교하는 데 사용할 입력 함수로 사용되는 인수 가 있습니다.

lambda s:sum(x==y for x,y in zip(S,s*len(S))) 그러한 기능으로 전달

이 람다는 튜플 목록에서 일치하는 문자 수를 계산합니다. zip(S,s*len(S))

s-조합 중 하나이며 len(S)S보다 길게 보장되는 문자열을 생성 하여 곱합니다.

zip각 문자열의 문자 튜플 생성 Ss*len(S)과 (이상 다른 것보다 하나의 문자열의 경우) 일치시킬 수없는 모든 문자를 무시

그래서 max이 선택하는 조합, 그 생산 최대 합


1
당신이 사용할 필요가 없습니다 [], 또한 당신이 사용하는 기능 내부 지능형리스트에 1 for ... if <cond>직접 사용할 수있는 <cond> for ...가에 사용되기 때문에 sum, 파이썬은 걸릴 것 True1False같은0
로드

@로드 감사합니다! 좀 더 내 대답을 sqeeze한다면, 그것은 당신의 대답으로 변환됩니다, 접근 방식은 동일합니다 : D 그래서 지금은 뭔가 다른 노력하고있어
죽은 포섬

네, 단지 미래의 답변에 사용할 수 있도록 말하기 : 3
Rod

1
람다로 전환하면 7 바이트가 절약됩니다.
L3viathan

1
@DeadPossum 그는이 의미 (바닥 글 및 헤더에주의를) 및 예, 함수는 유효한 대답은 , 그 람다 당신이 경우 에도 필요하지 않습니다f= (그것의 재귀하지 않는 한)
로드

5

자바 스크립트 (ES6), 104 (101) 94 바이트

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

@Arnauld 덕분에 3 바이트를 두 번 절약했습니다. 개행 문자 이외의 모든 문자와 작동하는 97 바이트 솔루션 :

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

이전 104 바이트 솔루션은 개행 문자와도 작동합니다.

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

아주 좋아요 테스트 사례를 추가 할 때 참조 용 솔루션을 골프화하고 122 바이트에서 모든 문자를 반복하여 카운트를 객체 배열에 저장 한 다음 해당 배열에서 문자열을 작성했습니다.
ETHproductions

o새 객체를 초기화 하는 대신 map세 번째 매개 변수를 사용하여 전달 된 배열을 재사용 할 수 있습니까?
Arnauld

@Arnauld 흠, 질문이 소문자를 보장하기 때문에 효과가 있다고 생각합니다. 따라서 배열 요소를 카운트와 혼동하지 않습니다 ...
Neil

(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:'')3 바이트를 더 절약해야 한다고 생각 합니다. (또는 카레 구문을 사용하여 4 바이트)
Arnauld

@Arnauld 나쁘지는 않지만 2 바이트를 더 줄였습니다. (또한 바이트 수를 수정했습니다. 후행 줄 바꿈으로 인해 줄이 끊어졌습니다.)
Neil

3

젤리 , 12 11 바이트

s@ZċþZMḢ$€ị

온라인으로 사용해보십시오!

작동 원리

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.

젤리는 의견이 있습니까?
caird coinheringaahing

아니 그렇지 않아.
Dennis

2

Pyth, 11 바이트

meo/dNd.TcF

s,n문자 목록으로 입력을 받아서 출력합니다.

설명

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 바이트

@obarakon 덕분에 1 바이트 절약

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

14 바이트의 코드 + -P플래그의 경우 1 바이트 온라인으로 사용해보십시오!

언 골프와 설명

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

나는 당신이 바꿀 수 있다고 생각 gJo
올리버

@obarakon 천재입니다, 감사합니다!
ETHproductions


1

05AB1E , 17 바이트

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

온라인으로 사용해보십시오!

설명

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 바이트

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

온라인 버전

고장

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

하스켈, 84 바이트

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

사용 예 :

f 10 "bbbbacacbcedecdbbbdebdaedcecdabcebddbdcecebbeeaacdebdbebaebcecddadeeedbbdbbaeaaeebbedbeeaeedadeecbcd"
"ebbbdbeece"

입력 문자열을 length의 덩어리로 n나누고 각 하위 목록에 대해 가장 빈번한 요소를 바꿉니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.