Самый длинный пробег символа в строке


19

Ваша задача: Написать функцию , которая принимает строку s, символ c, и находит длину самого длинного пробега cв s. Длина пробега будет l.

Правила :

  • Если sимеет длину 0 или cпусто, lдолжно быть 0.
  • Если нет экземпляров cin s, lдолжно быть 0.
  • Применяются стандартные лазейки и стандартные правила ввода / вывода .
  • Независимо от того, где в sпрогоне cs находится, 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и a, 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 байта.
Волшебная Урна Осьминога

8

Mathematica, 35 байт

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

Чистая функция, принимающая список символов и другой символ в качестве входных данных и возвращающая неотрицательное целое число. Улучшено после моих первых попыток, используя наблюдение Аднана (go upvote!) О том, что нужно проверять выравнивание специального символа, прежде чем разбивать массив.

Thread[#==#2]проверяет, равен ли каждый входной символ в первом аргументе символу, указанному в качестве второго аргумента. Booleпреобразует результирующие Trues и 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"}}для четвертого контрольного примера. /.a:{c_String..}:>заменяет каждое подвыражение a, являющееся списком повторяющегося символа c, Length@aумноженным на Boole[c==#2], то есть, 1если cравно входному символу и 0иначе. Затем Maxизвлекает ответ.


7

Japt , 20 18 15 байт

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

Попробуйте онлайн!

Сохранено 5 байтов благодаря obarakon и ETHproductions


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

Попробуйте онлайн!

Деннис сэкономил 3 байта, обновив cстроку дублированных символов, а не рекурсивно обновив число для умножения cна.


1
f=lambda s,c:c in s and-~f(s,c+c[0])сохраняет 6 байтов (3, если False не разрешено).
Деннис


4

Haskell, 43 39 байт

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

Попробуйте онлайн!

Пройдите через строку и замените текущий символ счетчиком, который увеличивается всякий раз, когда он равен cили сбрасывается, 0если нет. Возьмите максимум из списка.

Спасибо @xnor за 4 байта.


Ты можешь сделать sum[n+1|c==k] .
xnor

@xnor: Отлично! Я экспериментировал с *fromEnum(c==k)pointfree и lambda, но это всегда было на 2 или 3 байта длиннее.
Ними

4

C # 116 115 байт

Мой первый код гольф

Отредактировано, потому что первоначальная отправка была фрагментом и ей не хватало необходимого пространства имен для регулярных выражений

Редактирование # 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 #
Broom

3
Привет просто несколько общих комментариев для игры в гольф в C #, вы можете определить свою функцию как (s,c)=>. Вы должны либо использовать, System.Text.RegularExpressions.Regexлибо добавить оператор использования прямо перед вашей функцией.
LiefdeWen

4

JavaScript (ES6), 54 53 51 байт

-2 байта благодаря @Neil
-1 байт благодаря @apsillers

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>

Другой вариант с использованием evalи 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всегда будет иметь приоритет над нулем, как falseв i)
апсиллеров

@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, что на байт короче.
Нил

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}

Проверь это

Expanded:

-> $_, $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`

Установка tдля falseна не-спичках работает , потому что всякий раз , когда tувеличиваются, falseрассматриваются как 0(то есть, false + 1есть 1), и falseникогда не будет сравнивать терку , чем любое значение в глобальных максах T.


1
Хорошее решение, я не был знаком с [C,...s]синтаксисом. Должен помочь мне slice()от байтов от моих собственных сообщений.
Рик Хичкок

2

Желе , 5 байт

=ŒgṀS

Это диадическая ссылка / функция, которая принимает строку и символ. Обратите внимание, что он не может работать как полноценная программа, так как при вводе из аргументов командной строки используется синтаксис 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,≢¨⊂⍨⎕=⎕

Попробуйте онлайн!

⎕=⎕ Булево для равенства между двумя входами

⊂⍨ самостоятельное разбиение (начало разбиения, где ненулевой элемент больше, чем его предшественник)

≢¨ подсчитать каждый

0, добавить ноль (для случаев пустого ввода)

⌈/ максимум из тех


Старое решение

Запрашивает сначала для s , затем для c

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

Попробуйте онлайн!

 подскажите с

 для этого

(... )⎕S 1PCRE S нить поиск для длин вхождений

'+' символ плюс (означает один или несколько)

 добавлены к каждому из элементов

 предложенный c

0, добавить ноль (для случаев пустого ввода)

⌈/ максимум из тех

c должен быть задан как 1-элементный вектор вложенной строки, если требуется экранирование.


2

PHP, 70 67 байт

три версии:

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 Done и ввод могут быть только символами Ascii
Jörg Hülsermann

хорошо для глаз ++$n! Вы имели в виду ascii для печати. ;)
Тит

1
echo$r?max($r):0;сохраняет один байт
Тит

2

JavaScript (ES6), 47 40 38 байт

(Сохранено 7 байтов благодаря @Neil и 2 байта благодаря @HermanLauenstein.)

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

Объяснение:

Рекурсивно ищет более длинный прогон, пока ничего не найдено.

Отрывок:


1
Так просто! Brilliant!
Апсиллеры

Вы не можете сделать 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]).
Нил

Это почти работает, но возвращает «ложь» и пустую строку для последних двух случаев. Это исправлено добавлением ||0, которое все еще короче моего решения.
Рик Хичкок

Не f=является частью карри-версии, потому что только внутренняя функция является рекурсивной.
Нил

2

Желе, 10 9 байт

f⁴L
ŒgÇ€Ṁ

Объяснение:

f⁴L
f⁴      -Filter by the character argument.
  L     -Return Length of filtered String.

ŒgÇ€»/
Œg      -Group string by runs of characters.
  ǀ    -Run above function on each group.
    Ṁ   -Return the largest in the list.

Попробуйте онлайн!


Вы можете сохранить пару байтов с помощью Œgf€L€Ṁ.
Деннис


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


вход

["ххх хххх хх", "х"]



1

CJam , 20 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 можно размещать строки на рабочем листе. Так как он загружает значения миллиона + в память всякий раз, когда пересчитывает, это не быстрая формула.


1

MATL , 15 байт

0i0v=dfd1L)0hX>

Попробуйте онлайн!

Базовый алгоритм очень прост (без использования split!), Но мне пришлось добавить 0i0vи 0hучесть крайние случаи. Тем не менее, я думал, что подход был хорошим, и, возможно, я все еще могу найти другую технику для обработки краевых случаев: алгоритм находит самый длинный прогон в середине строки просто отлично, но не для одиночных символов или пустых строк; Я все еще проверяю, могу ли я «дополнить» переменные в лучших местах для лучших результатов.

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.

Не работает на пустую c. Опять же, я полагаю, что каждая строка содержит бесконечный пробег пустых строк между каждым символом :)


1

R , 66 58 байт

-8 байт благодаря BLT и MickyT

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

-2 байта благодаря @ OlivierGrégoire

Принимает вход sкак char[], и cкак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)
Оливье Грегуар

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.