Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

The code should take a string as input from keyboard:

The definition of insanity is quoting the same phrase again and again and not expect despair.

The output should be:

  :  15
. :  1
T :  1
a :  10
c :  1
e :  8
d :  4
g :  3
f :  2
i :  10
h :  3
m :  1
o :  4
n :  10
q :  1
p :  3
s :  5
r :  2
u :  1
t :  6
y :  1
x :  1

All ASCII characters count unicode is not a requirement, spaces, quotes,etc and input should come from keyboard / not constants, attributes, output should be printed with new line after each character like in the above example, it should not be returned as string or dumped as hashmap/dictionary etc, so x : 1 and x: 1 are ok, but {'x':1,... and x:1 are not.

share|improve this question
3  
All ascii characters as input? Or just printable? Or up to unicode? Will there be newlines? –  Quincunx yesterday
2  
Can I create a function, or is a whole program necessary? Can I output all the ascii characters and print 0 as the number of occurrences? –  Quincunx yesterday
13  
Is the output format strict, or it suffices to preserve the meaning? –  Jan Dvorak yesterday
 
Your edit did not address my question. –  Quincunx yesterday
4  
You didn't say if the output needs to be sorted alphabetically. You didn't say if the separator needs to be " : " (note the two spaces after the :) or if other(shorter) seperators are fine. You didn't address the unicode/encoding issue. –  CodesInChaos yesterday
show 2 more comments

27 Answers

PHP - 68 (or 39) bytes

<?foreach(count_chars(fgets(STDIN),1)as$k=>$v)echo chr($k)." : $v
";

Output for the example text:

  : 15
. : 1
T : 1
a : 10
c : 1
d : 4
e : 8
f : 2
g : 3
h : 3
i : 10
m : 1
n : 10
o : 4
p : 3
q : 1
r : 2
s : 5
t : 6
u : 1
x : 1
y : 1

If the exact output is not required, this would work for 39 bytes:

<?print_r(count_chars(fgets(STDIN),1));

Sample output:

Array
(
    [32] => 15
    [46] => 1
    [84] => 1
    [97] => 10
    [99] => 1
    [100] => 4
    [101] => 8
    [102] => 2
    [103] => 3
    [104] => 3
    [105] => 10
    [109] => 1
    [110] => 10
    [111] => 4
    [112] => 3
    [113] => 1
    [114] => 2
    [115] => 5
    [116] => 6
    [117] => 1
    [120] => 1
    [121] => 1
)

where each numerical index refers the ordinal value of the character it represents.

I suspect very strongly that using an in-built function that does exactly what the problem states will soon be disallowed.

share|improve this answer
add comment

GNU core utils - 29 22 20 chars (53 with formatting)

Wumpus's improvement (20 chars):

fold -1|sort|uniq -c

Firefly's improvement (22 chars):

grep -o .|sort|uniq -c

joeytwiddle's original (29 chars):

sed 's+.+\0\n+g'|sort|uniq -c

Originally I used sed to simply add a newline after each character. Firefly improved on that with grep -o ., since -o displays every matched pattern on its own line. Wumpus pointed out a further improvement using fold -1 instead. Nice work!

uniq does the real work, although it only applies to sorted lists.

Note that the output format does not exactly match the example in the question. That requires a final run through sed to swap the arguments. (Waiting on an answer to Jan Dvorak's question to see if this is required...)

Reformatting with sed is "only" another 33 characters! (Total 53)

|sed 's/ *\(.*\) \(.\)/\2 :  \1/'

Awk can almost do the job whilst adding only 25 chars, but it hides the first space. Silly awk!

|awk '{print $2" :  "$1}'

I wonder if improvements can be made in the reformatting stage...

share|improve this answer
1  
For sed you can use & for "whole match" instead of \0, though grep -o . is slightly shorter yet. It's worth mentioning that the output of uniq -c differs slightly from the one given in the question. –  FireFly yesterday
 
Oh thanks you! Updated. I should not forget grep -o; it is a useful one. –  joeytwiddle yesterday
2  
fold -1 does the same thing as grep -o . –  Wumpus Q. Wumbley yesterday
 
Awesome :) Learning new tricks! –  joeytwiddle yesterday
1  
ptx -S. does the same trick. –  Pureferret yesterday
add comment

k (8 7)

#:'=0:0

Example

k)#:'=:0:0
The definition of insanity is quoting the same phrase again and again and not expect despair.
T| 1
h| 3
e| 8
 | 15
d| 4
f| 2
i| 10
n| 10
t| 6
o| 4
s| 5
a| 10
y| 1
q| 1
u| 1
g| 3
m| 1
p| 3
r| 2
x| 1
c| 1
.| 1

edit: Down to seven, H/T Aaron Davies

share|improve this answer
 
Pretty incredible. –  Pureferret yesterday
 
the : in =: is superfluous; k)#:'=0:0 works fine (7 chars). (bonus for knowing about 0:0, i had no idea!) –  Aaron Davies 19 hours ago
add comment

Ruby 1.9.3: 53 characters

(Based on @shiva's and @daneiro's comments.)

gets.split("").uniq.map{|x|puts x+" : #{$_.count x}"}

Sample run:

bash-4.1$ ruby -e 'a=gets;a.split("").uniq.map{|x|puts"#{x} : #{a.count x}"}' <<< 'Hello world'
H : 1
e : 1
l : 3
o : 2
  : 1
w : 1
r : 1
d : 1

 : 1

Ruby: 44 characters

Not respecting the output format:

s=Hash.new 0;gets.chars{|c|s[c]+=1};pp s

Sample run:

bash-4.1$ ruby -rpp -e 's=Hash.new 0;gets.chars{|c|s[c]+=1};pp s' <<< 'Hello, world!'
{"H"=>1,
 "e"=>1,
 "l"=>3,
 "o"=>2,
 ","=>1,
 " "=>1,
 "w"=>1,
 "r"=>1,
 "d"=>1,
 "!"=>1,
 "\n"=>1}
share|improve this answer
1  
63 chars a=gets.strip;a.split('').uniq.each{|x|puts"#{x} : #{a.count(x)}"} –  shiva yesterday
 
Why to strip()? The question says, “all characters count”. –  manatwork yesterday
 
Well, gets will return \n even if you dont intend to –  shiva yesterday
 
Nope. Only returns \n if it was really passed. Passing it is a side-effect of using here-string. pastebin.com/gCrgk9m1 –  manatwork yesterday
1  
Using $_ and ditching a is still sound though. And c+"... instead of "#{c}... –  daniero yesterday
show 9 more comments

Python 3: 76 characters

76

import collections as c
for x,y in c.Counter(input()).items():print(x,':',y)

44

(print same characters many times, see Wasi's answer for a valid version)

a=input()
for x in a:print(x,':',a.count(x))
share|improve this answer
 
The 45 char version prints characters more than once. –  ugoren yesterday
 
Right... Thanks for noticing! –  evuez yesterday
 
@evuez I just fixed your 45 char version. But, you removed it so I have submitted it once again. Have a look –  Wasi yesterday
add comment

Python 2, correctly (58)

s=raw_input()
for l in set(s):print l+" : "+str(s.count(l))

Output:

python count.py
The definition of insanity is quoting the same phrase again and again and not expect despair.
  : 15
. : 1
T : 1
a : 10
c : 1
e : 8
d : 4
g : 3
f : 2
i : 10
h : 3
m : 1
o : 4
n : 10
q : 1
p : 3
s : 5
r : 2
u : 1
t : 6
y : 1
x : 1

Python 2, cheetah style (41)

s=input()
print {l:s.count(l) for l in s}

Output:

python count.py
"The definition of insanity is quoting the same phrase again and again and not expect despair."
{' ': 15, '.': 1, 'T': 1, 'a': 10, 'c': 1, 'e': 8, 'd': 4, 'g': 3, 'f': 2, 'i': 10, 'h': 3, 'm': 1, 'o': 4, 'n': 10, 'q': 1, 'p': 3, 's': 5, 'r': 2, 'u': 1, 't': 6, 'y': 1, 'x': 1}
share|improve this answer
 
Forgot to remove the brackets after print in the second one, that makes it 41 –  ToonAlfrink 16 hours ago
 
You can go down to 52 chars with your first version: for l in set(s):print l,":",s.count(l). For the second one, removing unnecessary spaces makes you win 2 chars: print{l:s.count(l)for l in s} –  evuez 10 hours ago
add comment

Perl 6: 21 chars

.say for get.comb.Bag
(REPL)
> .say for get.comb.Bag
The definition of insanity is quoting the same phrase again and again and not expect despair.
"T" => 1
"h" => 3
"e" => 8
" " => 15
"d" => 4
"f" => 2
"i" => 10
"n" => 10
"t" => 6
"o" => 4
"s" => 5
"a" => 10
"y" => 1
"q" => 1
"u" => 1
"g" => 3
"m" => 1
"p" => 3
"r" => 2
"x" => 1
"c" => 1
"." => 1
share|improve this answer
add comment

APL (15)

M,⍪+⌿Z∘.=M←∪Z←⍞

If you really need the :, it's 19 (but there's others who aren't including it):

M,':',⍪+⌿Z∘.=M←∪Z←⍞

Output:

      M,⍪+⌿Z∘.=M←∪Z←⍞
The definition of insanity is quoting the same phrase again and again and not expect despair. 
T  1
h  3
e  8
  16
d  4
f  2
i 10
n 10
t  6
o  4
s  5
a 10
y  1
q  1
u  1
g  3
m  1
p  3
r  2
x  1
c  1
.  1
share|improve this answer
add comment

Perl 5, 54 characters

map{$h{$_}++}split//,<>;print"$_ : $h{$_}\n"for keys%h
share|improve this answer
 
Very nice solution, easy to read. That would need to be sort keys%h, though. –  primo yesterday
 
Hey @protist, looks good! I agree with @primo though! You can however save two chars using $_=<>;s/./$h{$_}++/eg; or map{$h{$_}++}<>=~/./g; instead of map{$h{$_}++}split//,<>; –  Dom Hastings yesterday
 
@DomHastings or $h{$_}++for<>=~/./g, which I think might be optimal. Literal newline instead of \n as well. –  primo yesterday
 
Ah nice, even better! Yes, I forgot to mention the literal newline, that's become my new favourite -1 byte! –  Dom Hastings yesterday
add comment

JavaScript (44 characters):

Expects s to hold a string value.

r={};[].map.call(s,function(e){r[e]=-~r[e]})

The output is contained in r.

share|improve this answer
add comment

R, 30 characters

table(strsplit(readline(),""))

Example usage:

> table(strsplit(readline(),""))
The definition of insanity is quoting the same phrase again and again and not expect despair.

    .  a  c  d  e  f  g  h  i  m  n  o  p  q  r  s  t  T  u  x  y 
15  1 10  1  4  8  2  3  3 10  1 10  4  3  1  2  5  6  1  1  1  1 
share|improve this answer
add comment

python 3, 49

Stealing idea from evuez

t=input()
for i in set(t):print(i,':',t.count(i))

input:

The definition of insanity is quoting the same phrase again and again and not expect despair.

output:

  :  15
. :  1
T :  1
a :  10
c :  1
e :  8
d :  4
g :  3
f :  2
i :  10
h :  3
m :  1
o :  4
n :  10
q :  1
p :  3
s :  5
r :  2
u :  1
t :  6
y :  1
x :  1
share|improve this answer
 
nice improvement! why don't you remove the sorted()? –  evuez yesterday
1  
right! anyway, if you don't use a list comprehension, it's 1 char less: for i in sorted(set(t)):print(i,':',t.count(i)) –  evuez yesterday
 
@evuez Thanks, I was supposed to add it as a comment in your code. If you like you can add it again in your solution(I will happily delete this one) :D –  Wasi yesterday
 
Wouldn't be fair, I hadn't thought about set()! ;) –  evuez yesterday
add comment

C# (220 chars)

Line breaks added for readability, my first feeble attempt at code golf! :)

class P {static void Main(){var d=new Dictionary<char,int>();
Console.ReadLine().ToList().ForEach(x=>{ if(d.ContainsKey(x))
{d[x]++;}else{d.Add(x,1);}});Console.WriteLine(string
.Join("\n",d.Keys.Select(x=>x+":" +d[x])));}}
share|improve this answer
 
doesn't compile. this one does: 178 chars. using System.Linq;using C=System.Console;class F{static void Main(){C.WriteLine(string.Join("\n",C.ReadLine().GroupBy(c=>c).Select(g=>g.Key+" : "+g.Count()).OrderBy(s=>s)));}} –  Spongman 5 hours ago
 
168: using C=System.Console;using System.Linq;class F{static void Main(){foreach(var g in C.ReadLine().GroupBy(c=>c).OrderBy(g=>g.Key))C.WriteLine(g.Key+" : "+g.Count());}} –  Spongman 5 hours ago
add comment

Powershell, 63

$a=@{};[char[]](read-host)|%{$a[$_]++};$a.Keys|%{"$_ :"+$a[$_]}
share|improve this answer
add comment

J, 22 characters

(~.;"0+/@(=/~.))1!:1]1

Example:

   (~.;"0+/@(=/~.))1!:1]1
The definition of insanity is quoting the same phrase again and again and not expect despair.
+-+--+
|T|1 |
+-+--+
|h|3 |
+-+--+
|e|8 |
+-+--+
| |15|
+-+--+
|d|4 |
+-+--+
|f|2 |
+-+--+
|i|10|
+-+--+
|n|10|
+-+--+
|t|6 |
+-+--+
|o|4 |
+-+--+
|s|5 |
+-+--+
|a|10|
+-+--+
|y|1 |
+-+--+
|q|1 |
+-+--+
|u|1 |
+-+--+
|g|3 |
+-+--+
|m|1 |
+-+--+
|p|3 |
+-+--+
|r|2 |
+-+--+
|x|1 |
+-+--+
|c|1 |
+-+--+
|.|1 |
+-+--+
share|improve this answer
add comment

JavaScript

  1. 66 53 bytes:

    prompt(a={}).replace(/./g,function(c){a[c]=-~a[c]}),a
    
  2. 69 56 bytes:

    b=prompt(a={});for(i=b.length;i--;){a[b[i]]=-~a[b[i]]};a
    
  3. 78 65 bytes:

    prompt().split('').reduce(function(a,b){return a[b]=-~a[b],a},{})
    

N.B.: In all cases deleted number of bytes refer to extra console.log() call which is pointless if run in the console. Big thanks to @imma for the great catch with -~a[b] and prompt(a={}). This definitely saved some more bytes.

share|improve this answer
1  
map instead of a loop help a little also (a[b[i]]||0)+1 can be reduced to -~a[b[i]] & console.log can probably go, just returning the last value, giving prompt(a={}).split("").map(function(c){a[c]=-~a[c]});a –  imma yesterday
1  
you can change for into for in - testing in empty tab produces the same results. Also, the last ; is not needed, thus: b=prompt(a={});for(i in b){a[b[i]]=-~a[b[i]]}a –  eithedog yesterday
1  
nice :-) stick the b=... into the for & swop the for{}'s for a ; for another 2 bytes off : for(i in b=prompt(a={}))a[b[i]]=-~a[b[i]];a –  imma yesterday
 
although they may want exact text output :-/ which puts it/me back up by 36 (to 79) bytes : for(i in b=prompt(a={}))a[b[i]]=-~a[b[i]];for(n in a)console.log(n+" : "+a[n]) –  imma yesterday
 
@imma for .. in is not the best choice for arrays and strings: it will grab own properties of the objects behind them. Normal loop is the way to go here IMO. –  VisioN yesterday
show 1 more comment

C#: 129

This is Avivs answer but shorter:

var s=Console.ReadLine();for(int i=0;i<256;i++){var ch=(char)i;Console.Write(s.Contains(ch)?ch+":"+s.Count(c=>c==ch)+"\r\n":"");}

This is mine:

C#: 103

foreach(var g in Console.ReadLine().OrderBy(o=>o).GroupBy(c=>c))Console.WriteLine(g.Key+":"+g.Count());
share|improve this answer
 
Won't compile, need to add about 50 chars for usings/namespace/class/method definitions. –  Pierre-Luc Pineault yesterday
 
Oh, didn't know that was mandatory, I'm sorry. –  Abbas yesterday
add comment

Bash (20 characters)

 ptx -S.|sort|uniq -c
 10                                        a
  1                                        c
  4                                        d
  8                                        e
  2                                        f
  3                                        g
  3                                        h
 10                                        i
  1                                        m
 10                                        n
  4                                        o
  3                                        p
  1                                        q
  2                                        r
  5                                        s
  6                                        t
  1                                        T
  1                                        u
  1                                        x
  1                                        y

ASCII encoding now supported

Bash (23 characters):

xxd -p -c1|sort|uniq -c

  1 0a
 15 20
  1 2e
  1 54
 10 61
  1 63
  4 64
  8 65
  2 66
  3 67
  3 68
 10 69
  1 6d
 10 6e
  4 6f
  3 70
  1 71
  2 72
  5 73
  6 74
  1 75
  1 78
  1 79

ASCII formatting not supported

share|improve this answer
add comment

Befunge 98 - 31 to 42 chars

This does not print the spaces, and only prints for characters in the string (once for each character, even duplicates). So an input of aa will produce an output of:

a:2
a:2

31 chars

~::1g1+\1p;,a.- 'g1,:',:@j`0:;#

The following seems to match almost exactly. It outputs only one time for each character, in the order they appear in the string. An input of Bbaa gives an output of

B:1
b:1
a:2

38 chars

~:1g' `j::1g1+\1p;,a.- 'g1,:',:@j`0:;#

The following prints the spaces exactly as in the output example. It also outputs every single ascii character's count, which, since it is not clearly specified, I'll say is valid.

42 chars

~:1g1+\1p;,a+1.- 'g1:,,:,," : ",:@j!`~':;#
share|improve this answer
add comment

Windows Command Script - 72 Bytes

set/p.=
:a
set/a\%.:~,1%=\%.:~,1%+1
set.=%.:~1%
%.%goto:b
goto:a
:b
set\

Outputs:

\=15 (space)
\.=1
\a=10
\c=1
\d=4
\e=8
\f=2
\g=3
\h=3
\i=10
\m=1
\n=10
\o=4
\p=3
\q=1
\r=2
\s=5
\T=7
\u=1
\x=1
\y=1
share|improve this answer
add comment

J, 23 chars

(~.;"0+/@|:@=)/:~1!:1]1

Slightly different output format (line 2 is stdin):

   (~.;"0+/@|:@=)/:~1!:1]1
Mississippi
┌─┬─┐
│M│1│
├─┼─┤
│i│4│
├─┼─┤
│p│2│
├─┼─┤
│s│4│
└─┴─┘
share|improve this answer
add comment

Haskell, 93

import Data.List
main=getLine>>=mapM(\s->putStrLn$[head s]++" : "++show(length s)).group.sort
share|improve this answer
add comment

C#

string str = Console.ReadLine(); // Get Input From User Here
char chr;
for (int i = 0; i < 256; i++)
{
    chr = (char)i; // Use The Integer Index As ASCII Char Value --> Convert To Char
    if (str.IndexOf(chr) != -1) // If The Current Char Exists In The Input String
    {
        Console.WriteLine(chr + " : " + str.Count(x => x == chr)); // Count And Display
    }
}
Console.ReadLine(); // Hold The Program Open.

In Our Case, If The Input Will Be "The definition of insanity is quoting the same phrase again and again and not expect despair."

The Output Will Be:

  : 15
. : 1
T : 1
a : 10
c : 1
d : 4
e : 8
f : 2
g : 3
h : 3
i : 10
m : 1
n : 10
o : 4
p : 3
q : 1
r : 2
s : 5
t : 6
u : 1
x : 1
y : 1
share|improve this answer
1  
The question asks for input from the keyboard, so the first line should be string str = Console.ReadLine();. But this is code-golf so it should actually be var str=Console.ReadLine();. The other comments I would like to make have to be put on hold until OP improves the question. –  Peter Taylor yesterday
 
You're right, I edited my answer. –  Aviv yesterday
add comment

F# (66 59, 82 with prescribed formattting)

let f s=s|>Seq.sort|>Seq.countBy(id)|>Seq.iter(printfn"%A")

Output:

> f The definition of insanity is quoting the same phrase again and again and not expect despair.
(' ', 15)
('.', 1)
('T', 1)
('a', 10)
('c', 1)
('d', 4)
('e', 8)
('f', 2)
('g', 3)
('h', 3)
('i', 10)
('m', 1)
('n', 10)
('o', 4)
('p', 3)
('q', 1)
('r', 2)
('s', 5)
('t', 6)
('u', 1)
('x', 1)
('y', 1)

With the prescribed formatting, it becomes:

let f s=s|>Seq.sort|>Seq.countBy(id)|>Seq.iter(fun(a,b)->printfn"\"%c\" :  %d"a b)
share|improve this answer
add comment

Python 2 (90 chars)

import collections as c;print"\n".join("%s %s"%i for i in c.Counter(raw_input()).items())

Output when run on its own source:

  8
" 4
% 3
) 4
( 4
. 3
; 1
C 1
\ 1
_ 1
a 2
c 4
e 3
f 1
i 9
j 1
m 2
l 2
o 6
n 7
p 3
s 5
r 5
u 2
t 6
w 1
share|improve this answer
add comment

PowerShell (49)

[char[]](read-host)|group|%{$_.Name+":"+$_.Count}
share|improve this answer
add comment

Mathematica, 61 bytes

Map[{#[[1]], Length@#} &, Gather@Characters[Input[]]] // TableForm

It then pops up this dialog box,

input

and for the sample sentence, produces as output

output

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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