Character Counting System

7

GOAL : To Implement a character counting program

This is how this counting system works :

input of the program is a set of printable ASCII characters . the program counts each type of character , and outputs the number of each character , starting from first mentioned character to last mentioned character .

Example :

input : aaaabbbbbcccc    123445b
output : 4 6 4 4 1 1 1 2 1

Which 4 is number of as , 6 is number of bs , 4 is number of cs , 4 is number of spaces () and so on . Also you can split answers with space (like example) , EOL , or anything other than numerals .

Rules

Your program must log to STDOUT or an acceptable alternative, if STDOUT is not available.

Your program must be a full, runnable program, and not a function or snippet

It's optional to mention the ungolfed version of program and/or a short explanation .

Test input : ThIs Is ThE iNPUT , WITH 72/2 CHARS!

Test output : 4 2 3 2 7 1 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1

user55673

Posted 2016-06-23T09:22:51.333

Reputation:

Question was closed 2016-06-23T16:12:33.137

4What is the reason for disallowing functions? Does not make much sense for this challenge and gives a significant disadavante to languages like Java. – Denker – 2016-06-23T11:13:46.443

2

For reference, the default allows programs and functions but disallows snippets and also allows a few alternative output methods. This is a nice first challenge, but nevertheless I'd recommend posting future challenge ideas in the sandbox so you can get feedback before posting them. :)

– Martin Ender – 2016-06-23T12:15:02.997

2Spaces, newlines, tabs, carriage returns, nonbreaking spaces and vertical tabs are *not printable ASCII*, yet your example contains and counts spaces. Do we count all the bytes of the input or not? – cat – 2016-06-23T13:43:11.187

Can there be a trailing space? – Daniel – 2016-06-23T13:51:54.333

2

@cat Spaces are printable ASCII.

– Martin Ender – 2016-06-23T15:33:25.130

Answers

7

MATL, 3 bytes

8#u

Input is a string enclosed with quotation marks (which is allowed by default)

Try it online!

Explanation

u is the unique function, which essentially removes duplicates. It can produce up to four outputs. The fourth output is the count of unique characters, identified in order of appearance.

8# specifies that the fourth output of u should be produced. In general, 2# means "produce two outputs", 3# means "produce three outputs" etc. When the maximum number of function outputs is reached, larger numbers mean "take the first output only", or "the second only" etc. Thus, since u has four possible outputs, 4# would produce all four outputs; 5# produces the first, 6# the second, etc.

Luis Mendo

Posted 2016-06-23T09:22:51.333

Reputation: 87 464

well , it doesn't work with ' at first and end , which is not allowed , can you edit it in a way that it doesn't need ' ? or is this an implemented feathure in the language ? – None – 2016-06-23T09:41:48.497

I'm not sure what you mean. About strings using quotes, see here

– Luis Mendo – 2016-06-23T09:43:48.787

Ok , i didn't know that – None – 2016-06-23T09:45:12.733

4

05AB1E, 6 bytes

Ùv¹y¢,

Explained

Ùv      # for each unique char in original order
  ¹y¢   # count number of occurances in input string
     ,  # print on newline

Try it online

Emigna

Posted 2016-06-23T09:22:51.333

Reputation: 50 798

you have forgot to delete """ (quation marks) in try it online , which produced extra 2 at the first of output – None – 2016-06-23T09:30:34.363

@GLASSIC: Yeah, I just noticed. Thanks! – Emigna – 2016-06-23T09:31:21.740

4

Pyth, 4 bytes

/LQ{

Test suite.

Explanation

/LQ{    Input: Q
/LQ{Q   Implicitly fill arguments

   {Q   Yield the unique elements of Q.
 L      For each unique element:
/       Yield its number of occurrences
  Q     in Q.

Leaky Nun

Posted 2016-06-23T09:22:51.333

Reputation: 45 011

3

J, 18 15 bytes

echo#/.~stdin''

Following the challenge spec to write a program, the above is a one-line script in J that reads a line from stdin, computes the result, and prints it to stdout.

If using an online interpreter, it would require 4 bytes since without stdio, only function arguments could be used.

#/.~

Straight-forward application of adverbs /. and ~ to the tally # verb.

Usage

As a script,

$ echo -n 'aaaabbbbbcccc    123445b' | jconsole golf.j 
4 6 4 4 1 1 1 2 1

As a function,

   (#/.~) 'aaaabbbbbcccc    123445b'
4 6 4 4 1 1 1 2 1

Explanation

#/.~  Input: s
   ~  Reflects the input
 /.   An adverb that executes a verb on each set of identical items in s
      Operates in the order of first-seen distinct items in s
#     Get the size of each set of identical items
      Returns a list of the sizes of identical items

miles

Posted 2016-06-23T09:22:51.333

Reputation: 15 654

2

CJam, 9 bytes

l__&\fe=p

Test it here.

Explanation

l    e# Read input.
__   e# Make two copies.
&    e# Set intersection - removes duplicates.
\    e# Swap with input.
fe=  e# For each (unique) character, count its occurrences.
p    e# Print as array literal.

Martin Ender

Posted 2016-06-23T09:22:51.333

Reputation: 184 808

2

Dyalog APL, 10 bytes

Shortest by byte count

+⌿t∘.=∪t←⍞

t←⍞ get character input and store as t

`∪' unique elements of

t∘.= table of which elements of t are equal to (the unique elements of t)

+⌿ sum the columns

5 character solution which unfortunately is 15 bytes:

⊢∘≢⌸⍞

get character input

make a table of contents containing...

⊢∘≢ the tally () of the indices while the entries are ignored ()

Adám

Posted 2016-06-23T09:22:51.333

Reputation: 37 779

2

Jelly, 4 bytes

Qċ@€

Try it online

Explanation

Qċ@€   Main link. Argument: S

Q      Remove duplicate characters from S.
       Current value v contains each character of S once sorted by first appearance.
  @€   For each character in v.
 ċ       count its occurrence in S.

Essari

Posted 2016-06-23T09:22:51.333

Reputation: 541

1

Mathematica, 56 bytes

Print@StringRiffle[Last/@Tally@Characters@InputString[]]

Essentially, Tally does exactly what the challenge asks for (although it gives pairs of {element, count}). The rest is just for working with strings and proper I/O for a full program.

Martin Ender

Posted 2016-06-23T09:22:51.333

Reputation: 184 808

1

Retina, 30 28 bytes

2 bytes thanks to Martin Ender.

+`((.).+)\2
$2$1
(.)\1*
$.&¶

Try it online!

Leaky Nun

Posted 2016-06-23T09:22:51.333

Reputation: 45 011

1

Brachylog, 32 bytes

:efd:?:{tL,?he:L:{t:.m~h?}fl.}f.

Awfully long but there's no simple way of counting elements of something yet…

Fatalize

Posted 2016-06-23T09:22:51.333

Reputation: 32 976

1

Java 7, 246 235 231 213 bytes

Loads of bytes removed thanks to cliffroot.

import java.util.*;class M{public static void main(String[]a){Map<Long,Long>m=new LinkedHashMap();for(long c:a[0].toCharArray())m.put(c,m.get(c)!=null?m.get(c)+1:1);for(Long e:m.values())System.out.print(e+" ");}}

Ungolfed & test code:

Try it here.

import java.util.*;

class Main{
  public static void main(String[] a){
    // Test code:
    a = new String[]{ "ThIs Is ThE iNPUT , WITH 72/2 CHARS!" };

    Map<Long, Long> m = new LinkedHashMap();
    for(long c : a[0].toCharArray()){
      m.put(c, m.get(c) != null ? m.get(c) + 1 : 1);
    }
    for(Long e : m.values()){
      System.out.print(e + " ");
    }
  }
}

Output:

4 2 3 2 7 1 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1 

Kevin Cruijssen

Posted 2016-06-23T09:22:51.333

Reputation: 67 575

1You can use Map m=new LinkedHashMap which saves some bytes. Also in your first loop you can use int instead of char – cliffroot – 2016-06-23T11:03:01.147

@cliffroot Ah of course, edited. Thanks! – Kevin Cruijssen – 2016-06-23T11:06:58.603

1Map<Long,Long>m=new LinkedHashMap<>(); saves 2 more bytes because it allows to remove cast to int (though you'll have to use long in the first cycle) and to use Map.Entry in your second for-each loop. – cliffroot – 2016-06-23T11:09:58.150

1The last for loop is basically just for(Long e:m.values())System.out.print(e+" "); – cliffroot – 2016-06-23T12:15:18.587

1

Python 3, 134 81 bytes

s,r=input(),[]
for c in s:
 k,s=s.count(c),s.replace(c,'')
 if k:r+=[k]
print(*r)

Output:

4 2 3 2 7 1 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1

Not that short :(


Another approach: 109 bytes

Not shorter than the others but the counting happens in a one-liner.

s=input()
k=[i[1]for i in sorted({i:str(s.count(i))for i in s}.items(),key=lambda v:s.index(v[0]))]
print(*k)

Edit: Golfed 53 bytes thanks to @Dr Green Eggs and Iron Man Edit 2: Added one-liner method

Gábor Fekete

Posted 2016-06-23T09:22:51.333

Reputation: 2 809

You could make this a lot shorter by deleting the first and last lines, and putting s=input();r=[] – James – 2016-06-23T13:41:23.317

1

Java 7, 172 168 bytes

class M{public static void main(String[]a){int[]m=new int[256];byte[]b=a[0].getBytes();for(int z:b)m[z]++;for(int z:b){System.out.print(m[z]>0?(m[z]+" "):"");m[z]=0;}}}

Stores number of occurrences in an int array, then for each char print number of occurrences and replace this value with zero so it won't be printed again.

Whitespaces and comments added:

class M{
    public static void main(String[]a){
        int[]m=new int[256]; // map, ascii value to number of occurrences
        byte[b]=a[0].getBytes();
        for(int z:b)m[z]++; // count number of occurrences
        for(int z:b){
            System.out.print(m[z]>0?(m[z]+" "):""); // print result 
            m[z]=0; // make it not be printed again
        }
    }
}

See it online: https://ideone.com/7X58F9

cliffroot

Posted 2016-06-23T09:22:51.333

Reputation: 1 080

1

+1 and since you've helped me out in my Java 7 answer I'll help you as well. :) You can add byte[]b=a[0].getBytes(); and replace both a[0].getBytes() with b to save 4 bytes.

– Kevin Cruijssen – 2016-06-24T07:40:02.720

@Kevin Cruijssen oh right, thank you. We can arguably do byte[]m=new byte[256],b=a[0].getBytes();, but then number of symbols occurrences will be limited to 256 – cliffroot – 2016-06-24T08:18:46.250

0

C#

public static void Main(string[] args)
    {
        string str = "aaaabbbbbcccc    123445b";
        Dictionary<char, int> counts = new Dictionary<char, int>();

        for (int i = 0; i < str.Length; i++)
           if (counts.ContainsKey(str[i]))
               counts[str[i]]++;
           else
              counts.Add(str[i], 1);

        foreach (var count in counts)
         Console.WriteLine("{0} = {1}", count.Key, count.Value.ToString());
    }

Manish Kumar Singh

Posted 2016-06-23T09:22:51.333

Reputation: 101

2

Hi, and welcome to the site! This is a [tag:code-golf] challenge, meaning all answers must at least make an attempt to shorten their code as much as possible. For example, you can remove your whitespace, and use one letter variable names. You can also look through our list of tips for golfing in C#. If you don't try to shorten this code, the answer is invalid, and it will probably need to be deleted.

– James – 2016-06-23T13:33:52.680

0

ES6, 90 bytes

a=prompt();b=new Map();for(c of a)b.set(c,(b.get(c)|0)+1);alert([...b.values()].join(' '))

bodqhrohro

Posted 2016-06-23T09:22:51.333

Reputation: 583

0

Python 3, 76 73 bytes

3 bytes shorter:

s,a=input(),[]
for y in s:a+=(y,'')[y in a]
print([s.count(x)for x in a])

Old version:

s=input();print([s.count(x)for x in sorted(set(s),key=lambda i:s.index(i))])

Iterates over a sorted set of unique characters from the input, counts the occurrences, and outputs a list of the counts.

atlasologist

Posted 2016-06-23T09:22:51.333

Reputation: 2 945

@LeakyNun That returns the generator object for me. – atlasologist – 2016-06-23T12:29:07.957

I don't understand. Doesn't sorted(s) have the same number of elements? – Leaky Nun – 2016-06-23T12:30:12.067

sorted(s) has the same number of elements as the input, but I'm sorting a set of the input that has only unique elements (using the indexes of the original as the key, to preserve the order). – atlasologist – 2016-06-23T12:37:23.103

Does set preserve input order? – Leaky Nun – 2016-06-23T12:38:25.163

No, it's unordered. https://docs.python.org/3/tutorial/datastructures.html#sets A set is an unordered collection with no duplicate elements.

– atlasologist – 2016-06-23T12:41:18.853

@Dopapp not for Python 3. – atlasologist – 2016-06-23T14:48:31.003

@atlasologist oh. Good to know! – Daniel – 2016-06-23T14:55:45.897

0

Python 2.7 - 103 Bytes (Ungolfed)

i=list(raw_input())
print ''.join([str(e) for e in map(lambda x,y:x!=y and i.count(x)or' ',i,['']+i) ])

edit: Thanks to Dr Green Eggs and Iron Man for helping to reduce 47 Bytes!

Swadhikar C

Posted 2016-06-23T09:22:51.333

Reputation: 141

You can shorten it by 36 bytes by changing the first three lines to i=input() I don't think stripping whitespace or printing the original string is necessary. – James – 2016-06-23T13:45:02.460

You could also just do print s on the last line. (Although I haven't tested that) you might need print list(s) or print[s] – James – 2016-06-23T13:50:03.340

0

Python 3, 93 bytes

s=input();c,o=[],""
for i in s:
 if i not in c:c+=i
for i in c:o+=str(s.count(i))+" "
print o

Daniel

Posted 2016-06-23T09:22:51.333

Reputation: 6 425

0

Matlab, 47 chars

@(y)arrayfun(@(x)sum(y==x),unique(y,'stable'))

Reasonably straightforward, though the default behavior of Matlab's unique function to sort the values makes the function rather longer.

sintax

Posted 2016-06-23T09:22:51.333

Reputation: 291

0

Pyke, 3 bytes

}F/

Try it here!

for i in uniquify(input): print input.count(i)

Blue

Posted 2016-06-23T09:22:51.333

Reputation: 26 661