Problem 1
In cryptography, a Caesar cipher, also called a shift cipher, encrypts a plaintext string by shifting the letters by a fixed number of positions shift_by. For example, if shift_by=3, then a shifts to d, b to e, x to a, A to D, and Z to C. Note that lowercase letters ‘wrap around', as do uppercase letters. Only upper- and lower-case letters are shifted; all other characters, including whitespace, punctuation, and digits, encode as themselves. Write a class CaesarCipher that gets constructed on the value shift_by. Its encode method encodes a string by shifting letters by shift_by positions, and its decode method decodes an encoded string.
>> cipher_1 = CaesarCipher.new(1)
>> s = 'A man, a plan, a canal: Panama!'
=> "A man, a plan, a canal: Panama!"
>> s_encoded = cipher_1.encode(s)
=> "B nbo, b qmbo, b dbobm: Qbobnb!"
>> cipher_1.decode(s_encoded)
=> "A man, a plan, a canal: Panama!"
>> cipher_12 = CaesarCipher.new(12)
>> cipher_12.encode(s)
=> "M ymz, m bxmz, m omzmx: Bmzmym!"
>> cipher_12.decode (cipher_12.encode(s))
=> "A man, a plan, a canal: Panama!"
>> cipher_12.decode(s_encoded)
=> "P bpc, p eapc, p rpcpa: Epcpbp!"
# s_encoded constructed with shift_by=1; wrong decoder!
Problem 2
Write a PhoneNumber class that gets initialized with a 10-digit phone number. In the call PhoneNumber.new(ph), the input ph take any of these possible formats:
- a 10-digit integer
- a string of 10 digits
- (ddd) ddd-dddd where d is any digit [parenthesis format]
- ddd-ddd-dddd where d is any digit [hyphen format]
Wherever whitespace appears in a string format, we can have a string of zero or more whitespace characters (including before and after the string as a whole). A PhoneNumber object responds to the to_s message which returns the number as a string in parenthesis format, and the area_code, prefix, and root messages which return the parts of the number in string format, as illustrated here:
a = PhoneNumber.new(1234567890)
puts a # (123) 456-7890
puts a.area_code # 123
puts a.prefix # 456
puts a.root # 7890
puts PhoneNumber.new(' 7778889999 ') # (777) 888-9999
puts PhoneNumber.new(' (555)444-3333') # (555) 444-3333
PhoneNumber.new('1234')
# ArgumentError: Improper phone number syntax
PhoneNumber.new('(12) 333-4444')
# ArgumentError: Improper phone number syntax
PhoneNumber.new('123- 456- 7890')
# ArgumentError: Improper phone number syntax
Problem 3
Write a function word_count(s) that parses the string s into words and returns an array (of arrays of the form [word, count]) representing the frequency of each word. Words are case-insensitive:
'Hello', 'HELLO', and 'hello' are instances of the same word. It is helpful to write helper functions in addition to word_count.
The following processes the first paragraph of Alice in Wonderland. Note that res2 is an array of those words that occur at least twice in this paragraph.
some_text = <
Alice was beginning to get very tired of sitting by her sister on the bank,and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it," and what is the use of a book," thought Alice "without pictures or conversation?"
SAMPLE_TEXT
res = word_count(some_text)
print res, "\n\n"
res2 = res.select { |pair| pair[1] > 1 }
res2.sort.each do |key, count|
puts "#{key}: #{count}"
end
[["of", 3], ["or", 3], ["the", 3], ["alice", 2], ["and", 2], ["book", 2], ["had", 2], ["her", 2], ["it", 2], ["pictures", 2], ["sister", 2], ["to", 2], ["was",2], ["a", 1], ["bank", 1], ["beginning", 1], ["but", 1], ["by", 1], ["conversation", 1], ["conversations", 1], ["do", 1], ["get", 1], ["having", 1], ["in", 1],["into", 1], ["is", 1], ["no", 1], ["nothing", 1], ["on", 1], ["once", 1], ["peeped", 1], ["reading", 1], ["she", 1], ["sitting", 1], ["thought", 1], ["tired",1], ["twice", 1], ["use", 1], ["very", 1], ["what", 1], ["without", 1]]
alice: 2
and: 2
book: 2
had: 2
her: 2
it: 2
of: 3
or: 3
pictures: 2
sister: 2
the: 3
to: 2
was: 2