29
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Is there a maximum to the length of the input string? \$\endgroup\$ – sigma Jun 25 '14 at 20:08
  • 2
    \$\begingroup\$ 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? \$\endgroup\$ – xnor Jun 25 '14 at 20:45
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – Dennis Jun 26 '14 at 2:17
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ – Cruncher Jun 27 '14 at 19:17
  • 1
    \$\begingroup\$ Does this count? :) wolframalpha.com/input/?i=char+%22acbaabbbaaaaacc%22+frequency \$\endgroup\$ – dualed Jun 27 '14 at 21:41

43 Answers 43

1
2
0
\$\begingroup\$

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

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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")
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – ProgramFOX Jun 28 '14 at 14:16
  • \$\begingroup\$ Thanks for the advice, I misunderstood the goal of this forum. \$\endgroup\$ – Crane Jun 28 '14 at 19:15
0
\$\begingroup\$

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)
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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)]
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This doesn't take input, but otherwise looks like a good approach. \$\endgroup\$ – gggg Jun 25 '14 at 20:29
  • \$\begingroup\$ Also you're missing an import re or __import__('re') for the findall. \$\endgroup\$ – WorldSEnder Jun 25 '14 at 21:36
  • \$\begingroup\$ fixed, I forgot I was testing it interactively ;) \$\endgroup\$ – jermenkoo Jun 25 '14 at 21:50
  • \$\begingroup\$ 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. \$\endgroup\$ – Rɪᴋᴇʀ Jan 11 '17 at 15:59
0
\$\begingroup\$

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))])
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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

}

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

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"
| improve this answer | |
\$\endgroup\$
-1
\$\begingroup\$

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.

| improve this answer | |
\$\endgroup\$
-2
\$\begingroup\$

Python (62 55)

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

Old answer:

n=raw_input()
s=set(n)
print zip(s,map(lambda x:[x,n.count(x)],s))
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You should output the maximum sequence length foe each character, not the count of each character. aaaabaa -> a=4 b=1 \$\endgroup\$ – seequ Jun 26 '14 at 11:46
  • \$\begingroup\$ oh, well I'll leave this here as an example of how not to read a question! \$\endgroup\$ – Mardoxx Jun 26 '14 at 12:02
  • \$\begingroup\$ You can edit your answer with a correct answer, if you wish. Otherwise I would recommend either making it a Community Wiki or deleting it, so you won't lose reputation from the most likely incoming downvotes. \$\endgroup\$ – seequ Jun 26 '14 at 12:24
  • \$\begingroup\$ The map/lambda idiom map(lambda x:expression_in(x),list) is longer that the equivalent comprehension [expression_in(x)for x in list]. \$\endgroup\$ – xnor Jun 26 '14 at 13:35
  • \$\begingroup\$ 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 \$\endgroup\$ – Mardoxx Jun 26 '14 at 13:42
1
2

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