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.
49 Answers 49
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
, where3d
is the ascii-code for=
. This way, the address for array's entry for characterx
is3d78
. When interpreted as a 2-character string, it'sx=
. - Output buffer is at address
104
; it overwrites initialization code that is no longer needed. End-of-line sequence0D 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 codeC3
by luck.
-
\$\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\$Homer6– Homer62014年06月28日 17:03:05 +00:00Commented Jun 28, 2014 at 17:03
CJam, (削除) 27 (削除ここまで) (削除) 26 (削除ここまで) 25 bytes
l:S_&{'=L{2$+_S\#)}g,(N}/
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. ";
}/ " ";
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│
└─┴─┘
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.
-
\$\begingroup\$
chars
is a bit shorter thansplit("")
. \$\endgroup\$Ventero– Ventero2014年06月25日 19:44:50 +00:00Commented 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\$afuous– afuous2014年06月25日 19:50:44 +00:00Commented Jun 25, 2014 at 19:50 -
\$\begingroup\$ Yeah, in 2.0
chars
returns an array. \$\endgroup\$Ventero– Ventero2014年06月25日 20:14:26 +00:00Commented Jun 25, 2014 at 20:14 -
\$\begingroup\$ It may be stretching the rules a bit, but perhaps use
p
instead ofputs
? \$\endgroup\$Shelvacu– Shelvacu2014年06月28日 10:37:05 +00:00Commented 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\$daniero– daniero2014年06月28日 19:44:20 +00:00Commented Jun 28, 2014 at 19:44
GolfScript, 26 bytes
:s.&{61{2$=}s%1,/$-1=,n+}%
Explanation:
:s
saves the input string in the variables
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 strings
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+}%
-
1\$\begingroup\$ You can save the swap if you push the
61
first::s.&{61{2$=}s%1,/$-1=,n+}%
. \$\endgroup\$Howard– Howard2014年06月26日 06:23:18 +00:00Commented Jun 26, 2014 at 6:23
Python 3, 69 bytes
s=input()
for c in set(s):
i=0
while-~i*c in s:i+=1
print(c,'=',i)
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
-
\$\begingroup\$ This is an interesting solution \$\endgroup\$Cruncher– Cruncher2014年06月26日 14:26:43 +00:00Commented 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\$Cruncher– Cruncher2014年06月26日 14:30:18 +00:00Commented 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\$xnor– xnor2014年06月26日 15:24:10 +00:00Commented Jun 26, 2014 at 15:24
-
1\$\begingroup\$ You can change
for c in set(s)
tofor c in{*s}
for -2 bytes \$\endgroup\$2021年02月27日 10:23:26 +00:00Commented 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\$xnor– xnor2021年02月27日 11:42:13 +00:00Commented Feb 27, 2021 at 11:42
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
-
\$\begingroup\$ This seems to generate incorrect results for input like
aaaabaa
. \$\endgroup\$Ventero– Ventero2014年06月25日 19:06:52 +00:00Commented 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\$Martin Ender– Martin Ender2014年06月25日 19:09:51 +00:00Commented Jun 25, 2014 at 19:09
-
\$\begingroup\$ @Ventero fixed. \$\endgroup\$Martin Ender– Martin Ender2014年06月25日 19:37:07 +00:00Commented Jun 25, 2014 at 19:37
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
-
\$\begingroup\$ Seems like you had the exact same idea. Have a +1 for that. \$\endgroup\$seequ– seequ2014年06月25日 21:57:30 +00:00Commented Jun 25, 2014 at 21:57
-
\$\begingroup\$ @TheRare yeah, it seems like a very good way to do it. \$\endgroup\$izzyg– izzyg2014年06月25日 21:59:54 +00:00Commented 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\$gggg– gggg2014年06月25日 22:58:16 +00:00Commented Jun 25, 2014 at 22:58 -
\$\begingroup\$ Yeah, sorry about that. I'll work on improving it. I'll edit it too. \$\endgroup\$izzyg– izzyg2014年06月25日 23:24:15 +00:00Commented Jun 25, 2014 at 23:24
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
-
\$\begingroup\$ You could replace
getchar()>0
by~getchar()
like in this answer \$\endgroup\$anatolyg– anatolyg2014年06月27日 06:51:35 +00:00Commented 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\$fluffy– fluffy2014年06月27日 07:30:41 +00:00Commented 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\$anatolyg– anatolyg2014年06月27日 07:36:51 +00:00Commented 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\$fluffy– fluffy2014年06月27日 07:39:34 +00:00Commented Jun 27, 2014 at 7:39
-
2
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. :-)
-
\$\begingroup\$ This is pretty impressive golfing (saying this after having tried it myself ...) \$\endgroup\$Szabolcs– Szabolcs2014年06月28日 02:38:51 +00:00Commented 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\$Szabolcs– Szabolcs2014年06月28日 02:40:09 +00:00Commented Jun 28, 2014 at 2:40 -
\$\begingroup\$ @Szabolcs Thanks! What's the difference between
GroupBy
andGatherBy
? \$\endgroup\$Mr.Wizard– Mr.Wizard2014年06月28日 04:42:32 +00:00Commented Jun 28, 2014 at 4:42 -
\$\begingroup\$ The main difference is that
GroupBy
returns anAssociation
. 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\$Szabolcs– Szabolcs2014年06月28日 04:44:47 +00:00Commented Jun 28, 2014 at 4:44
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
-
\$\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\$tsavinho– tsavinho2014年06月27日 12:59:04 +00:00Commented 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\$Abbas– Abbas2014年06月27日 13:07:00 +00:00Commented 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\$Dan Puzey– Dan Puzey2014年06月27日 13:24:54 +00:00Commented Jun 27, 2014 at 13:24
R, 73 bytes
paste(names(b<-by((r<-rle(el(strsplit(scan(,""),""))))$l,r$v,max)),"=",b)
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.
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}
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!
-
\$\begingroup\$ Great answer! I've got some suggestions but that was too long for a comment so click here for my answer. :) \$\endgroup\$Abbas– Abbas2014年06月27日 12:39:58 +00:00Commented Jun 27, 2014 at 12:39
Powershell (削除) 80 (削除ここまで) (削除) 77 (削除ここまで) 72
$x=$args;[char[]]"$x"|sort -u|%{"$_="+($x-split"[^$_]"|sort)[-1].length}
You need to run it on console...
-
1\$\begingroup\$
$x
is superfluous. You're three byte shorter not using it. Alsosort -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\$Joey– Joey2014年06月27日 18:59:20 +00:00Commented 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\$DarkAjax– DarkAjax2014年06月27日 21:17:17 +00:00Commented 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\$Joey– Joey2014年06月27日 22:48:43 +00:00Commented Jun 27, 2014 at 22:48
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
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)]
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
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
-
\$\begingroup\$ I don't think I've seen a SQL solution here before. Interesting. \$\endgroup\$Seiyria– Seiyria2014年06月26日 14:46:05 +00:00Commented Jun 26, 2014 at 14:46
-
\$\begingroup\$ consider the
str
, function instead ofltrim
. You can also name your variable@
to save a char. This allows you to lose thei
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\$Michael B– Michael B2014年06月29日 15:11:53 +00:00Commented 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\$comfortablydrei– comfortablydrei2014年07月01日 21:32:59 +00:00Commented Jul 1, 2014 at 21:32
-
\$\begingroup\$ It's true that
str
always outputs 10 characters, but this is golfing :P \$\endgroup\$Michael B– Michael B2014年07月01日 21:44:30 +00:00Commented Jul 1, 2014 at 21:44
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)]
-
\$\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 intoreverse.sort.group
. \$\endgroup\$YawarRaza7349– YawarRaza73492014年06月27日 05:28:19 +00:00Commented Jun 27, 2014 at 5:28
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}
".
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)
Husk, 18 bytes
mȯJ'=§eo;←osL►Lk←g
11 bytes if we ignore the exact input format and display as a list of pairs instead.
-
\$\begingroup\$ 16 bytes: your turn now! \$\endgroup\$Dominic van Essen– Dominic van Essen2021年02月27日 16:03:53 +00:00Commented Feb 27, 2021 at 16:03
Husk, 16 bytes
mS:(:'=s▲さんかく`mg1#)U
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...
-
\$\begingroup\$ I'm surprised Husk doesn't have any form of run-length encoding \$\endgroup\$2021年02月27日 16:55:07 +00:00Commented 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\$Dominic van Essen– Dominic van Essen2021年02月27日 17:30:34 +00:00Commented Feb 27, 2021 at 17:30
Jelly, 12 bytes
ŒriƇṀj"=ʋⱮQY
-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
-
\$\begingroup\$ I think the
Ṫṭ
can be removed: Try it online! \$\endgroup\$Unrelated String– Unrelated String2021年02月27日 03:42:09 +00:00Commented Feb 27, 2021 at 3:42 -
1\$\begingroup\$ @UnrelatedString Of course! The dangers of golfing at 1 in the morning :) \$\endgroup\$2021年02月27日 16:18:53 +00:00Commented Feb 27, 2021 at 16:18
Bash / GNU core utils (40)
fold -1|uniq -c|sort -k2 -k1r|uniq -f1
Output when input is "acbaabbbaaaaacc":
5 a
3 b
2 c
Explanation:
fold -1
adds a newline after each characteruniq -c
counts the number of consecutive identical linessort -k2 -k1r
sorts the result so as the maximum count for each character comes firstuniq -f1
keeps only the first line for each character
-
\$\begingroup\$ Welcome to Code Golf! Nice first answer. \$\endgroup\$2021年02月27日 20:09:10 +00:00Commented Feb 27, 2021 at 20:09
-
\$\begingroup\$ Thank you @RedwolfPrograms :-) \$\endgroup\$xhienne– xhienne2021年02月27日 20:11:37 +00:00Commented Feb 27, 2021 at 20:11
05AB1E, 17 bytes
ÙvIγʒyå}€gZy...ÿ=ÿ,
Ù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"
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}
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
-
\$\begingroup\$ You really should exclude the unnecessary output. (I think) \$\endgroup\$seequ– seequ2014年06月25日 20:11:26 +00:00Commented Jun 25, 2014 at 20:11
-
\$\begingroup\$ "fixed" the output \$\endgroup\$Dog eat cat world– Dog eat cat world2014年06月25日 20:15:55 +00:00Commented Jun 25, 2014 at 20:15
-
\$\begingroup\$ You can remove spaces between braces, numbers and keywords, such as
for
orif
. \$\endgroup\$seequ– seequ2014年06月25日 20:21:35 +00:00Commented Jun 25, 2014 at 20:21 -
3\$\begingroup\$ I think you've misread the questions.
l=2
ando=1
for "helloworld" \$\endgroup\$gnibbler– gnibbler2014年06月25日 21:53:22 +00:00Commented Jun 25, 2014 at 21:53 -
4\$\begingroup\$ You're counting total appearances instead of maximum consecutive appearances. \$\endgroup\$xnor– xnor2014年06月25日 22:53:32 +00:00Commented Jun 25, 2014 at 22:53
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 ]
l:S_&{'=L{2$+_S\#)}g,(N}/
in production systems! And I will curse your name. \$\endgroup\$