# 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? – sigma Jun 25 '14 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 '14 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. – Dennis Jun 26 '14 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. – Cruncher Jun 27 '14 at 19:17 • Does this count? :) wolframalpha.com/input/?i=char+%22acbaabbbaaaaacc%22+frequency – dualed Jun 27 '14 at 21:41 ## 43 Answers # 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,"")[];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, "")[] 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,"")[];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, "")[]
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. – ProgramFOX Jun 28 '14 at 14:16 • Thanks for the advice, I misunderstood the goal of this forum. – Crane Jun 28 '14 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,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 '14 at 20:29
• Also you're missing an import re or __import__('re') for the findall. – WorldSEnder Jun 25 '14 at 21:36
• fixed, I forgot I was testing it interactively ;) – jermenkoo Jun 25 '14 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. – Rɪᴋᴇʀ Jan 11 '17 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

}

# 05AB1E, 17 bytes (non-competing)

Ù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.

## 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 – seequ Jun 26 '14 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]. – xnor Jun 26 '14 at 13:35
• 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 – Mardoxx Jun 26 '14 at 13:42