Problem of the Day
A new programming or logic puzzle every Mon-Fri

Character Frequency

Another great Monday is upon us! Today's Problem of the Day comes from user D. Thanks for the submission!

For some input string, for example "Feel free to include attribution details such as a Twitter handle so you can get credit for submitting the problem.", determine the character frequencies and display a simple visualization:

      ...................
    e ............
    t ............
    i ........
    r ......
    o ......
    a ......
    l .....
    n .....
    u .....
    s .....
    c ....
    d ....
    b ...
    h ...
    f ..
    g ..
    m ..
    F .
    T .
    w .
    y .
    p .
    . .

Permalink: http://problemotd.com/problem/character-frequency/

Comments:

  • Emre Ozdemir - 3 years ago

    #include <iostream>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    int main()
    {
        int  k, i;
        int arr[123][2]= {0};
        string str;
        getline(cin,str);
    
        for(k=0;k<=122;k++)
            arr[k][0]=k;
    
    
        for(i=65;i<=122;i++)            //Letter counter
        {
            for(k=0;k<str.length();k++)
            {
                if(str[k]==i)
                    arr[i][1]++;
            }
        }
    
        for(i=65;i<=122;i++)        //Sorts by number of letters and swaps
        {
            for(k=i+1;k<=122;k++)
            {
                if(arr[i][1]<arr[k][1])
                {
                swap(arr[i][0],arr[k][0]);
                swap(arr[i][1],arr[k][1]);
                }
    
            }
        }
    
        for(i=65;i<=122;i++)        //Dot and letter printer
        {
            if(arr[i][1]>0)
            {
                printf("%c", arr[i][0]);
                for(k=1;k<=arr[i][1];k++)
                    cout<<'.';
    
                puts("\n");
            }
        }
    
        getchar();
        getchar();
        return 0;
    }
    

    reply permalink

  • Pyro - 3 years ago

    My code in python. It's not really optimised but works well!

    def print_dots(n):
        print " ",
        for i in range(n):
            print ".",
        print " "
    
    lst = [[i,0] for i in xrange(127)]
    text=raw_input("text?\n")
    
    for i in range(len(text)):
        lst[ord(text[i])][1]=lst[ord(text[i])][1]+1
    lst.sort(key=lambda x: x[1], reverse=True)
    not_finished=True
    
    while not_finished:
        for i in xrange(127):
            if lst[i][1]>0:
                print chr(lst[i][0]),
                print_dots(lst[i][1])
        not_finished=False
    

    reply permalink

  • Pearce Keesling - 3 years ago

    Getting them to display in descending was a little ugly, but the output is quite elegant IMHO opinion. Alphabetical order was a side-effect :). Wrote this in C.

    #include <stdio.h>
    #include <string.h>
    
    int compare (const void * a, const void * b)
    {
        return(*(int*)a - *(int*)b);
    }
    
    int main(int argc, char* argv[])
    {
        int frequency[256] = {0};
        for(int i = 0; i < strlen(argv[1]);i++)
        {
            frequency[argv[1][i]] ++;
        }
        int max_i = 0;
        int max = 0;
        do
        {
            max =0;
            for(int i = 0; i < 256;i++)
            {
                if(frequency[i]>max)
                {
                    max = frequency[i];
                    max_i = i;
                }
            }
            if(frequency[max_i]==0)continue;
            printf("%c ",max_i);
            while(frequency[max_i]>0)
            {
                printf(".");
                frequency[max_i]--;
            }
            printf("\n");
        }while(max>0);
    
        return 0;
    }
    

    reply permalink

  • Tim - 3 years ago

    Happy to add another python submission to the pile. How does one enable pretty markup?

    def counter(input_string): dictionary = {} for l in input_string: if l != " ": dictionary[l] = dictionary.get(l, 0) + 1 return dictionary

    def graph(input_string): data = counter(input_string) tdata = data.items() tdata.sort(key=lambda tup: tup[1]) for tup in reversed(tdata): print tup[0], "."*tup[1]

    graph("Feel free to include attribution details such as a Twitter handle so you can get credit for submitting the problem.")

    reply permalink

  • Pyro - 3 years ago

    You have to put ``` before and after the code!

    reply permalink

  • Tim - 3 years ago

    Thanks!

    def counter(input_string):
        dictionary = {}
        for l in input_string:
            if l != " ":
                dictionary[l] = dictionary.get(l, 0) + 1
        return dictionary
    
    def graph(input_string):
        data = counter(input_string)
        tdata = data.items()
        tdata.sort(key=lambda tup: tup[1])
        for tup in reversed(tdata):
            print tup[0], "."*tup[1]
    
    graph("Feel free to include attribution details such as a Twitter handle so you can get credit for submitting the problem.")
    

    reply permalink

  • SithEngineer - 3 years ago

    a C# solution...

        public struct CharCount {
            public ulong Count;
            public char Value;
        }
    
        public static LinkedList<CharCount> CountChars(string toCount) {
            char[] charArray = toCount.ToCharArray();
            int charCounterLength = (int) Math.Pow(2, sizeof(char) * 8);
            ulong[] charCounter = new ulong[charCounterLength];
    
            // count chars
            for(int i = 0 ; i < charArray.Length ; ++i) {
                charCounter[charArray[i]]++;
            }
    
            // render response
            LinkedList<CharCount> result = new LinkedList<CharCount>(); 
            for(int i = 0 ; i < charCounterLength ; ++i) {
                if(charCounter[i] > 0) {
                    result.AddFirst( new CharCount { Count = charCounter[i], Value = (char)i } );
                }
            }
            return result;
        }
    

    and test code...

    public static void Main() 
    {
        var data = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse commodo est eu massa scelerisque vehicula. Integer vehicula dolor eu aliquet.";
        Console.WriteLine ("counting chars frequency of: {0}", data);
    
        var result = Algorithms.CountChars(data);
        foreach(var countResult in result) {
            Console.WriteLine ("{0} apeared {1} times", countResult.Value, countResult.Count);    
        }
    
        // Keep the console window open in debug mode.
        Console.WriteLine ("Press any key to exit.");
        Console.ReadKey();
    }
    

    reply permalink

  • Nick Krichevsky - 3 years ago

    Python Code!

    d={}
    for char in string:
        if char not in d:
            d[char]=1
        else:
            d[char]+=1
    for item in d:
        print item,
        print " ",
        for i in range(d[item]):
            print '.',
        print ""
    

    reply permalink

  • Akshay Bist - 3 years ago

    My Python solution

    from collections import Counter
    import operator
    
    
    def get_sorted_freq(text):
        freq = Counter(text)
        return sorted(freq.iteritems(), key=operator.itemgetter(1), reverse=True)
    
    
    def print_result(sorted_freq):
        for char, freq in sorted_freq:
            print "{0}:\t{1}".format(char, "." * freq)
    
    
    def main():
        text = raw_input("Enter text: ")
        sorted_freq = get_sorted_freq(text)
        print_result(sorted_freq)
    
    
    if __name__ == "__main__":
        main()
    

    reply permalink

  • rav - 3 years ago

    Python:

    
    import sys
    import operator
    
    phrase = "Feel free to include attribution details such as a Twitter handle so you can get credit for submitting the problem".lower()
    frequency = {}
    
    for letter in phrase:
      try:
        frequency[letter]
      except KeyError:
        frequency[letter] = 1
      else:
        frequency[letter] = frequency[letter] + 1
    
    frequency.pop(" ", None)
    
    sortFreq = sorted(frequency.iteritems(), key=operator.itemgetter(1),reverse=True)
    
    for key,value in sortFreq:
      dots = ''
      for i in range(0,value):
        dots = dots + '.'
      print key + ": " + dots
    
    

    reply permalink

  • ujjl - 3 years ago

    Haskell solution

    import Data.Map
    charFreq input = putStr $ formatFreq ( toList $ fromListWith (+) [(c, 1) | c <- input] )
    
    formatFreq [] = []
    formatFreq ((a,b):xs) = a:' ':(take b (repeat '.'))++"\n"++(formatFreq xs)
    

    Output:

    *Main> charFreq "abcdefgabc deabcdabcaba"
      .
    a ......
    b .....
    c ....
    d ...
    e ..
    f .
    g .
    

    reply permalink

  • James - 3 years ago

    Python solution. Anyone give feedback?

    def charfreq(string):
        l = list(string)
        s = list(set(l))
        p = []
        for i in s:
            p.append((i, l.count(i)))
        p = sorted(p, key=lambda x: x[1], reverse=True)
        for i in p:
            print('{}{}'.format(i[0], i[1]*'.'))
    

    reply permalink

  • Ben - 3 years ago

    A C# solution using LINQ:

    public static void Main()
    {
        var input = Console.ReadLine();
        var inputArray = input.ToCharArray();
        var distinctChars = inputArray.GroupBy(i => i);
    
        foreach (var character in distinctChars.OrderByDescending(d => d.Count()))
        {
            Console.Write(character.Key + " ");
            for (var i = 0; i < character.Count(); i++)
            {
                Console.Write('.');
            }
    
            Console.WriteLine();
        }
    
        Console.ReadKey();
    }
    

    reply permalink

  • Hueho - 3 years ago

    def frequencies(phrase)
      multiset = Hash.new { |hash, key| hash[key] = 0 }
      phrase.chars.each { |ch| multiset[ch] += 1 }
      multiset
    end
    
    def sort(frequencies)
      frequencies.to_a.sort_by { |arr| arr[1] }
    end
    
    def output(ordered_freq)
      ordered_freq.each do |ch, count|
        puts "#{ch} " + ('.' * count)
      end
    end
    
    output sort(frequencies(ARGF.read)).reverse
    

    Reads the phrase from the standard input or loading any file passed to script as a argument

    reply permalink

  • Anonymous - 2 years, 11 months ago

    #python 2.7
    import string
    from operator import itemgetter
    
    def charfreq(b):
    
        mydict = {}
    
        for letters in b:
            mydict.update({letters: 0})
    
        for letters in b:
            mydict[letters] = mydict[letters] + 1
    
        sortedletters = sorted(mydict.items(), key=itemgetter(1))[::-1]
    
        i = 0
        while i < len(sortedletters):
            print sortedletters[i][0], ":", "*"*sortedletters[i][1]
            i = i + 1
    

    reply permalink

Content curated by @MaxBurstein