32
\$\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.

caird coinheringaahing
50.8k11 gold badges133 silver badges363 bronze badges
asked Jun 25, 2014 at 18:17
\$\endgroup\$
9
  • \$\begingroup\$ Is there a maximum to the length of the input string? \$\endgroup\$ Commented Jun 25, 2014 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\$ Commented Jun 25, 2014 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\$ Commented Jun 26, 2014 at 2:17
  • 2
    \$\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\$ Commented Jun 27, 2014 at 19:17
  • 1
    \$\begingroup\$ Does this count? :) wolframalpha.com/input/?i=char+%22acbaabbbaaaaacc%22+frequency \$\endgroup\$ Commented Jun 27, 2014 at 21:41

49 Answers 49

1
2
22
\$\begingroup\$

8086 machine code, (削除) 82 (削除ここまで) 80

Contents of the x.com file:

B7 3D 89 DF B1 80 F3 AA 0D 0A 24 B4 01 CD 21 42
38 D8 74 F7 38 17 77 02 88 17 88 C3 31 D2 3C 0D
75 E9 BF 21 3D B1 5E 31 C0 F3 AE E3 EE 4F BB 04
01 8A 05 D4 0A 86 E0 0D 30 30 89 47 02 3C 30 77
04 88 67 03 43 89 3F 89 DA B4 09 CD 21 47 EB D7

It only supports repetitions of up to 99 characters.

Source code (served as input for the debug.com assembler), with comments!

a
 mov bh, 3d ; storage of 128 bytes at address 3d00
 mov di, bx
 mov cl, 80
 rep stosb ; zero the array
 db 0d 0a 24
; 10b
 mov ah, 1
 int 21 ; input a char
 inc dx ; calculate the run length
 cmp al, bl ; is it a repeated character?
 je 10b
 cmp [bx], dl ; is the new run length greater than previous?
 ja 11a
 mov [bx], dl ; store the new run length
; 11a
 mov bl, al ; remember current repeating character
 xor dx, dx ; initialize run length to 0
 cmp al, d ; end of input?
 jne 10b ; no - repeat
 mov di, 3d21 ; start printing run lengths with char 21
 mov cl, 5e ; num of iterations = num of printable characters
; 127
 xor ax, ax
 repe scasb ; look for a nonzero run length
 jcxz 11b ; no nonzero length - exit
 dec di
 mov bx, 104 ; address of output string
 mov al, [di] ; read the run length
 aam ; convert to decimal
 xchg al, ah
 or ax, 3030
 mov [bx+2], ax
 cmp al, 30 ; was it less than 10?
 ja 145
 mov [bx+3], ah ; output only one digit
 inc bx ; adjust for shorter string
; 145
 mov [bx], di ; store "x=" into output string
 mov dx, bx ; print it
 mov ah, 9
 int 21
 inc di
 jmp 127 ; repeat
; 150
rcx 50
n my.com
w
q

Here are some golfing techniques used here that I think were fun:

  • array's address is 3d00, where 3d is the ascii-code for =. This way, the address for array's entry for character x is 3d78. When interpreted as a 2-character string, it's x=.
  • Output buffer is at address 104; it overwrites initialization code that is no longer needed. End-of-line sequence 0D 0A 24 is executed as harmless code.
  • The aam instruction here doesn't provide any golfing, though it could...
  • Writing the number twice, first assuming it's greater than 10, and then correcting if it's smaller.
  • Exit instruction is at an obscure address 11b, which contains the needed machine code C3 by luck.
answered Jun 26, 2014 at 8:13
\$\endgroup\$
1
  • \$\begingroup\$ Interesting approach. However, with a limitation of 99 repetitions, it wouldn't handle cases where the input of 1024 aaaa's is supplied. \$\endgroup\$ Commented Jun 28, 2014 at 17:03
14
\$\begingroup\$

CJam, (削除) 27 (削除ここまで) (削除) 26 (削除ここまで) 25 bytes

l:S_&{'=L{2$+_S\#)}g,(N}/

Try it online.

Example

$ cjam maxseq.cjam <<< "acbaabbbaaaaacc"
a=5
c=2
b=3

How it works

l:S " Read one line from STDIN and store the result in "S". ";
_& " Intersect the string with itself to remove duplicate characters. ";
{ " For each unique character "C" in "S": ";
 '=L " Push '=' and ''. ";
 { " ";
 2$+_ " Append "C" and duplicate. ";
 S\#) " Get the index of the modified string in "S" and increment it. ";
 }g " If the result is positive, there is a match; repeat the loop. ";
 , " Retrieve the length of the string. ";
 ( " Decrement to obtain the highest value that did result in a match. ";
 N " Push a linefeed. ";
}/ " ";
answered Jun 25, 2014 at 20:11
\$\endgroup\$
9
\$\begingroup\$

J - 52 bytes

Well, a simple approach again.

f=:([,'=',m=:":@<:@#@[`(]m~[,{.@[)@.(+./@E.))"0 1~~.

Explanation:

f=:([,'=',m=:":@<:@#@[`(]m~[,{.@[)@.(+./@E.))"0 1~~.
 ~~. Create a set of the input and apply it as the left argument to the following.
 ([,'=',m=:":@<:@#@[`(]m~[,{.@[)@.(+./@E.))"0 1 The function that does the work
 "0 1 Apply every element from the left argument (letters) with the whole right argument (text).
 @.(+./@E.) Check if the left string is in right string.
 (]m~[,{.@[) If yes, add one letter to the left string and recurse.
 ":@<:@#@[ If not, return (length of the left string - 1), stringified.
 [,'=', Append it to the letter + '='

Example:

 f 'acbaabbbaaaaacc'
a=5
c=2
b=3
 f 'aaaabaa'
a=4
b=1

If free-form output is allowed (as in many other answers), I have a 45 bytes version too. These boxes represent a list of boxes (yes, they're printed like that, although SE's line-height breaks them).

 f=:([;m=:<:@#@[`(]m~[,{.@[)@.(+./@E.))"0 1~~.
 f 'acbaabbbaaaaacc'
┌─┬─┐
│a│5│
├─┼─┤
│c│2│
├─┼─┤
│b│3│
└─┴─┘
 f 'aaaabaabba'
┌─┬─┐
│a│4│
├─┼─┤
│b│2│
└─┴─┘
answered Jun 25, 2014 at 20:07
\$\endgroup\$
8
\$\begingroup\$

Ruby, 72

(a=$*[0]).chars.uniq.map{|b|puts [b,a.scan(/#{b}+/).map(&:size).max]*?=}

This takes input from command line arguments and outputs to stdout.

answered Jun 25, 2014 at 18:34
\$\endgroup\$
7
  • \$\begingroup\$ chars is a bit shorter than split(""). \$\endgroup\$ Commented Jun 25, 2014 at 19:44
  • \$\begingroup\$ @Ventero I tried that, but chars gives an enumerator rather than an array. I am in 1.9.3, so is it a 2.0 thing? \$\endgroup\$ Commented Jun 25, 2014 at 19:50
  • \$\begingroup\$ Yeah, in 2.0 chars returns an array. \$\endgroup\$ Commented Jun 25, 2014 at 20:14
  • \$\begingroup\$ It may be stretching the rules a bit, but perhaps use p instead of puts? \$\endgroup\$ Commented Jun 28, 2014 at 10:37
  • 1
    \$\begingroup\$ I see. Although that makes it less pretty, I can't see that it would break any rules tho. \$\endgroup\$ Commented Jun 28, 2014 at 19:44
7
\$\begingroup\$

GolfScript, 26 bytes

:s.&{61{2$=}s%1,/$-1=,n+}%

Try it online.

Explanation:

  • :s saves the input string in the variable s for later use.
  • .& extracts the unique characters in the input, which the rest of the code in the { }% loop then iterates over.
  • 61 pushes the number 61 (ASCII code for an equals sign) on top of the current character on the stack, to act as an output delimiter.
  • {2$=}s% takes the string s and replaces its characters with a 1 if they equal the current character being iterated over, or 0 if they don't. (It also leaves the current character on the stack for output.)
  • 1,/ takes this string of ones and zeros, and splits it at zeros.
  • $ sorts the resulting substrings, -1= extracts the last substring (which, since they all consist of repetitions of the same character, is the longest), and , returns the length of this substring.
  • n+ stringifies the length and appends a newline to it.

Ps. If the equals signs in the output are optional, the 61 can be omitted (and the 2$ replaced by 1$), for a total length of 24 bytes:

:s.&{{1$=}s%1,/$-1=,n+}%
answered Jun 25, 2014 at 23:55
\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can save the swap if you push the 61 first: :s.&{61{2$=}s%1,/$-1=,n+}%. \$\endgroup\$ Commented Jun 26, 2014 at 6:23
7
\$\begingroup\$

Python 3, 69 bytes

s=input()
for c in set(s):
 i=0
 while-~i*c in s:i+=1
 print(c,'=',i)

Try it online!

Even golfed Python can be very readable. I think this code is fully idiomatic except for the -~i for i+1 and the single-letter variables. Thanks to pxeger for saving 1 byte.

Example runs:

>>> helloworld
e = 1
d = 1
h = 1
l = 2
o = 1
r = 1
w = 1
>>> acbaabbbaaaaacc
a = 5
c = 2
b = 3
answered Jun 25, 2014 at 22:57
\$\endgroup\$
6
  • \$\begingroup\$ This is an interesting solution \$\endgroup\$ Commented Jun 26, 2014 at 14:26
  • 1
    \$\begingroup\$ if you change set(s) to just s I think it still meets the requirements. Nowhere does it say each char must be printed only once. \$\endgroup\$ Commented Jun 26, 2014 at 14:30
  • \$\begingroup\$ @Cruncher I agree the OP doesn't specify each letter once, but the other Python answers seem to assume it, so I'll stick with that to be comparable. Though output formats are still inconsistent. I do wish the OP had responded to the requests to clarify. \$\endgroup\$ Commented Jun 26, 2014 at 15:24
  • 1
    \$\begingroup\$ You can change for c in set(s) to for c in{*s} for -2 bytes \$\endgroup\$ Commented Feb 27, 2021 at 10:23
  • \$\begingroup\$ @cairdcoinheringaahing It looks like this answer actually predates the introduction of set unpacking in Python 3.5, so I'll keep it as is. \$\endgroup\$ Commented Feb 27, 2021 at 11:42
6
\$\begingroup\$

CoffeeScript, 109 bytes

I like regex.

f=(s)->a={};a[t[0]]=t.length for t in s.match(/((.)2円*)(?!.*1円)/g).reverse();(k+'='+v for k,v of a).join '\n'

Here is the compiled JavaScript you can try in your browser's console

f = function(s) {
 var a, t, _i, _len, _ref;
 a = {};
 _ref = s.match(/((.)2円*)(?!.*1円)/g).reverse();
 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
 t = _ref[_i];
 a[t[0]] = t.length;
 }
 return a;
};

Then you can call

f("acbaabbbaaaaacc")

to get

c=2
a=5
b=3
answered Jun 25, 2014 at 18:43
\$\endgroup\$
3
  • \$\begingroup\$ This seems to generate incorrect results for input like aaaabaa. \$\endgroup\$ Commented Jun 25, 2014 at 19:06
  • \$\begingroup\$ @Ventero you're right, there are two problems. one is easily fixed, but I need to think about the other. \$\endgroup\$ Commented Jun 25, 2014 at 19:09
  • \$\begingroup\$ @Ventero fixed. \$\endgroup\$ Commented Jun 25, 2014 at 19:37
5
\$\begingroup\$

Pyth, 24 (削除) 25 (削除ここまで) (削除) 26 (削除ここまで) (or 29)

=ZwFY{Z=bkW'bZ~bY)p(Yltb

Test can be done here: link

Outputs in the format:

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

Explanation:

=Zw Store one line of stdin in Z
FY{Z For Y in set(Z):
=bk b=''
W'bZ while b in Z:
~bY b+=Y
) end while
p(Yltb print (Y, len(b)-1)

Python:

k=""
Z=copy(input())
for Y in set(Z):
 b=copy(k)
 while (b in Z):
 b+=Y
 print(_tuple(Y,len(tail(b))))

For proper (a=5) output, use:

=ZwFY{Z=bkW'bZ~bY)p++Y"="`ltb

29 characters

yossico
4235 silver badges9 bronze badges
answered Jun 25, 2014 at 21:19
\$\endgroup\$
4
  • \$\begingroup\$ Seems like you had the exact same idea. Have a +1 for that. \$\endgroup\$ Commented Jun 25, 2014 at 21:57
  • \$\begingroup\$ @TheRare yeah, it seems like a very good way to do it. \$\endgroup\$ Commented Jun 25, 2014 at 21:59
  • \$\begingroup\$ Not really related to your algorithm, but the python output is confusing, because k='' is defined elsewhere. \$\endgroup\$ Commented Jun 25, 2014 at 22:58
  • \$\begingroup\$ Yeah, sorry about that. I'll work on improving it. I'll edit it too. \$\endgroup\$ Commented Jun 25, 2014 at 23:24
5
\$\begingroup\$

C, (削除) 126 (削除ここまで) (削除) 125 (削除ここまで) 119 bytes

l,n,c[256];main(p){while(~(p=getchar()))n*=p==l,c[l=p]=c[p]>++n?c[p]:n;for(l=256;--l;)c[l]&&printf("%c=%d\n",l,c[l]);}

Running:

$ gcc seq.c 2>& /dev/null
$ echo -n 'acbaabbbaaaaacc' | ./a.out
c=2
b=3
a=5
answered Jun 26, 2014 at 5:22
\$\endgroup\$
6
  • \$\begingroup\$ You could replace getchar()>0 by ~getchar() like in this answer \$\endgroup\$ Commented Jun 27, 2014 at 6:51
  • \$\begingroup\$ @anatolyg Is EOF guaranteed to be exactly -1? I thought it was only specifically defined as being <0. \$\endgroup\$ Commented Jun 27, 2014 at 7:30
  • \$\begingroup\$ I think -1 is common enough (i.e. Windows and linux) so you can assume it for Code Golf. For production code, less than zero is perfectly OK, but == EOF is more clear. \$\endgroup\$ Commented Jun 27, 2014 at 7:36
  • \$\begingroup\$ @anatolyg Sure, and actually I guess per the spec EOF apparently isn't even guaranteed to be <0 - it could also be, for example, 256. So I'll just save the single byte. :) \$\endgroup\$ Commented Jun 27, 2014 at 7:39
  • 2
    \$\begingroup\$ EOF is guaranteed to be negative, and -1 is used even if char is signed; see here \$\endgroup\$ Commented Jun 27, 2014 at 7:49
4
\$\begingroup\$

Mathematica, (削除) 74 (削除ここまで) (削除) 72 (削除ここまで) 69

Print[#[[1,1]],"=",Max[Tr/@(#^0)]]&/@Split@Characters@#~GatherBy~Max&
% @ "acbaabbbaaaaacc"
a=5
c=2
b=3

Not very good but strings are not Mathematica's best area. Getting better though. :-)

answered Jun 26, 2014 at 3:02
\$\endgroup\$
4
  • \$\begingroup\$ This is pretty impressive golfing (saying this after having tried it myself ...) \$\endgroup\$ Commented Jun 28, 2014 at 2:38
  • \$\begingroup\$ v10, not a full solution: First@*MaximalBy[Length] /@ GroupBy[First]@Split@Characters[#] & At least it's pretty straightforward and readable. \$\endgroup\$ Commented Jun 28, 2014 at 2:40
  • \$\begingroup\$ @Szabolcs Thanks! What's the difference between GroupBy and GatherBy? \$\endgroup\$ Commented Jun 28, 2014 at 4:42
  • \$\begingroup\$ The main difference is that GroupBy returns an Association. I haven't studied the other differences in detail yet. reference.wolfram.com/language/ref/GroupBy.html You can try it in the cloud with a free account (that's how I'm playing with these). \$\endgroup\$ Commented Jun 28, 2014 at 4:44
3
\$\begingroup\$

C# (LinQPad)

146

This is tsavino's answer but shorter. Here, I used Distinct() instead of GroupBy(c=>c). Also the curly braces from the foreach-loop are left out:

void v(string i){foreach(var c in i.Distinct())Console.WriteLine(c+"="+(from Match m in Regex.Matches(i,"["+c+"]+")select m.Value.Length).Max());}

136

I tried using a lambda expression instead of the normal query syntax but since I needed a Cast<Match> first, the code became 1 character longer... Anyhow, since it can be executed in LinQPad, you can use Dump() instead of Console.WriteLine():

void v(string i){foreach(var c in i.Distinct())(c+"="+(from Match m in Regex.Matches(i,"["+c+"]+")select m.Value.Length).Max()).Dump();}

Further study of the code got me thinking about the Max(). This function also accepts a Func. This way I could skip the Select part when using the lambda epxression:

void v(string i){foreach(var c in i.Distinct())(c+"="+Regex.Matches(i,"["+c+"]+").Cast<Match>().Max(m=>m.Value.Length)).Dump();}

Thus, final result:

128

Update:

Thanks to the tip from Dan Puzey, I was able to save another 6 characters:

void v(string i){i.Distinct().Select(c=>c+"="+Regex.Matches(i,"["+c+"]+").Cast<Match>().Max(m=>m‌​.Value.Length)).Dump();}

Length:

122

answered Jun 27, 2014 at 12:38
\$\endgroup\$
3
  • \$\begingroup\$ Thank you for your improvements, I didn't know about the trick with the .Dump() in LinqPad. To be honest, I developed the code in Visual Studio and copied it to LinqPad to save some characters because LinqPad doesn't need a main method. \$\endgroup\$ Commented Jun 27, 2014 at 12:59
  • \$\begingroup\$ Thanks! I also just got to know the Dump() method recently, saves you 10+ chars every time :) The curly braces was easy and the rest was a bit of braincracking :D \$\endgroup\$ Commented Jun 27, 2014 at 13:07
  • 1
    \$\begingroup\$ If you're happy to use LinqPad's IEnumerable display style you can save another 8 chars, with this as your body: i.Distinct().Select(c=>c+"="+Regex.Matches(i,"["+c+"]+").Cast<Match>().Max(m=>m.Value.Length)).Dump(); \$\endgroup\$ Commented Jun 27, 2014 at 13:24
3
\$\begingroup\$

R, 73 bytes

paste(names(b<-by((r<-rle(el(strsplit(scan(,""),""))))$l,r$v,max)),"=",b)

Try it online!

I would like to mention that this solution uses rle function, which was introduced in the R version 3.6.2 (Dec. 2019); therefore my answer and the earlier one from 2014 are not directly comparable.

answered Jun 23, 2024 at 13:04
\$\endgroup\$
2
\$\begingroup\$

Ruby, 58

h={}
gets.scan(/(.)1円*/){h[1ドル]=[h[1ドル]||0,$&.size].max}
p h

Takes input from STDIN, outputs it to STDOUT in the form {"a"=>5, "c"=>2, "b"=>3}

answered Jun 25, 2014 at 20:10
\$\endgroup\$
2
\$\begingroup\$

C# in LINQPad - 159 Bytes

Well, at least I beat T-SQL ;P Won't beat anyone else, but I thought I'd share it anyway.

void v(string i){foreach(var c in i.GroupBy(c=>c)){Console.WriteLine(c.Key+"="+(from Match m in Regex.Matches(i,"["+c.Key+"]+")select m.Value.Length).Max());}}

Usage:

v("acbaabbbaaaaacc");

Suggestions are always welcome!

answered Jun 26, 2014 at 13:26
\$\endgroup\$
1
  • \$\begingroup\$ Great answer! I've got some suggestions but that was too long for a comment so click here for my answer. :) \$\endgroup\$ Commented Jun 27, 2014 at 12:39
2
\$\begingroup\$

Powershell (削除) 80 (削除ここまで) (削除) 77 (削除ここまで) 72

$x=$args;[char[]]"$x"|sort -u|%{"$_="+($x-split"[^$_]"|sort)[-1].length}

You need to run it on console...

answered Jun 26, 2014 at 23:17
\$\endgroup\$
3
  • 1
    \$\begingroup\$ $x is superfluous. You're three byte shorter not using it. Also sort -u suffices. There is rarely a need of spelling out the complete parameter names. This will, however, fail for certain characters due to the unescaped use in the regex. Depending on how »The string can contain any character« is to be understood, this could be a problem. \$\endgroup\$ Commented Jun 27, 2014 at 18:59
  • \$\begingroup\$ @Joey thanks for the tip on sort -u, however regarding the $x I couldn't get it to work like [char[]]"$args"|sort -u|%{"$_="+($args-split"[^$_]"|sort)[-1].length}, it seems the second $args comes empty... – darkajax 17 mins ago \$\endgroup\$ Commented Jun 27, 2014 at 21:17
  • \$\begingroup\$ Eep, yes. Sorry. That's because it's in a script block, which has its own arguments (the $args there is no longer the one of the script). \$\endgroup\$ Commented Jun 27, 2014 at 22:48
2
\$\begingroup\$

Perl - 65 (削除) 71 (削除ここまで) (削除) 76 (削除ここまで) characters

My first code golf!

For each answer, copy to golf.pl and run as:

echo acbaabbbaaaaacc | perl golf.pl

My shortest solution prints each character as many times as it appears, since that is not prohibited by the rules.

$_=$i=<>;for(/./g){$l=length((sort$i=~/$_*/g)[-1]);print"$_=$l
"}

My next-shortest solution (85 (削除) 90 (削除ここまで) characters) only prints each character once:

<>=~s/((.)2円*)(?{$l=length1ドル;$h{2ドル}=$l if$l>$h{2ドル}})//rg;print"$_=$h{$_}
"for keys %h
answered Jun 27, 2014 at 17:06
\$\endgroup\$
1
\$\begingroup\$

F# - 106

let f s=
 let m=ref(Map.ofList[for c in 'a'..'z'->c,0])
 String.iter(fun c->m:=(!m).Add(c,(!m).[c]+1))s;m

In FSI, calling

f "acbaabbbaaaaacc"

gives

val it : Map<char,int> ref =
 {contents =
 map
 [('a', 8); ('b', 4); ('c', 3); ('d', 0); ('e', 0); ('f', 0); ('g', 0);
 ('h', 0); ('i', 0); ...];}

However, to print it without the extra information, call it like this:

f "acbaabbbaaaaacc" |> (!) |> Map.filter (fun _ n -> n > 0)

which gives

val it : Map<char,int> = map [('a', 8); ('b', 4); ('c', 3)]
answered Jun 25, 2014 at 19:29
\$\endgroup\$
1
\$\begingroup\$

Javascript, 116 bytes

y=x=prompt();while(y)r=RegExp(y[0]+'+','g'),alert(y[0]+'='+x.match(r).sort().reverse()[0].length),y=y.replace(r,'')

Sample output:

lollolllollollllollolllooollo
l=4
o=3
acbaabbbaaaaacc
a=5
c=2
b=3
helloworld
h=1
e=1
l=2
o=1
w=1
r=1
d=1 
answered Jun 26, 2014 at 9:16
\$\endgroup\$
1
\$\begingroup\$

T-SQL (2012) (削除) 189 (削除ここまで) 171

Edit: removed ORDER BY because rules allow any output order.

Takes input from a CHAR variable, @a, and uses a recursive CTE to create a row for each character in the string and figures out sequential occurrences.

After that, it's a simple SELECT and GROUP BY with consideration for the order of the output.

Try it out on SQL Fiddle.

WITH x AS(
 SELECT @a i,''c,''d,0r,1n
 UNION ALL 
 SELECT i,SUBSTRING(i,n,1),c,IIF(d=c,r+1,1),n+1
 FROM x
 WHERE n<LEN(i)+2
)
SELECT d+'='+LTRIM(MAX(r))
FROM x
WHERE n>2
GROUP BY d

Assigning the variable:

DECLARE @a CHAR(99) = 'acbaabbbaaaaacc';

Sample output:

a=5
c=2
b=3
answered Jun 25, 2014 at 22:42
\$\endgroup\$
4
  • \$\begingroup\$ I don't think I've seen a SQL solution here before. Interesting. \$\endgroup\$ Commented Jun 26, 2014 at 14:46
  • \$\begingroup\$ consider the str, function instead of ltrim. You can also name your variable @ to save a char. This allows you to lose the i variable in the rcte. I think you can shave quite a few chars that way. You might also be able to rewrite the query with using a windowing function like sum over rows preceding or lag. I haven't quite formed how yet mind you. \$\endgroup\$ Commented Jun 29, 2014 at 15:11
  • \$\begingroup\$ @MichaelB thanks for the advice. The trouble I have with str() is that it outputs a bunch of extra spaces. I will definitely start using @ as a variable! \$\endgroup\$ Commented Jul 1, 2014 at 21:32
  • \$\begingroup\$ It's true that str always outputs 10 characters, but this is golfing :P \$\endgroup\$ Commented Jul 1, 2014 at 21:44
1
\$\begingroup\$

Haskell - 113 (削除) 120 (削除ここまで) bytes

import Data.List
main=interact$show.map(\s@(c:_)->(c,length s)).sort.nubBy(\(a:_)(b:_)->a==b).reverse.sort.group

Tested with

$ printf "acbaabbbaaaaacc" | ./sl
[('a',5),('b',3),('c',2)]
answered Jun 25, 2014 at 22:53
\$\endgroup\$
1
  • \$\begingroup\$ You can use the . (compose) function to avoid creating a lambda where the parameter only appears after the end of a chain of $ connected functions. To do this, simply change all the $s to .s (example: (\i->reverse$sort$group i) turns into reverse.sort.group. \$\endgroup\$ Commented Jun 27, 2014 at 5:28
1
\$\begingroup\$

JavaScript [83 bytes]

prompt().match(/(.)1円*/g).sort().reduce(function(a,b){return a[b[0]]=b.length,a},{})

Run this code in the browser console.

For input "acbaabbbaaaaacc" the console should output "Object {a: 5, b: 3, c: 2}".

answered Jun 27, 2014 at 10:40
\$\endgroup\$
1
\$\begingroup\$

JavaScript - 91

for(i=0,s=(t=prompt()).match(/(.)1円*/g);c=s[i++];)t.match(c+c[0])||alert(c[0]+'='+c.length)

EDIT: My first solution obeys the rules, but it prints several times single char occurrences like abab => a=1,b=1,a=1,b=1 so I came out with this (101 chars), for those not satisfied with my first one:

for(i=0,s=(t=prompt()).match(/((.)2円*)(?!.*1円)/g);c=s[i++];)t.match(c+c[0])||alert(c[0]+'='+c.length)
answered Jun 26, 2014 at 16:24
\$\endgroup\$
1
\$\begingroup\$

Husk, 18 bytes

mȯJ'=§eo;←osL►Lk←g

Try it online!

11 bytes if we ignore the exact input format and display as a list of pairs instead.

answered Feb 27, 2021 at 14:00
\$\endgroup\$
1
  • \$\begingroup\$ 16 bytes: your turn now! \$\endgroup\$ Commented Feb 27, 2021 at 16:03
1
\$\begingroup\$

Husk, 16 bytes

mS:(:'=sさんかく`mg1#)U

Try it online!

Explanation:

m U # for each of the unique elements of the input
 S: # prepend the element to
 (:'= ) # '=' prepended to
 さんかく # the maximum of
 # # the number of times it occurs in 
 `mg1 # each group of identical items in the input,
 s # converted into a string

I saw that Razetime had answered this in Husk, so I had to have a go too...

answered Feb 27, 2021 at 16:03
\$\endgroup\$
2
  • \$\begingroup\$ I'm surprised Husk doesn't have any form of run-length encoding \$\endgroup\$ Commented Feb 27, 2021 at 16:55
  • \$\begingroup\$ @cairdcoinheringaahing - it doesn't have it as a single builtin command, so g = group on equal adjacent values is the closest we can get... \$\endgroup\$ Commented Feb 27, 2021 at 17:30
1
\$\begingroup\$

Jelly, 12 bytes

ŒriƇṀj"=ʋⱮQY

Try it online!

-2 bytes thanks to Unrelated String!

8 bytes to output as a list of pairs

How it works

ŒriƇṀj"=ʋⱮQY - Main link. Takes a string S on the left
 ʋ - Group the previous 4 links into a dyad f(S, C):
Œr - Run-length encode S
 Ƈ - For each sublist in rle(S), keep it if:
 i - It contains C
 Ṁ - Maximum
 As all elements are in the form [C, n] for integers n,
 Python considers the maximum as the greatest n
 j"= - Join with "="; Yields [C, "=", n]
 Q - Get the unique characters of S
 Ɱ - For each unique character C in S, yield f(C, S)
 Y - Join by newlines and output
answered Feb 27, 2021 at 1:12
\$\endgroup\$
2
  • \$\begingroup\$ I think the Ṫṭ can be removed: Try it online! \$\endgroup\$ Commented Feb 27, 2021 at 3:42
  • 1
    \$\begingroup\$ @UnrelatedString Of course! The dangers of golfing at 1 in the morning :) \$\endgroup\$ Commented Feb 27, 2021 at 16:18
1
\$\begingroup\$

Bash / GNU core utils (40)

fold -1|uniq -c|sort -k2 -k1r|uniq -f1

Try it online!

Output when input is "acbaabbbaaaaacc":

 5 a
 3 b
 2 c

Explanation:

  • fold -1 adds a newline after each character
  • uniq -c counts the number of consecutive identical lines
  • sort -k2 -k1r sorts the result so as the maximum count for each character comes first
  • uniq -f1 keeps only the first line for each character
answered Feb 27, 2021 at 19:44
\$\endgroup\$
2
  • \$\begingroup\$ Welcome to Code Golf! Nice first answer. \$\endgroup\$ Commented Feb 27, 2021 at 20:09
  • \$\begingroup\$ Thank you @RedwolfPrograms :-) \$\endgroup\$ Commented Feb 27, 2021 at 20:11
1
\$\begingroup\$

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"
emanresu A
46.1k5 gold badges111 silver badges254 bronze badges
answered May 29, 2017 at 13:06
\$\endgroup\$
0
\$\begingroup\$

Julia, 85

f(s)=(l=0;n=1;a=Dict();[c==l?n+=1:(n>get(a,l,1)&&(a[l]=n);n=1;l=c) for c in s*" "];a)
julia> f("acbaabbbaaaaacc")
{'a'=>5,'c'=>2,'b'=>3}
answered Jun 25, 2014 at 20:23
\$\endgroup\$
0
\$\begingroup\$

Python3 - (削除) 111 (削除ここまで), (削除) 126 (削除ここまで), (削除) 115 (削除ここまで) (削除) 114 (削除ここまで) 111 bytes

Executable code that will read 1 line (only use lowercase letters a-z)

d={}.fromkeys(map(chr,range(97,123)),0)
for c in input():d[c]+=1
[print("%s=%d"%(p,d[p]))for p in d if d[p]>0]

Edit: Excluded unnecessary output on request from @Therare

The output looks nice

~/codegolf $ python3 maxseq.py 
helloworld
l=3
o=2
h=1
e=1
d=1
w=1
r=1
answered Jun 25, 2014 at 20:08
\$\endgroup\$
6
  • \$\begingroup\$ You really should exclude the unnecessary output. (I think) \$\endgroup\$ Commented Jun 25, 2014 at 20:11
  • \$\begingroup\$ "fixed" the output \$\endgroup\$ Commented Jun 25, 2014 at 20:15
  • \$\begingroup\$ You can remove spaces between braces, numbers and keywords, such as for or if. \$\endgroup\$ Commented Jun 25, 2014 at 20:21
  • 3
    \$\begingroup\$ I think you've misread the questions. l=2 and o=1 for "helloworld" \$\endgroup\$ Commented Jun 25, 2014 at 21:53
  • 4
    \$\begingroup\$ You're counting total appearances instead of maximum consecutive appearances. \$\endgroup\$ Commented Jun 25, 2014 at 22:53
0
\$\begingroup\$

JavaScript - (削除) 141 (削除ここまで) (削除) 137 (削除ここまで) 125

I don't like regex :)

function g(a){i=o=[],a=a.split('');for(s=1;i<a.length;){l=a[i++];if(b=l==a[i])s++;if(!b|!i){o[l]=o[l]>s?o[l]:s;s=1}}return o}

Run

console.log(g("acbaabbbaaaaacc"));

outputs

[ c: 2, a: 5, b: 3 ]
answered Jun 25, 2014 at 22:51
\$\endgroup\$
1
2

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.