文字列内の文字の最長実行


19

あなたの課題:文字列s、文字を受け取り、inのc最長実行の長さを見つける関数を作成します。実行の長さはになります。csl

ルール

  • 場合はs長さが0であるか、c空である、l0にしてください。
  • cin のインスタンスがない場合、0 slなければなりません。
  • 標準の抜け穴標準のI / Oルールが適用されます。
  • s sの実行中cの場所に関係lなく、同じである必要があります。
  • 印刷可能なASCII文字は、sとに表示できますc

テストケース

s,c --> l
"Hello, World!",'l'  -->  2
"Foobar",'o'         -->  2
"abcdef",'e'         -->  1
"three   spaces",' ' -->  3
"xxx xxxx xx",'x'    -->  4
"xxxx xx xxx",'x'    -->  4
"",'a'               -->  0
"anything",''        -->  0

勝者

と同様に、各言語の最短回答が勝ちます。



あなたは、空のエッジケース含めることができますsし、c非空に含まれていないs、あなたのテストケースでは?
マーティンエンダー

s/に表示できる文字の範囲はc
マーティンエンダー

6
c空にできますか?多くの言語では、文字は特別なセマンティクスを持つ単なる整数であり、空の整数を実際に持つこともできません。
マーティンエンダー

14
それは私には本当に意味がありません。あなたのテストケースは、それをサポートする必要があることを示唆しています。サポートする必要がない場合、必要な出力を指定することは意味がありません。その場合、ソリューションが何か他のことをするとサポートされないと言うことができるからです。
マーティンエンダー

回答:


12

05AB1E、5バイト

コード:

SQγOM

05AB1Eエンコードを使用します。オンラインでお試しください!

説明:

SQ      # Check for each character if it is equal to the second input
  γ     # Split the list of zeros and ones into groups
   O    # Sum each array in the arrays
    M   # Get the maximum

2
いい解決策!私はこのようにそれを行う方法があることを知っていました、私はそれを考えることができませんでした。
ライリー

γ¢M思ったほどのパフォーマンスではなく、3バイトだと思っていました。
魔法のタコUr

8

Mathematica、35バイト

Max[Tr/@Split@Boole@Thread[#==#2]]&

文字のリストと別の文字を入力として受け取り、非負の整数を返す純粋な関数。配列を分割する前に特殊文字と等しいかどうかをテストする必要があるというAdnanの観察を使用して、最初の努力で改善しました(賛成票を投じてください!)。

Thread[#==#2]最初の引数の各入力文字が、2番目の引数として指定された文字と等しいかどうかを確認します。Boole結果TrueのsとFalsesを1sと0sに変換します。Splitリストを連続した要素の実行に分割します。Tr/@各サブリストを合計しMax、勝者を見つけます。(どのようにMax機能するのか、最初の引数が空のリストである場合、この関数はを返します-∞

最初の提出(51バイト)

Max[Split@#/.a:{c_String..}:>Boole[c==#2]Length@a]&

Split@#{{"t"}, {"h"}, {"r"}, {"e", "e"}, {" ", " ", " "}, {"s"}, {"p"}, {"a"}, {"c"}, {"e"}, {"s"}}4番目のテストケースのように、入力を連続した文字の実行に分割します。/.a:{c_String..}:>各部分式置き換えるa繰り返し文字のリストであるcことでLength@a乗じたBoole[c==#2]です、1あればc入力文字に等しく、0それ以外を。次にMax、答えを抽出します。


7

Japt20 18 15バイト

fV+Vî+)ª0)n o l

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

obarakonとETHproductionsのおかげで5バイト節約


1
私はしばらくの間自分のソリューションで遊んでみましたが、最終的にはほぼあなたのものになりましたが、より短いものになりました。使用する場合fV+Vî+)...残りを理解することができます:
ETHproductions

@ETHproductions "If s is of length 0 or c is empty, l should be 0"、私はそれを文字通りあまりにも取っているかもしれません
トム

ああ、のsインスタンスが含まれていないときはいつでも失敗することに気付いていませんでしたc
ETHproductions

7

Python、38バイト

f=lambda s,c:+(c in s)and-~f(s,c+c[0])

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

デニスcは、乗算する数値を再帰的に更新するのではなく、重複した文字列に更新することで3バイトを節約しcました。


1
f=lambda s,c:c in s and-~f(s,c+c[0])6バイトを節約します(Falseが許可されていない場合は3バイト)。
デニス


4

Haskell、43 39バイト

f c=maximum.scanl(\n k->sum[n+1|c==k])0

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

文字列を実行し、現在の文字を、等しい場合は増加するカウンターで置き換え、そうでない場合はcリセットし0ます。リストの最大値を取得します。

4バイトの@xnorに感謝します。


できますsum[n+1|c==k]
-xnor

@xnor:いいね!私は*fromEnum(c==k)、ポイントフリーとラムダの両方を試しましたが、常に2バイトまたは3バイト長かったです。
-nimi

4

C#116 115バイト

私の最初のコードゴルフ

最初の送信はスニペットであり、正規表現に必要な名前空間が欠落していたため、編集されました

特別な正規表現の意味を持つ文字をサポートするためのEdit#2完全な書き換え

使用System.Linq; s => c => System.Text.RegularExpressions.Regex.Replace(s、 "[^" + c + "]"、++ c + "")。Split(c).Max(x => x.Length);

using System.Linq;s=>c=>{var r=(char)(c-1);return string.Join("",s.Select(x=>x==c?c:r)).Split(r).Max(x=>x.Length)};

3
私はC#を知りませんが、あなたのコードは変数cを期待sし、事前定義されているようです。これは「コードスニペット」と呼ばれ、許可されていません。コードを匿名関数として再構築するか、これらの変数を入力に設定することができます。両方とも許可されています。
小麦ウィザード

それは動作しますか?(上記の編集を参照)
ほうき

1
繰り返しますが、私はC#を知りませんが、そのように見えます。あなたは私たちのチェックアウトする場合がありますヒントを C#でのゴルフのためにここに C#での多くの経験豊富なアドバイスを。
小麦ウィザード

リンクをありがとう!私は間違いなくC#のヒントを熟読します
ほうき

3
こんにちは、C#でのゴルフに関するいくつかの一般的なコメントです(s,c)=>。関数をとして定義できます。System.Text.RegularExpressions.Regex関数の直前にusingステートメントを使用するか、追加する 必要があります。
-LiefdeWen

4

JavaScript(ES6)、54 53 51バイト

@Neilのおかげで-2バイト@apsillersのおかげで
-1バイト

s=>c=>[...s].map(x=>j=(i=x==c&&i+1)>j?i:j,i=j=0)&&j

カリー化構文の入力を受け取りますf("foobar")("o")

テストスニペット

f=
s=>c=>[...s].map(x=>j=(i=x==c&&i+1)>j?i:j,i=j=0)&&j
String: <input id=I> Letter: <input id=J maxlength=1 size=1> <button onclick='O.innerHTML+=`f("${I.value}")("${J.value}") = ${f(I.value)(J.value)}\n`'>Run</button><pre id="O"></pre>

evaland を使用する別のオプションfor(54バイト)

s=>c=>eval("i=j=0;for(x of s)i=x==c&&i+1,i>j?j=i:0;j")

正規表現を使用した古い回答(85バイト)

s=>c=>c?Math.max(...s.match(eval(`/${/\w/.test(c)?c:"\\"+c}*/g`)).map(x=>x.length)):0

1
私は考えるx==c?i++:i=0だけでことができますi=x==c&&i+1ので、false上の結果x==cの比較は次のように扱われます0(を含む、任意の数のため、戻り値になることはありません数値比較と増加のため0に、j常にゼロのようなよりも優先されますfalsei
apsillers

@apsillersありがとう、更新されましたが、戻り値にならないことについてどういう意味ですか?
ジャスティンマリナー

混乱させて申し訳ありません; 変更によってプログラムが復帰することはないことを説明していましたfalse(チャレンジでは常に数値を返す必要があるため)
-apsillers

1
s=>c=>[...s].map(x=>j=(x!=c?i=0:++i)>j?i:j,i=j=0)&&j数バイト節約できるようです。
ニール

1
申し訳ありませんが、間違ったコードを投稿しました。投稿するf=s=>c=>[...s].map(x=>j=(i=x==c&&i+1)>j?i:j,i=j=0)&&jつもりでしたが、これは1バイト短くなっています。
ニール

4

JavaScript(Firefox 30-57)、75 72バイト

(s,c)=>Math.max(0,...(for(s of s.split(/((.)\2*)/))if(s[0]==c)s.length))

ES6互換スニペット:

f=
(s,c)=>Math.max(0,...s.split(/((.)\2*)/).filter(s=>s[0]==c).map(s=>s.length))
<div oninput=o.textContent=f(s.value,c.value)><input id=s><input id=c maxlength=1 size=1><pre id=o>0

split 一連の空の文字列と単一の文字、および実行を返しますが、これは結果に影響しません。




2

Perl 6の 45の43  42バイト

->$_,$c {$c&&$_??.comb(/$c+/)».chars.max!!0}

試して

->$_,$c {$c&&$_??.comb(/$c+/).max.chars!!0}

試して

->$_,$c {$c&$_??.comb(/$c+/).max.chars!!0}

試して

拡張:

-> $_, $c {       # pointy block lambda

    $c & $_       # AND junction of $c and $_
                  #   empty $c would run forever
                  #   empty $_ would return 4 ( "-Inf".chars )

  ??              # if True (neither are empty)

    .comb(/$c+/)  # find all the substrings
    .max          # find the max
    .chars        # get the length

  !!              # if False (either is empty)

    0             # return 0
}

2

JavaScript、ES6、52

文字列入力を配列として扱い(注:最初の入力はまだ文字列です)、文字の左から右を消費する再帰的ソリューションC

f=([C,...s],c,t=0,T=0)=>C?f(s,c,C==c&&++t,t>T?t:T):T

での現在のランtとグローバルなベストを追跡しTます。

説明:

f=            // function is stored in `f` (for recursion)
  ([C,...s],  // turn input string in first-char `C` and the rest in `s`
   c,         // argument `c` to search for
   t=0,T=0)   // current total `t`, best total `T`
     =>
        C?             // if there is still any char left in the string
          f(s,c,       // recursively call `f`
            C==c&&++t, // increment `t` if char is match, or set `t` to `false`
            t>T?t:T)   // set global `T` to max of `t` and `T`
          :T           // when string is depleted, return `T`

設定tfalseいつでもがあるため非マッチの作品にtインクリメントされ、falseとして扱われる0(すなわち、false + 1ある1)、およびfalseグローバル・maxの任意の値よりもおろし金を比較することはありませんT


1
素敵な解決策、私は[C,...s]構文に不慣れでした。slice()自分の投稿からバイトを取り除くのに役立つはずです。
リックヒッチコック

2

ゼリー、5バイト

=ŒgṀS

これは、文字列と文字を受け取る2項リンク/関数です。コマンドライン引数からの入力はPython構文を使用し、PythonはJellyとは異なり、シングルトン文字列と文字を区別しないため、完全なプログラムとしては機能しないことに注意してください。

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

使い方

=ŒgṀS  Main link. Left argument: s (string). Right argument: c (character)

=      Compare all characters in s with c, yielding 1 for c and 0 otherwise.
 Œg    Group adjacent, equal Booleans in the resulting array.
   Ṁ   Take the maximum. Note that any array of 1's will be greater than any array
       of 0's, while two arrays of the same Booleans are compared by length.
    S  Take the sum, yielding the length for an array of 1's and 0 otherwise.


2

APL(ダイアログ)18 11バイト

スワップが必要バージョン16.0または持つ⎕ML←3(多くのシステム上のデフォルト)。

⌈/0,≢¨⊂⍨⎕=⎕

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

⎕=⎕ 2つの入力間の等価性のブール

⊂⍨ 自己パーティション(ゼロ以外の要素がその前の要素よりも大きいパーティションを開始)

≢¨ 集計する

0, ゼロを追加する(空の入力の場合)

⌈/ それらの最大


古いソリューション

最初にsを要求し、次にcを要求します

⌈/0,(⎕,¨'+')⎕S 1⊢⎕

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

 sのプロンプト

 そのために

(... )⎕S 1PCRE のSの発生の長さのためのearchが

'+' プラス記号(1つ以上を意味する)

 の各要素に追加

 プロンプトのc

0, ゼロを追加する(空の入力の場合)

⌈/ それらの最大

cは、エスケープが必要な場合、囲まれた文字列の1要素ベクトルとして指定する必要があります。


2

PHP、70 67バイト

3つのバージョン:

while(~$c=$argv[1][$i++])$x=max($x,$n=($c==$argv[2])*++$n);echo+$x;
while(~$c=$argv[1][$i++])$x=max($x,$n=$c==$argv[2]?++$n:0);echo+$x;
for(;++$n&&~$c=$argv[1][$i++];)$x=max($x,$n*=$c==$argv[2]);echo+$x;

コマンドライン引数から入力を受け取ります。オンラインで実行-rまたはテストします


2

PHP、70バイト

for(;~$c=$argv[1][$i++];)$r[]=$argv[2]==$c?++$n:$n=0;echo$r?max($r):0;

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

PHP、75バイト

for(;~$s=substr($argv[1],$i++);)$r[]=strspn($s,$argv[2]);echo max($r?:[0]);

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

PHP、83バイト

<?=@preg_match_all("<".preg_quote($argv[2])."+>",$argv[1],$t)?strlen(max($t[0])):0;

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

回避する+8バイト @

<?=($a=$argv[2])&&preg_match_all("<".preg_quote($a)."+>",$argv[1],$t)?strlen(max($t[0])):0;

正規表現の特殊文字については、67バイトバージョンは失敗します(#もちろん)。
タイタス

...およびに~失敗する場合がありchr(207)ます。
タイタス

@Titusは完了し、入力はASCII文字のみ可能
イェルクHülsermann

良い目++$n!あなたは印刷可能なアスキーを意味していました。;)
タイタス

1
echo$r?max($r):0;1バイトを節約
タイタス

2

JavaScript(ES6)、47 40 38バイト

(@Neilのおかげで7バイト、@ HermanLauensteinのおかげで2バイト保存されました。)

s=>g=c=>c&&s.includes(c)?1+g(c+c[0]):0

説明:

何も見つからなくなるまで、より長い実行を再帰的に検索します。

スニペット:


1
とても簡単!ブリリアント!
-apsillers

できませんf=(s,c)=>c&&s.includes(c)&&1+f(s,c+c[0])か?
ニール

それとも、それをカレーしs=>g=c=>c&&s.includes(c)&&1+g(c+c[0])ます。
ニール

これはほとんど機能しますが、最後の2つのケースでは「false」とヌル文字列を返します。||0これは、を追加することで修正されます。
リックヒッチコック

f=だけ内側関数が再帰的であるため、カリーバージョンの一部ではありません。
ニール



1

Haskell、66バイト

import Data.List
((maximum.(0:).map length).).(.group).filter.elem

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

少し読みやすいバージョン-ポイントフリーではありません:

f c s = maximum (0:(map length (filter (elem c) (group s))))

文字列を文字でグループ化し、適切な文字を含むグループでフィルタリングし、長さを見つけ、表示されない場合は長さのリストに0を追加し、最後に最大値を見つけます。


1

Mathematica、109バイト

(s=Differences[First/@StringPosition[#,#2]];k=t=0;Table[If[s[[i]]==1,t++;If[k<t,k=t],t=0],{i,Length@s}];k+1)&


入力

["xxx xxxx xx"、 "x"]



1

CJam20 19 18 16バイト

0q~e`f{~@=*}$+W=

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

説明

0                 e# Push 0. We'll need it later.
 q~               e# Read and eval input. Pushes c and s to the stack.
   e`             e# Run-length encode s: turns it into an array of [length, char] pairs.
     f{           e# Map over these pairs using c an extra parameter:
       ~          e#  Dump the pair to the stack.
        @=        e#  Bring c to the top, check equality with the char, pushing 0 or 1.
          *       e#  Multiply the length by the result.
           }      e# (end map)
            $     e# Sort the resulting list in ascending order.
             +    e# Prepend the 0 from before, in case it's empty.
              W=  e# Get the last element.

1

Excel、56バイト

{=MAX(IFERROR(FIND(REPT(A2,ROW(A:A)),A1)^0*ROW(A:A),0))}

sに入力する必要がありますA1
cに入力する必要がありますA2
数式は配列数式(でなければなりませんCtrl+ Shift+ Enter中括弧を追加します){ }

技術的には、これは最長実行が1,048,576(2 ^ 20)未満である場合にのみ処理できます。これは、現在のExcelがワークシートに含める行だからです。再計算するたびに100万以上の値をメモリに読み込むため、これは高速な式ではありません。


1

MATL、15バイト

0i0v=dfd1L)0hX>

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

基本的なアルゴリズムは、(分割の不使用!)非常にシンプルですが、私はに投げなければならなかった0i0v0hエッジケースを可能にします。それでも、私はアプローチがいいと思ったので、おそらくエッジケースを処理するための別のテクニックを見つけることができます。より良い結果を得るために、より良い場所で変数を「パディング」できるかどうかはまだテスト中です。

0i0v % Prepends and appends a zero to the (implicit) input.
   = % Element-wise equality with the desired char (implicit input)
   d % Pairwise difference. Results in a 1 at the start of a run, and -1 at the end.
   f % Get indices of 1's and -1's.
   d % Difference to get length of the runs (as well as length of non-runs)
 1L) % Only select runs, throw out non-runs. We now have an array of all run lengths.
  0h % 'Find' (`f`) returns empty if no run is found, so append a zero to the previous array.
  X> % Maximum value.

emptyでは機能しませんc。繰り返しますが、各文字列には各文字間に無限の空文字列が含まれていると思います:)


1

R66 58バイト

BLTおよびMickyTのおかげで-8バイト

function(s,c)max((r=rle(el(strsplit(s,''))))$l*(r$v==c),0)

無名関数を返します。TIOには1バイトの違いがありますelがあります。は、説明できない動作しないです。

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


バイト保存r=rle(el(strsplit(s,'')))
BLT

1
あなたがそれを見たなら、私の以前のコメントを無視してください。あなたのために良いものを手に入れたfunction(s,c)max((r=rle(el(strsplit(s,''))))$l*(r$v==c),0)
-MickyT

@BLT elはTIOで動作せず(理由はわかりません)、作業コードからコピーして貼り付けただけなので、@ MickyTに戻すのを忘れないでください!ありがとう!
ジュゼッペ

1

Java 8、67 65バイト

s->c->{int t=0,m=0;for(char x:s)m=m>(t=x==c?t+1:0)?m:t;return m;}

@OlivierGrégoireのおかげで-2バイト

入力を取りsとしてchar[]、およびcAなどchar

説明:

ここで試してみてください。

s->c->{          // Method with char[] and char parameters and int return-type
  int t=0,       //  Temp counter-integer
      m=0;       //  Max integer
  for(char a:s)  //  Loop over the characters of the input
    m=m>(
     t=x==c?     //   If the current character equals the input-character:
      t+1        //    Raise `t` by 1
      :          //   Else:
       0)        //    Reset `t` to 0
    ?m:t;        //   If `t` is now larger than `m`, put `t` as new max into `m`
                 //  End of loop (implicit / single-line body)
  return m;      //  Return the resulting max
}                // End of method

1
m=m>(t=x==c?t+1:0)?m:t;はより短い{t=x==c?t+1:0;m=m>t?m:t;}
オリビエグレゴワール

長いですが、私は最初に考えたことが好きs->c->java.util.Arrays.stream(s.split("[^"+c+"]")).mapToInt(z->z.length()).max().orElse(0)です:;)
オリビエグレゴワール

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