最適なパターンを見つける


33

以下のような小文字で構成される文字列sが与えられた場合

aabaaababbbbaaba

およびなどの正の整数n4、長さnの文字列tを出力します。これにより、tsの長さまで繰り返されたときに、できるだけ多くの共通文字を持ちます。与えられた例の場合、最適な出力はaaba、ターゲット文字列と共通の13文字を持っているため、です。

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

可能なtはそれ以上ありません。ただし、にはaaaaaab、2つの出力があります。aaaaおよびaabaには、ターゲット文字列と共通の6文字があります。

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

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

どちらaaaaaaba、または出力可能、または必要に応じて両方を出力できます。sは繰り返されないことに注意してください。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品質です。よくやった!
マーティンエンダー

末尾の文字のみが無視されると仮定していますか?したがって、次のような先頭の文字を無視することはできません。:2 abb -> baとして構築される場合、(b)[ab]a先頭(b)は無視され、[ab]一致します。
ケビンCruijssen

@KevinCruijssenそうですね、パターンは最初から繰り返し始めなければなりません。
-ETHproductions

回答:


11

ゼリー、11バイト

sZµṢŒrUṀṪµ€

オンラインでお試しください!

これでデニスに勝つことを期待していなかったので、それを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バイト長です)。

Jelly、@ Dennisのソリューションに基づく10バイト

⁸ċ$ÞṪ
sZÇ€

オンラインでお試しください!

これは、@ Dennisのソリューションと私自身のソリューションの組み合わせです。そのソリューションには5バイトモードがあり、このソリューションを盗みました。(に基づいたソリューションはすでにありましたが⁸ċ、6バイトを下回ることはできませんでしたÞ。使用することを考えていませんでした。)

説明

µ…µ€およびÇ€前の行の)両方とも3バイト長(後者には改行が必要)で、同等です。通常、前者を使用しますが、後者を使用すると、引数に言及するために使用できるため、より柔軟です。

これによりÞ⁸ċ)の出現回数でソート()し、最後の要素()を取得して、わずか5文字でモードを見つけることができます。


5
デニスが自分の言語でゴルフをするのは素晴らしい仕事です!:P
ハイパーニュートリノ

10

Mathematica、51バイト

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

入力と出力は文字のリストです。

トランスポーズのラインのモードにも基づいています。私は、彼らがコードゴルファーをいじめるためCommonest だけにリストのモードの組み込みを呼び出したと信じています。


少なくともそれはより短いバイトだMostCommon...
ETHproductions

7

Python 3、99、73 61バイト

-12、@ Rodへのthx

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 Dropping ''.join(...)はジェネレーターを返しますが、出力が許可されているかどうかはわかりません。
L3viathan

@ L3viathan動作するにはpython2.7である必要があり、他のコメントに追加されました
Rod

これがどのように機能するかの説明を書くことができますか?
デッドポッサム

2
@Rod文字列のリストは、可能な解決策をすべて返すかどうかの質問でのみ許可されます。それが私が意味するものだと思ったものです。
mbomb007

5

Python 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-組み合わせの1つで、len(S)Sより長く保証される文字列を作成するために乗算されます

zip各文字列の文字のタプルを作成Sし、s*len(S)そして(長い別のものより1つの文字列の場合には)一致させることができないすべての文字を無視します

したがってmax、最大合計を生成する組み合わせを選択します


1
あなたが使用する必要はありません[]、また、あなたが使用している関数の内部リストの内包に1 for ... if <cond>あなたが直接使用することができ<cond> for ...、それが上の使用されるのでsum、PythonはかかりますTrueように1Falseのように0
ロッド

@ロッドあり​​がとうございます!私の答えをもっと絞ると、あなたの答えに変わります、アプローチは同じです:Dだから私は今何か違うことを試みています
デッドポッサム

3:うん、ちょうどあなたがあなたの将来の回答に使用できるようにと言って
ロッド

1
ラムダに切り替えると、7バイト節約されます。
L3viathan

1
@DeadPossum 彼は、この意味(ノートフッターやヘッダーを)はい、機能は有効な回答であるあなたがそのラムダ場合、でも必要はありませんf=(それは再帰的でない限り)
ロッド

5

JavaScript(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バイトを2回保存しました。すべての非改行文字で機能する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、3番目のパラメーターを使用して、渡された配列を再利用できますか?
アーナルド

@Arnauldうーん、質問は小文字を保証するのでうまくいくと思うので、配列要素とカウントを混同しないようにします...-
ニール

(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悪くはないが、さらに2バイト削った。(また、バイトカウントを修正しました。末尾の改行がそれら
ニール

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.

Jellyにはコメントがありますか?
22:05にコイナーリンガーをケア

いいえ、違います。
デニス

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

Japt16 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

Haskell、84バイト

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

使用例:

f 10 "bbbbacacbcedecdbbbdebdaedcecdabcebddbdcecebbeeaacdebdbebaebcecddadeeedbbdbbaeaaeebbedbeeaeedadeecbcd"
"ebbbdbeece"

入力文字列をn、サブリストごとに最も頻繁な要素であるlength 、transposeおよびffindのチャンクに分割します。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.