Найдовший запуск символу в рядку


19

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

Правила :

  • Якщо sдовжина 0 або cпорожня, lмає бути 0.
  • Якщо немає жодного примірника cв системі 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та ті, 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-байт.
Magic Octopus Urn

8

Математика, 35 байт

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

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

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 байт завдяки обаракону та ETHproductions


1
Я деякий час пограв зі своїм власним рішенням і закінчив таке, яке було майже вашим, але коротшим. Якщо ви користуєтесь fV+Vî+)... Я дозволяю вам розібратися з рештою :-)
ETHproductions

@ETHproductions "If s is of length 0 or c is empty, l should be 0", я можу сприймати це занадто буквально, хоча
Том,

О, я не розумів, що не працює, коли sне містить жодних примірників c.
ETHproductions

7

Пітон , 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)точковою, і з лямбда, але це завжди було на 2 або 3 байти довше.
німі

4

C # 116 115 байт

Мій перший гольф-код

Відредаговано тому, що початкове надсилання було фрагментом і не вистачало необхідного простору імен для регулярного виразу

Редагуйте повне перезапис №2 для підтримки символів зі спеціальними значеннями регулярних виразів

використовуючи System.Linq; s => c => System.Text.RegularExpressions.Regex.Replace (s, "[^" + c + "]", ++ c + ""). Спліт (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або додати користувальний оператор безпосередньо перед функцією.
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")

Стара відповідь за допомогою Regex (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

@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 повертає купу порожніх рядків та одиночних символів, а також прогонів, але це не впливає на результат.


3

Мікро , 112 байт

{T l m 1+:Q # T Q T l~:r}:Z{T[0]+}:X
{i s m:n
n p = if(Z,X)
i L=if(,a)}:a
0\\:C:s:i"":p"":n[0]:T
s l:L
a
T l m:\


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`

Установка 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 (Dyalog) , 18 11 байт

Вимагає заміни з в версії 16.0 або з ⎕ML←3( по замовчуванням на багатьох системах).

⌈/0,≢¨⊂⍨⎕=⎕

Спробуйте в Інтернеті!

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

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

≢¨ підрахунок кожного

0, додайте нуль (для випадків порожнього вводу)

⌈/ макс


Старе рішення

Підказує спочатку для s , потім для c

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

Спробуйте в Інтернеті!

 підказка для с

 для того

()⎕S 1PCRE S шукайте тривалості подій

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

 додається до кожного з елементів

 підказки-для с

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 and Input можуть бути лише символами 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
Так просто! Блискуче!
апспіллери

Ти не можеш цього зробити 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]).
Ніл

Це майже працює, але повертає "false" та нульовий рядок для останніх двох випадків. Це виправлено додаванням ||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

Математика, 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

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), яка додає фігурні дужки { }.

Технічно це може вирішуватися лише там, коли найдовший пробіг менший ніж 1048,576 (що становить 2 ^ 20), оскільки саме так рядки поточного Excel дозволять вам мати на робочому аркуші. Оскільки він завантажує мільйони значень + у пам'ять кожного разу, коли він перераховує, це не швидка формула.


1

MATL , 15 байт

0i0v=dfd1L)0hX>

Спробуйте в Інтернеті!

Основний алгоритм дуже простий (не використовуйте спліт!), Але мені довелося кинутись 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.