Skip to content

Instantly share code, notes, and snippets.

@BoringCode
Created September 12, 2013 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BoringCode/6537959 to your computer and use it in GitHub Desktop.
Save BoringCode/6537959 to your computer and use it in GitHub Desktop.
Histogram class written in Ruby. Also a frequency method is added to the Array class.
class Histogram
#Create the object
def initialize(words)
#These are used later for calculating how many * are displayed
@highestWordCount = 0
@longestCharWord = 0
#Save the original word array
@raw = words
@wordsHash = Hash.new
#place words in hash
@raw.each do |word|
#This will be used later for the display method
if word.length > @longestCharWord
@longestCharWord = word.length
end
#Check if word exists in hash
if @wordsHash[word].nil?
@wordsHash[word] = @raw.count(word)
if @raw.count(word) > @highestWordCount
@highestWordCount = @raw.count(word)
end
end
end
end
#Output histogram
def display(n = -1)
#Only display n number of words
count = 0
#Calculate how much space the word with the most entries needs to fill
spaceAvailable = (77 - @longestCharWord).round(2)
if (spaceAvailable < @highestWordCount)
scale = (@highestWordCount / spaceAvailable)
#This sets how the scale is displayed to the user
displayScale = scale.round(3).to_s()
else
scale = (spaceAvailable / @highestWordCount)
#In this case each * represents less than one word
displayScale = (@highestWordCount / spaceAvailable).round(3).to_s()
end
#Display the scale to the user
print "Scale: 1 * = " + displayScale + " word(s)\n\n"
#Sort by value, descending
sorted = @wordsHash.sort_by {|k,v| v}.reverse
#Loop through each key, value pair in the hash
sorted.each do |word, num|
if count < n || n == -1
#Number of spaces after word so pipes line up
spaces = " "*(@longestCharWord - word.length)
#Check how many stars should be displayed
if spaceAvailable < num
numToDisplay = num / scale
else
numToDisplay = num*scale
end
#Display the string
print word + spaces + " |" + "*"*(numToDisplay) + "\n"
count = count + 1
else
break
end
end
nil
end
end
#Bonus points
class Array
def frequency
returnHash = Hash.new
#Loop through each item in the array
self.each do |item|
#Check if word exists in hash
if returnHash[item].nil?
returnHash[item] = self.count(item)
end
end
returnHash
end
end
arr = ["bradley", "kyle", "kyle", "bye", "hello", "bye", "bye", "bye", "bye", "bye", "bye", "test", "test", "bradley", "test", "test", "test", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "bradley", "bradley", "bradley", "bradley", "hello", "hello", "hello", "bradley", "bradley", "hello", "bradley", "hello", "bradley"]
#RUN THE THING!
hs = Histogram.new(arr)
hs.display
#Returns a hash
puts arr.frequency
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment