# Find max sequence length

Assume we have a string, and we want to find the maximum repeated sequence of every letter.

For example, given the sample input:

"acbaabbbaaaaacc"


Output for the sample input can be:

a=5
c=2
b=3


Rules:

• Your code can be function or a program - for you to choose
• Input can be by stdin, file or function parameter
• The output should contain only characters that appear in the input
• Input max length is 1024
• The output order does not matter, but it has to be printed in the form [char]=[maximum repeated sequence][delimiter]
• The string can contain any character

The competition ends on Thursday 3rd at 23:59 UTC.

• Is there a maximum to the length of the input string? Jun 25, 2014 at 20:08
• Does the output have to be exactly as given? Can we say 0 for letters that don't appear? Will every letter up to the highest letter appear at least once?
– xnor
Jun 25, 2014 at 20:45
• Please clarify if the output has to be formatted exactly as exemplified in your question. At least 10 of the current 16 answers use a different format, three others present two different versions. Jun 26, 2014 at 2:17
• @Joey You probably should punish for golfing. By you condoning it, I'm going to end up seeing l:S_&{'=L{2$+_S\#)}g,(N}/ in production systems! And I will curse your name. Jun 27, 2014 at 19:17 • Does this count? :) wolframalpha.com/input/?i=char+%22acbaabbbaaaaacc%22+frequency Jun 27, 2014 at 21:41 ## 48 Answers Java 247 import java.util.*;public class a{public static void main(String[]a){Map<Character, Integer> m = new HashMap<>();for(char c:a[0].toCharArray()){Integer v=m.get(c);m.put(c,v==null?1:v+1);}for(char c:m.keySet())System.out.println(c+"="+m.get(c));}}  • Does import java.util.*; work in Java? Jun 26, 2014 at 13:29 • yes and i paste old code Jun 26, 2014 at 13:32 • The OP said it could just be a function/method so you can shorten this to simply the method. Jun 26, 2014 at 17:08 • This outputs all occurrences of the character in the String, not the longest substrings consisting of the character. For example, acbaabbbaaaaacc outputs a=8; b=4; c=3 instead of a=5; b=3; c=2. Nov 10, 2017 at 13:21 ## C 169 Iterates each printable character in ASCII table and counts max from input string. #define N 128 int c,i,n; char Y[N],*p; int main(){gets(Y); for(c=33;c<127;c++){p=Y;n=0,i=0;while(*p){if(*p==c){i++;}else{n=(i>n)?i:n;i=0;}p++;} if(n>0) printf("%c=%d\n",c,n);} }  • Have you tested this? It doesn't look like it produces correct output on a lot of strings , and also doesn't meet the spec which says that input can be up to 1024 long... plus, there's a lot of easy golfing techniques that you've missed. :) Jun 27, 2014 at 8:11 # JavaScript 116 prompt(x={}).replace(/(.)\1*/g,function(m,l){n=m.length if(!x[l]||x[l]<n)x[l]=n}) for(k in x)console.log(k+'='+x[k])  ## Groovy - 80 chars Based on this clever answer by xnor : t=args[0];t.toSet().each{i=0; while(t.contains(it*++i)); println "${it}=${i-1}"}  Output: $ groovy Golf.groovy abbcccdddd
d=4
b=2
c=3
a=1


Ungolfed:

t=args[0]

t.toSet().each { c ->
i=0
s=c

// repeat the char c with length i
// e.g. "b", "bb", "bbb", etc
// stop when we find a length that is not in t:
// this is the max + 1
while (t.contains(s)) {
i++
s=c*i
}
println "${c}=${i-1}"
}

• Does that actually count the maximum sequence length? I don't see how that would work correctly for a string like "aabbbbaaaabbbbbba" although I don't know Groovy either. Jun 27, 2014 at 7:35
• It works for your example. I've updated the ungolfed version. Note that "a" * 4 == "aaaa" . Jun 27, 2014 at 11:22
• Ah, I see how it works now. Clever. Jun 27, 2014 at 21:48

# Javascript (E6) 103

A javascript solution that cares about the requested output format.

F=a=>(p=q={},m={},[...a].map(x=>(x!=p&&(q[p=x]=0),m[x]>++q[x]?0:m[x]=q[x])),''+[i+'='+m[i]for(i in m)])


Ungolfed

F=a=>(
p=q={}, m={},
[...a].map(
x=>(
x!=p && (q[p=x]=0),
m[x] > ++q[x] ? 0 : m[x] = q[x]
)
),
'' + [i+'='+m[i] for(i in m)]
)


Test

In Firefox console

console.log(F("aaaaaddfffabbbbdb"))


a=5,d=2,f=3,b=4

## R (219, 213, 197, 196, 191, 165, 169, 157, 163 characters)

The data.table version added. There was an error in the previous data.table version.

Golfed data.table version (163)

require(data.table);f=function(x){x=strsplit(x,"")[[1]];data.table(x=x,y=cumsum(c(1,x[-1]!=head(x,-1))))[,.N,list(x,y)][order(-N)][!duplicated(x),paste0(x,"=",N)]}


Ungolfed data.table version

require(data.table)
f <- function(x) {
x <- strsplit(x, "")[[1]]
data.table(a=x, y=cumsum(c(1, x[-1] != head(x, -1))))[
, .N, list(a, y)][order(-N)][!duplicated(a), paste0(a, "=", N)]
}


Golfed data.frame version (174)

f=function(x){x=strsplit(x,"")[[1]];d=data.frame(a=x,y=cumsum(c(1,x[-1]!=head(x,-1))));d=aggregate(d$y,d,length);d=d[order(-d$x),];d=d[!duplicated(d$a),];paste0(d$a,"=",d$x)}  Ungolfed data.frame version f <- function(x) { x <- strsplit(x, "")[[1]] d <- data.frame(a = x, y = cumsum(c(1, x[-1] != head(x, -1)))) d <- aggregate(d$y, d, length)
d <- d[order(-d$x), ] d <- d[!duplicated(d$a), ]
paste0(d$a, "=", d$x)
}

f("acbaabbbaaaaacc")
f("acbaabbbaaaaaccdee")


It's written in Python, in order to run the code, just call thefunction maxsequence(str). For instance, maxsequence('aaaaaannndmdejlsfnsfsssssnnnnnxxx') or maxsequence("kdkdkdkdjeeeiwwwnnnmdnnsbjdiiiiiiiiiidndbbcbbccbcvcvdddcjdjdjwwwwwwkkkkxlxllllllll")

def maxsequence(str):

count = 1 # count if the letters are repeat
step = 0 # once the next letter changed, step = count.
countArray = [] # put all the sequence numbers in an array
lettersArray = [] # put all the repeat letters in an array
max = 0
# for calculating the max of the array, it needs two indexes to do that
indexFirst = 0
indexNext = 1
i = 0
while(i<len(str) and i<=(len(str)-2)):
if(str[i]==str[i+1]):
count += 1
step = count
else:
lettersArray.append(str[i])
step = count
countArray.append(step)
count = 1
i += 1
countArray.append(step)
lettersArray.append(str[i])

while(countArray[indexFirst]>=countArray[indexNext] and indexNext<(len(countArray)-1)):
indexNext += 1
if(countArray[indexFirst]<=countArray[indexNext]):
indexFirst = indexNext
max = countArray[indexFirst]

for i in range(len(lettersArray)):
print lettersArray[i],"=",countArray[i]

print "The max sequence is:", max
return max

• Note that the question is a code-golf, and that means that you should write the shortest code possible. You can do this by removing comments, removing whitespace and using one-letter variable names. After doing that, include the character count in your answer. Also, it is a good idea to provide a un-golfed version of your code. The code that you have now is a good example of a un-golfed code. Jun 28, 2014 at 14:16
• Thanks for the advice, I misunderstood the goal of this forum. Jun 28, 2014 at 19:15

# Scala – 99 as program, 97 as function

Program (reads one line from stdin)

for((k,v)<-"(.)\\1*".r.findAllIn(Console.in.readLine).toSeq.groupBy(_(0)))println(k+"="+v.max.size)


Function:

def f(s:String)=for((k,v)<-"(.)\\1*".r.findAllIn(s).toSeq.groupBy(_(0)))println(k+"="+v.max.size)


## Clojure - 105 bytes

I'm learning Clojure at the moment and what would be a better way to do it than golfing? So, here's my second entry to this challenge.

(def f #(apply str(for[c(distinct %)](str c\=(apply max(map count(re-seq(re-pattern(str c\+))%)))"\n"))))


Examples:

=> (f "acbaabbbaaaaacc")
"a=5\nc=2\nb=3\n"
=> (f "aaaabaa")
"a=4\nb=1\n"
=> (println (f "acbaabbbaaaaacc"))
a=5
c=2
b=3


## J 45

~.,.'=',.":@({.@>>.//.$&>)@(<;.2~2&(~:/\),1:)  As a verb. Though for using it , you'd need to assign it to a name, eg: f=:~.,.'=',.":@({.@>>.//.$&>)@(<;.2~2&(~:/\),1:)
f 'acbaabbbaaaaacc'
a=5
c=2
b=3


Short explanation:

                                @(        2&(~:/\),1:): find where neighbors are different
<;.2~              : cut in these places
(              $&> ) : get the length of the string in the box ({.@>) : get the first letter from the box (>./)/. : get the maximum for each unique char ~.,.'=',.":@( ) : Output: letter = stringified value  ## BACCHUS, 41 'acbaabbbaaaaacc'j:A=·z#:B=($A,$0h:a(·>0.$0,'=',·+)?),$B¨n  I have discounted the actual parameter String. Explanation j:A= Transform the String in a block (some sort of array) and stores it in A variable. ·z#:B= Read last value on the stack (the block) and removes al duplicates, storing it in B. ( Open for each $A,$0h:a counts how many times the current element of the for each is present in A (read as a String) and pushes this value to Stack (this avoid inmediate printing of the value). ( Open if ·>0. is last value is > 0 then $0,'=',·+ Concatenates current for each element, '=' and last value in stack (that will be printed out)

)? Close if

,\$B¨ Close for each indicating the block to loop over (B).

n Indicates that the output must be space separated

## Python 3, 88 bytes

from re import*;a=input();[(i[0],len(max(i))) for i in(findall(l+"+",a)for l in set(a))]


Outputs in a format of:

[('b', 3), ('c', 2), ('a', 5)]

• This doesn't take input, but otherwise looks like a good approach.
– gggg
Jun 25, 2014 at 20:29
• Also you're missing an import re or __import__('re') for the findall. Jun 25, 2014 at 21:36
• fixed, I forgot I was testing it interactively ;) Jun 25, 2014 at 21:50
• Your byte count was different, I saw the discrepancy and fixed that part of the code. I also changed to byte count, not char count. Jan 11, 2017 at 15:59

## Clojure, 107 bytes

#(apply str(for[p(vals(group-by last(partition-by(fn[i]i)%)))](str(ffirst p)\=(apply max(map count p))\,)))


Returns "a=5,c=2,b=3," for the example input. This would have been 89 bytes, returning ([\a 5] [\c 2] [\b 3]):

#(for[p(vals(group-by last(partition-by(fn[i]i)%)))][(ffirst p)(apply max(map count p))])


# APL (Dyalog), 41 bytes

{(⊃,'=',⍕∘≢)¨l[∪⍳⍨⊃¨l←n[⍒≢¨n←⍵⊂⍨1,2≠/⍵]]}


Try it online!

Ungolfed:

{
n←⍵⊂⍨1,2≠/⍵
l←n[⍒≢¨n]
(⊃,'=',⍕∘≢)¨l[∪⍳⍨⊃¨l]
}


{ anonymous function

2≠/⍵ pair-wise sliding window inequality of the argument
1, prepend a one
⍵⊂⍨ use that to partition the argument
n← store in n

n[] index n with:
⍒ the descending order of
≢¨ the length of each element in
⍵ argument
l← store in l

l[] index l with:
∪ the unique of
⍳⍨ the first occurrence of each element of
⊃¨l the first element of each of l
()¨ apply the following tacit function on each element
⊃ the first element
, concatenated to
'=' an equal sign
, concatenated to
⍕∘≢ the formatted length

}

# Java, 192 bytes

import java.util.*;s->{int p=0,c=0;Map<Character,Integer>m=new HashMap();for(byte b:s.getBytes()){c=p==b?c+1:1;m.merge((char)(p=b),c,Math::max);}m.forEach((k,v)->System.out.println(k+"="+v));}


Try it online!

## Java, 251 bytes (with regular expressions)

import java.util.regex.*;import java.util.function.*;s->{Matcher m=Pattern.compile("(.)\\1*").matcher(s);Map<String,Integer>a=new HashMap();while(m.find())a.merge(m.group(1),m.group().length(),Math::max);a.forEach((k,v)->System.out.println(k+'='+v));}


Try it online!

# 05AB1E, 17 bytes

ÙvIγʒyå}€gZy…ÿ=ÿ,


Try it online!

ÙvIγʒyå}€gZy…ÿ=ÿ,   Argument s
Ùv                  For each c in s uniquified
Iγ                Split s into chunks of consecutive equal elements
ʒyå}            Filter: Keep elements that contain c
€g          Map to element length
Z         Get max
y…ÿ=ÿ,   Print "c=max"


Java Code: Out of interest I just found a solution will further enhance soon.

import java.util.HashMap;


import java.util.Map.Entry; import java.util.Scanner;

public class MaxSequenceLength { private HashMap characterCount = new HashMap<>();

public static void main(String[] args) {
Scanner inputScanner = new Scanner(System.in);
new MaxSequenceLength().validateInput(inputScanner.nextLine());
inputScanner.close();
}

private void validateInput(String inputString) {
if (inputString.length() <= 1024) {
scanInput(inputString.toCharArray());
}
}

private void scanInput(char[] characterArrayInput) {
for (char tempCharacter : characterArrayInput) {
if ((int) tempCharacter < 65
|| ((int) tempCharacter > 90 && (int) tempCharacter < 97)
|| (int) tempCharacter > 122) {
continue;
} else if (characterCount.containsKey(tempCharacter)) {
characterCount.put(tempCharacter,
characterCount.get(tempCharacter) + 1);
} else {
characterCount.put(tempCharacter, 1);
}
}
for (Entry<Character, Integer> tempEntry : characterCount.entrySet()) {
System.out.println(tempEntry.getKey() + " = "
+ tempEntry.getValue());
}
}


}

The code would ignore all the other symbols and give only case sensitive character output.

• This is a code-golf question, which means you should try to use the least number of characters to solve the problem. Jun 26, 2014 at 16:55

## Python (62 55)

n=raw_input()
print map(lambda x:[x,n.count(x)],set(n))


n=raw_input()

• You should output the maximum sequence length foe each character, not the count of each character. aaaabaa -> a=4 b=1 Jun 26, 2014 at 11:46
• The map/lambda idiom map(lambda x:expression_in(x),list) is longer that the equivalent comprehension [expression_in(x)for x in list].
• Oh cool thanks, but that returns a generator object, so to output it all you'd have to do: n=raw_input() for i in ((x,n.count(x))for x in set(n)):print i which is longer, unless I've missed something Jun 26, 2014 at 13:42