24
\$\begingroup\$

Given a string containing only letters, output the length of the longest run of consecutive alphabetical letters the word contains, where order does not matter. An example algorithm may sort the word, remove duplicates, and then output the length of the longest run.

Test Cases

watch -> 1
stars -> 3
antidisestablishmentarianism -> 3
backdoor -> 4
a -> 1
tutorials -> 4

For example, antidisestablishmentarianism contains the letters abdehilmnstr. The longest runs are lmn and rst, both of length 3.

Notes

You may take all lowercase, all uppercase, or mixed-case letters as input, but the case cannot encode information about the word (i.e. you cannot make the first n characters capitalized where n is the length of the longest run).

This is , so shortest answer in bytes wins.

\$\endgroup\$
  • \$\begingroup\$ @H.PWiz, I'm guessing that's a typo and it should be rst - uniquify, sort and get longest consecutive run. Can we take input as an array of characters? \$\endgroup\$ – Shaggy Jul 11 '18 at 21:46
  • \$\begingroup\$ @Shaggy yes, definitely, I didn't include it because I thought it was a default \$\endgroup\$ – Stephen Jul 11 '18 at 21:51
  • \$\begingroup\$ Is 'a' adjacent to 'z' -- should 'zebra' score 2 or 3? \$\endgroup\$ – Jonathan Allan Jul 11 '18 at 21:54
  • \$\begingroup\$ (...judging by your example algorithm I guess "no" and "2") \$\endgroup\$ – Jonathan Allan Jul 11 '18 at 22:00
  • \$\begingroup\$ @JonathanAllan you are correct \$\endgroup\$ – Stephen Jul 11 '18 at 22:05

30 Answers 30

10
\$\begingroup\$

Jelly,  10 9 8 7  6 bytes

OṬṣ0ZL

Try it online!

9 was using Sok's method: ṢQẆẇƇØaṪL

How?

OṬṣ0ZL - Link: list of (single-case) characters  e.g.  codegolf
O      - ordinal (vectorises)           [99,111,100,101,103,111,108,102]
 Ṭ     - untruth (1s at those indices)  [0,0,0,...,1,1,1,1,1,0,0,0,0,1,0,0,1]
       -                                 ^         ^       ^         ^     ^
       -                   i.e. indices: 1        99     103       108   111
   0   - literal zero
  ṣ    - split at                       [[],[],[],...,[1,1,1,1,1],[],[],[],[1],[],[1]]
    Z  - transpose                      [[1,1,1],[1],[1],[1],[1]]
     L - length                         5
\$\endgroup\$
7
\$\begingroup\$

APL (Dyalog Classic), 10 9 bytes

-1 byte thanks to H.PWiz

≢⍉↑⊆⍨⎕a∊⍞

Try it online!

inputs a string

⎕a is the uppercase English alphabet

⎕a∊⍞ a boolean length-26 vector - which letters occur in the string?

⊆⍨ form vectors of consecutive 1s

≢⍉↑ mix into a matrix, transpose, and return its height - effectively, find the length of the longest vector of 1s

\$\endgroup\$
  • 1
    \$\begingroup\$ ⌈/≢¨ -> ≢⍉↑ \$\endgroup\$ – H.PWiz Jul 11 '18 at 22:39
7
\$\begingroup\$

R, 44 43 bytes

Works on an array of lowercase characters. Edit: changed it from testing True values to multiplying by the T/F for a byte.

function(x,r=rle(letters%in%x))max(r$l*r$v)

Try it online!

Does a run length encoding on letters that are in the supplied characters then return the max value for the trues.

\$\endgroup\$
  • \$\begingroup\$ Was working on a similar rle solution using utf8ToInt but taking an array of string is much smarter. +1 \$\endgroup\$ – JayCe Jul 12 '18 at 0:12
  • \$\begingroup\$ @JayCe Started out the same way, but then realised that a letters %in% check took care of the sort, unique and diff steps in one swoop \$\endgroup\$ – MickyT Jul 12 '18 at 2:32
6
\$\begingroup\$

Perl 6, 41 bytes

{max values bag .ords.sort.squish Z-0..*}

Test it

Expanded:

{  # bare block lambda with implicit param $_

  max       # find the max
    values  # get the values from the following Bag (repeat counts)
      bag   # find the repeats

          .ords.sort.squish # get the unique ordinals (method call on $_)
        Z-                  # zip subtract with
          0 .. *            # Range starting with 0
}

Given 'stars', .ords.sort.squish Z-0..* would return (97,113,113,113)

\$\endgroup\$
6
\$\begingroup\$

Haskell, 35 bytes

f[]=0
f s=1+f[c|c<-s,elem(succ c)s]

Try it online!

Haskell, 50 bytes

f s=maximum$scanl(\x c->sum[x+1|elem c s])0['a'..]

Try it online!

\$\endgroup\$
6
\$\begingroup\$

JavaScript (Node.js), 51 bytes

The case of the input string doesn't matter.

s=>(g=_=>s&&1+g(s&=s*2))(Buffer(s).map(c=>s|=1<<c))

Try it online!

How?

We first convert the input string into a bitmask of encountered letters with:

Buffer(s).map(c => s |= 1 << c)

The bitwise shift is processed with an implicit modulo 32.

Example:

"feedback" --> 100001111110
               kjihgfedcba-

We then 'reduce' runs of consecutive 1's in the bitmask by repeatedly AND'ing it with a left-shifted copy of itself until all bits are cleared:

0100001111110 AND 1000011111100 --> 0000001111100
0000001111100 AND 0000011111000 --> 0000001111000
0000001111000 AND 0000011110000 --> 0000001110000
0000001110000 AND 0000011100000 --> 0000001100000
0000001100000 AND 0000011000000 --> 0000001000000
0000001000000 AND 0000010000000 --> 0000000000000

The number of consecutive letters in alphabetical order is the number of iterations of the above process. Hence the recursive function:

g = _ => s && 1 + g(s &= s * 2)
\$\endgroup\$
5
\$\begingroup\$

Pyth, 9 bytes

le}#G.:S{

Input is assumed to be a lower case string. Try it out online here, or verify all the test cases at once here.

le}#G.:S{Q   Q=eval(input()), G=lowercase alphabet. Trailing Q inferred.

        {Q   Deduplicate input string
       S     Sort it
     .:      Take all substrings (these are generated in length order)
  }#G        Filter out those that aren't found in the alphabet
le           Find the length of the last remaining element
\$\endgroup\$
  • \$\begingroup\$ Great method using the fact that the substrings are ordered by length! \$\endgroup\$ – Jonathan Allan Jul 11 '18 at 22:43
  • \$\begingroup\$ It'll be much less efficient, but you can use y in place of .:. \$\endgroup\$ – FryAmTheEggman Jul 12 '18 at 15:48
5
\$\begingroup\$

MATL, 10 bytes

2Y2imY'*X>

Input is in lowercase.

Try it online! Or verify all test cases.

This uses a mix of @Sundar's (old) and @ngn's approaches.

Explanation

Consider input 'tutorial' as an example.

2Y2   % Push predefind literal 'abcdefghijklmnopqrstuvwxyz'
      % STACK: 'abcdefghijklmnopqrstuvwxyz'
i     % Push input
      % STACK: 'abcdefghijklmnopqrstuvwxyz', 'tutorials'
m     % Ismember: true for letters present in the input
      % STACK: [1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 1 1 1 0 0 0 0 0]
Y'    % Run-length encoding
      % STACK: [1 0 1 0 1 0 1 0 1 0], [1 7 1 2 1 2 1 2 4 5]
*     % Multiply, element-wise
      % STACK: [1 0 1 0 1 0 1 0 4 0]
X>    % Maximum. Implicitly display
      % STACK: 4
\$\endgroup\$
5
\$\begingroup\$

Python 3, 55 bytes

f=lambda s:s and-~f({*s}&{chr(ord(c)+1)for c in s})or 0

Try it online!


Python 2, 58 bytes

f=lambda s,c=99,r=0:c and max(r,f(s,c-1,-~r*(chr(c)in s)))

Try it online!


Python 2, 63 bytes

n=t=0
for c in input():n|=2**ord(c)
while n:n&=n/2;t+=1
print t

Try it online!

\$\endgroup\$
5
\$\begingroup\$

05AB1E, 6 bytes

Saved 1 byte thanks to Adnan: taking the contiguous substrings, then sorting by length (Œ...é) \$\to\$ using the powerset built-in instead (æ).

êæAÃθg

Try it online!

Also 6 bytes

Saved 2 bytes, again thanks to Adnan: using ASå instead êÇ¥Θ, thus also removing the need to increment the maximum at the end. See the revision history to compare the beviours of the two methods.

ASåγOà

Try it online!

How those works

I like challenges like this one which lead to a variety of different approaches.

êæAÃθg | Full program.
ê      | Push a sorted and without duplicates version of the input.
 æ     | Powerser.
  AÃ   | Keep those that also occur in the lowercase alphabet.
    θg | Take the length of the last one. θ and ` can be used interchangeably.
-------+-------------------------------------------------------------------------------
ASåγOà | Full program.
A      | Push the lowercase alphabet.
 S     | Listify it (i.e. convert it to a sequence of characters).
  å    | Replace each char in the alphabet by 1 if its in the input, else by 0.
   γ   | Split into chunks of equal adjacent elements.
    O  | Sum each part.
     à | Extract the maximum of this list. Again, à and Z can be used interchangeably.
\$\endgroup\$
  • \$\begingroup\$ The first program can be golfed to êæAÃ`g and the second program can be golfed to ASåγOZ. \$\endgroup\$ – Adnan Jul 12 '18 at 9:23
  • \$\begingroup\$ @Adnan Thanks, updated! I like the ASå trick. \$\endgroup\$ – Mr. Xcoder Jul 12 '18 at 12:19
4
\$\begingroup\$

TSQL (Microsoft SQL Server), 206 bytes

WITH C AS (SELECT 1p,SUBSTRING(@,1,1)c UNION ALL SELECT p+1,SUBSTRING(@,p+1,1)FROM C WHERE p<LEN(@)),R AS(SELECT c d,1r FROM C UNION ALL SELECT c,r+1FROM R JOIN c ON ASCII(d)+1=ASCII(c))SELECT MAX(r)FROM R

For input, use the following DECLARE statement before the code:

DECLARE @ varchar(200) = 'propinquities';

It is expected that input is all the same case (upper or lower doesn't matter, but mixed case would not work).

Ungolfed:

DECLARE @data varchar(200) = 'propinquities'

;WITH CTE AS (
    SELECT
        1 as CharacterPosition,
        SUBSTRING(@data,1,1) as Character
    UNION ALL
    SELECT
        CharacterPosition + 1,
        SUBSTRING(@data,CharacterPosition + 1,1)
    FROM
        CTE
    WHERE CharacterPosition < LEN(@data)
), Runs AS
(
    SELECT Character, 1 rc
    FROM CTE
    UNION ALL
    SELECT b.Character, rc + 1
    FROM Runs r
    JOIN CTE b ON ASCII(r.Character) + 1 = ASCII(b.Character)
)
SELECT max(rc)
from runs

Explanation:

Splits the string into a a row for each character (adapted from https://stackoverflow.com/a/27623321/1474939) in the CTE cte.

Then, finds runs of consecutive letters by converting to the ASCII code in the Runs cte.

Lastly, it picks the largest run and reports back in the select statement.

\$\endgroup\$
  • \$\begingroup\$ Good answer, very nice use of the CTE. Not sure if this would help or hurt your byte count, but the "approved" method to get input in T-SQL is via a pre-created table. \$\endgroup\$ – BradC Jul 18 '18 at 18:19
  • \$\begingroup\$ @BradC If I can take a table with each row as one character (sort of like a char array instead of a string), then it would help remove one CTE. If it still has to be one row, it's probably about the same as taking it as an input variable. Thanks for the idea though! \$\endgroup\$ – Brian J Jul 18 '18 at 18:59
4
\$\begingroup\$

C (gcc), 58 56 bytes

Saved 2 bytes thanks to @gastropner

Uses the same approach as my Node.js answer. The case of the input string doesn't matter.

m,i;f(char*s){for(i=0;*s?m|=1<<*s++:(i++,m&=m*2););s=i;}

Try it online!

Commented

m,                   // m = bitmask of encountered letters
i;                   // i = counter of max. consecutive letters
f(char *s) {         // f = function taking the input string s
  for(               // main loop:
    i = 0;           //   start with i = 0 and assume m = 0 on first call
                     //   (it is forced back to 0 when the program terminates)
    *s ?             //   if we haven't reached the end of the string:
      m |= 1 << *s++ //     update m by setting the appropriate bit for this character
                     //     (with implicit modulo 32) and advance the string pointer
    : (              //   else:
        i++,         //     increment i
        m &= m * 2   //     'reduce' runs of consecutive 1's in m by AND'ing it with a
      );             //     left-shifted copy of itself (e.g. 11101 & 111010 -> 11000;
                     //     11000 & 110000 -> 10000); we stop when m = 0
  );                 // end of for()
  s = i; }           // return i
\$\endgroup\$
  • \$\begingroup\$ Is it implementation specific that 1<<*s wraps or is it standard behaviour? \$\endgroup\$ – Jonathan Frech Jul 12 '18 at 1:40
  • \$\begingroup\$ @JonathanFrech I think that's officially undefined behavior. So it must be implementation specific. \$\endgroup\$ – Arnauld Jul 12 '18 at 1:50
  • \$\begingroup\$ Because interestingly enough it only appears to wrap when it is computed at runtime. At compile time 1<<32 results in 0 and issues a data type size warning. \$\endgroup\$ – Jonathan Frech Jul 12 '18 at 10:48
  • \$\begingroup\$ Actually, I doubt that the compiler would explicitly apply a 5-bit mask. Chances are that this is done at the CPU level. \$\endgroup\$ – Arnauld Jul 12 '18 at 11:02
  • 2
    \$\begingroup\$ @Arnauld it is (see the note: "[...] The count operand can be an immediate value or register CL. The count is masked to 5 bits, which limits the count range to 0 to 31.") \$\endgroup\$ – ErikF Jul 12 '18 at 15:30
3
\$\begingroup\$

K (ngn/k), 17 bytes

{#1_{x^x^x+1}\-x}

Try it online!

{ } is a function with argument x

- is there only to convert the chars to numbers (it doesn't matter if they are negative)

{ }\ applies a function until convergence, preserving intermediate results

x+1 add 1 to each number in x

^ "without" - the list on the left without elements that occur in the list on the right

x^x^x+1 means x intersected with x+1

1_ drop the first element

# count

\$\endgroup\$
  • \$\begingroup\$ #1_{x^x^x+1}\-? \$\endgroup\$ – Adám Jul 11 '18 at 21:47
  • \$\begingroup\$ @Adám yeah, one day I should make trains work... \$\endgroup\$ – ngn Jul 11 '18 at 21:52
  • \$\begingroup\$ conceptualizing this as the intersection with the increment until convergence is quite nice \$\endgroup\$ – Jonah Jul 12 '18 at 1:59
3
\$\begingroup\$

C (gcc), 100 bytes

c,o,u;n(t,e,r)char*r,*e,*t;{for(u=0,e=t;c=*t++;u=u<o?o:u)for(o=0,r=e;*r;*r++-c||(c++,r=e,++o));o=u;}

Try it online!

Explanation

c,o,u;n(t,e,r)    // setup, function declaration
char*r,*e,*t;{    // K&R style
 for(u=0,e=t;     // initialize global maximum u to 0, write string start to e
 c=*t++;          // look at every character in the string
 u=u  <o?o:  u)   // funny face
  for(o=0,r=e;*r; // initialize local maximum o to 0, look at entire string again
  *r++-c||(c++,   // equal character found, search for next one
   r=e,++o));     // reset local pointer, increment local maximum
o=u;}             // return maximum character streak

Try it online!

\$\endgroup\$
  • \$\begingroup\$ +1 for the "c,o,u;n(t,e,r)" :) \$\endgroup\$ – user34409 Jul 12 '18 at 6:29
3
\$\begingroup\$

MATL, 12 10 bytes

91:wX-dX>q

Try it online!

Explanation:

91: - Create the list of numbers from 1 to 91. 91 is character '[', which comes after 'Z'. So this effectively creates the list of all characters from '\x1' to '['. (We mainly want those in the range ['A'-1 : 'Z'+1], but having the rest doesn't hurt, and needs less bytecount.)

w - Implicit input, bring input to top of stack (assume 'TUTORIALS')

X- - Set difference. This leaves only the characters that were not found in the input string, in their original order ('stable'). Stack: ' !"#$%&'()*+,-./0123456789:;<=>?@BCDEFGHJKMNPQVWXYZ['

d - Difference between successive elements in that list. Stack: [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 2 1 2 1 2 1 5 1 1 1 1 1]

X> - Get the maximum of those differences i.e. the max number of consecutive alphabets missing from the set difference.

q - Decrement to get actual character count


Older:

12 bytes

Sud1=Y'*X>sQ

Try it online!

\$\endgroup\$
  • \$\begingroup\$ So many approaches :-) \$\endgroup\$ – Luis Mendo Jul 12 '18 at 0:49
2
\$\begingroup\$

Retina 0.8.2, 54 bytes

O`.
D`.
.
$&$&¶
T`l`_l`¶.
(.)¶\1
$1
.(.+)
$.1
O#^`
1G`

Try it online! Link includes test cases. Explanation:

O`.

Sort the letters into order.

D`.

Deduplicate the letters.

.
$&$&¶

Duplicate each letter on separate lines.

T`l`_l`¶.

Decrement the first of each pair.

(.)¶\1
$1

If this now matches the previous character, join them back together.

.(.+)
$.1

Count the lengths of all the runs.

O#^`

Sort them in reverse numerical order.

1G`

Take the first (largest).

\$\endgroup\$
2
\$\begingroup\$

J, 16 bytes

-7 bytes thanks to FrownyFrog

[:>./a.#;._1@e.]

Try it online!

explanation

[: >./ a. #;._1@e. ]    
       a. (    )e. ]    is the ascii alphabet an element of the input:
                        this will transform the alphabet into a 1-0 array,
                        the ones representing the letters in the input
          #;._1@        split that 1-0 list up into pieces, using 0
                        as the delimiter, and transforming each chunk
                        into its length. now we have a list of ints
[: >./                  take the max 
\$\endgroup\$
  • \$\begingroup\$ I think that you can use ] instead of ~.@/:~ The alphabet is already sorted, so you don't need to sort the input and keep only the unique items. TIO - 18 bytes \$\endgroup\$ – Galen Ivanov Jul 12 '18 at 6:21
  • 1
    \$\begingroup\$ 16 \$\endgroup\$ – FrownyFrog Jul 12 '18 at 9:52
  • \$\begingroup\$ @FrownyFrog and Galen, Thank you both! In retrospect it should have been obvious I didn't need that uniq/sort first. \$\endgroup\$ – Jonah Jul 12 '18 at 12:56
2
\$\begingroup\$

C (gcc), 98 92 bytes

Thanks to Jonathan Frech for the suggestions.

Uppercase-only.

f(char*s){int a[99]={0},i,j,k=j=i=0;for(;*s;a[*s++]++);for(;i<99;j=!!a[i++]*++j,k=j>k?j:k);}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ You do not actually need the k; at the end. Implicit gcc returning is a side effect of variable assignment which appearently is executed as a last step in your for loop. \$\endgroup\$ – Jonathan Frech Jul 12 '18 at 10:58
  • \$\begingroup\$ Possible 95 bytes. \$\endgroup\$ – Jonathan Frech Jul 12 '18 at 11:00
  • \$\begingroup\$ @JonathanFrech I don't trust gcc's implicit returns. They don't always happen the way that I expect them to, and they often don't work at all for pointers and floating-point. Fortunately, outside of code golf I never use them! :-) \$\endgroup\$ – ErikF Jul 12 '18 at 15:36
2
\$\begingroup\$

Japt -h, 9 bytes

Case insenstive, takes input as a string or an array of characters.

;CôkU mÊn

Try it or run multiple tests (the second line serves as a replacement for the -h flag so the flag can be used to process multiple inputs instead)


Explanation

              :Implicit input of string/array U
;C            :The lowercase alphabet
  ô           :Partition at characters returning truthy
   kU         :  Remove all characters in U from the current letter
              :  This will return a non-empty string (truthy) if the current letter ISN'T in U
     m        :Map
      Ê       :  Length
       n      :Sort
              :Implicitly output the last element in the array
\$\endgroup\$
  • \$\begingroup\$ @Downvoter, could you provide a reason for your -1, please? \$\endgroup\$ – Shaggy Jul 13 '18 at 10:03
2
\$\begingroup\$

Perl 5, 68 bytes

$"=<>;map{$"=~/$_/i&&++$$_||last for$_..z;$.=$$_ if$$_>$.}a..z;say$.

Try it online.

Ungolfed:

use feature 'say';

my $s = <>;
my $r;
for ('a' .. 'z') {
    my $c = 0;
    for ($_ .. 'z') {
        last if $s !~ /$_/i;
        $c++;
    }
    $r = $c if $c > $r;
}
say($r);
\$\endgroup\$
2
\$\begingroup\$

C (gcc), 66 65 63 bytes

Assumes input only contains lowercase letters. First, it loops over the string and sets bits in an integer according to which letters are seen. Next, it counts the longest streak of 1 bits in the integer.

Edit: a is global, so will be initialised to 0 at first call. The second loop makes sure it is reset to 0 before returning. Therefore, we can avoid resetting it manually.

a,l;f(char*s){for(l=0;*s;)a|=1<<*s++-97;for(;a;l++)a&=a*2;s=l;}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Perl 5, 62 + 2 (-nF flag) = 64 bytes

$c[ord lc$_]=1for@F;$y[y///c]++for"@c "=~/((1 )+)/g}{say@y/2|0

Try it online.

Perl 5, 68 bytes

<>=~s/./$c[ord lc$&]=1/gre;$y[y///c]++for"@c "=~/((1 )+)/g;say@y/2|0

Try it online.

\$\endgroup\$
  • 1
    \$\begingroup\$ Nice approach! I'd not considered that method at all... You can save a few bytes using -pF and -MList::Util+(max) to get to 56: Try it online! \$\endgroup\$ – Dom Hastings Jul 13 '18 at 9:25
  • \$\begingroup\$ @DomHastings -MList::Util=max adds 16 bytes to the result score. \$\endgroup\$ – Denis Ibaev Jul 13 '18 at 11:32
  • \$\begingroup\$ If I understand the new scoring correctly, command-line flags aren't counted as bytes, but as as a separately scored language, so rather than just Perl, it'd be Perl with -MList::Util+(max) -pF, or similar. codegolf.meta.stackexchange.com/a/14339/9365 \$\endgroup\$ – Dom Hastings Jul 13 '18 at 11:57
2
\$\begingroup\$

SQLite 265

WITH w AS(SELECT'a'w),n AS(SELECT 1 n UNION ALL SELECT n+1 FROM n LIMIT(SELECT length(w)FROM w)),l AS(SELECT substr(w,n,1)l FROM n,w)SELECT max(v)FROM(SELECT min(n)v FROM(SELECT*FROM l,n EXCEPT SELECT l.l,unicode(l.l)-unicode(b.l)d FROM l,l b WHERE d>0)GROUP BY l);

Ungolfed:

WITH w AS (SELECT 'antidisestablishmentarianism' w)
   , n AS (SELECT 1 n
           UNION ALL
           SELECT n+1 FROM n
           LIMIT (SELECT length(w) FROM w) )
   , l AS (SELECT DISTINCT substr(w,n,1) l FROM n,w ORDER BY l)
   , d AS (
           SELECT l,n FROM l,n
           EXCEPT
           SELECT a.l l, unicode(a.l) - unicode(b.l) d 
           FROM l a, l b 
           WHERE d > 0 
           )

SELECT max(v) FROM ( SELECT min(d.n) v FROM d GROUP BY d.l );
\$\endgroup\$
2
\$\begingroup\$

Brachylog, 14 13 12 bytes

{⊇pS∧ẠsSl}ᶠ⌉

Try it online!

{        }ᶠ    % Find all values that satisfy this predicate
           ⌉   % And get their maximum
               % The predicate being:
 ⊇pS           % There exists a permutation of a subset of the input
               %  Call it S
    ∧          % And, 
      sS       % S is a substring of
     Ạ         %  the set of alphabets, Ạ, 
        l      % Then, the length of that substring is the return value of the 
               %  predicate

Slow enough that it doesn't finish for input "antidisestablishmentarianism" on TIO. Relatively much faster one for +1 byte:

13 bytes

{dosS∧ẠsSl}ᶠ⌉

Try it online!

Use dos instead of ⊇p: S is a deduplicated sorted substring of the input, instead of just some permutation of some subset.

\$\endgroup\$
1
\$\begingroup\$

Haskell, 87 bytes

import Data.List
maximum.map length.filter(`isInfixOf`['a'..'z']).subsequences.nub.sort

Try it online!

Expects lowercase characters

Explanation:

maximum.map length.filter(`isInfixOf`['a'..'z']).subsequences.nub.sort
                                                                  sort {- sort the characters -}
                                                              nub      {- remove duplicates -}
                                                 subsequences          {- all subsequences -}
                   filter(`isInfixOf`['a'..'z'])                       {- all characters are adjacent -}
        map length                                                     {- length of filtered subsequences -}
maximum                                                                {- maxmimum length -}
\$\endgroup\$
1
\$\begingroup\$

Python 2, 95 bytes

lambda s:max(reduce(lambda(p,v),c:(c,v+[v[-1]*(c==p+1)+1]),map(ord,sorted(set(s))),(0,[0]))[1])

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Pyth - 11 bytes

le@.:G).:S{

Input must be wrapped in quotes. If not allowed:

Pyth - 12 bytes

le@.:G).:S{z

Explanation:

l(
  e(
    @(
      .:(G),
      .:(
         S(
           {(Q)
         )
      )
    )
  )
)
length(
    last element(
        intersection(
            all positive length substrings(the alphabet as string),
            all positive length substrings(
                sorted(
                    uniquified(input)
                )
            )
        )
    )
)
\$\endgroup\$
1
\$\begingroup\$

Kotlin, 97 bytes

{w:String->{var s=0
var m=0
for(c in 'a'..'z')if(c in w)s++
else{if(s>m)m=s
s=0}
if(s>m)m=s
m}()}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Java 8, 77 bytes

int i,j,m;
c->{for(i=j=0;(m=j<c.length?m|1<<c[j++]:m&m*2+0*++i)>0;);return i;}

Port of Arnauld's C answer. Try it online here.

Ungolfed:

int i, j, m; // instance variables of the surrounding class - initialised to 0
c -> { // lambda - c is of type char[]; return type is int
    for(i = j = 0; // i is the length of the longest run, j is used to step through c - both start at 0
        (m = j < c.length // work with the bitmask of all the letters present in c: if we have not reached the end of c ...
             ? m | 1 << c[j++] // ... set the bit corresponding to the current character, advance one character ...
             : m & m * 2 + 0 * ++i) > 0 ;) ; // ... else reduce runs of consecutively set bits in m by AND-combining it with a left-shifted copy of itself until m hits 0
    return i; // return the result - by now m is back to 0
}
\$\endgroup\$
1
\$\begingroup\$

><>, 63 bytes

Reads lowercase characters from stdin, outputs a number to stdout.

0l55*)?\
8/?(0:i<]r1~r[-*c
~/00
}</?)@:{:*+1/?(3l
  \~:03. ;n~/

Try it online!

0l55*)?\             Push 26 zeroes onto the stack

Record which characters are used
      i              Read a character from the input
 /?(0:               Check if it is -1, marking the end of the input
8             -*c    Subtract 96 from the character code, 
                         giving 1 for 'a', 2 for 'b' etc.
            r[       Pop that many values on to a new stack and reverse 
                         it, putting that character's value at the top of 
                         the stack
          1~         Write 1 to that value
        ]r           Return the stack back to it's normal state

Count the longest run of ones in the stack
  00                 Push values for currentRun = 0, and bestRun = 0
}                    Move bestRun to the bottom of the stack
            /?(3l    Check if there are only 2 values left on the stack
          +1         Increment currentRun
         *           Multiply currentRun by the next value in the stack, 
                         resetting it to 0 if the run is broken
  /?)@:{:            Check if currentRun > bestRun
  \~:                Overwrite bestRun if so
     03.             Jump back to the start of loop
         ;n~/        Once all values have been consumed, 
                         print bestRun and exit
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.