Ruby Anagram Comparison Module - ruby

I am new to Ruby and trying to figure out a problem for an online test. The problem is as follows:
An anagram is a word formed from another by rearranging its letters,
using all the original letters exactly once; for example, orchestra
can be rearranged into carthorse.
Write a function that checks if two words are each other's anagrams.
For example, AreAnagrams.are_anagrams?('momdad', 'dadmom') should
return true as arguments are anagrams.
The code I have come up with is this:
module AreAnagrams
def self.are_anagrams?(string_a, string_b)
## Create #word1 variable to store string_a
#word1 = string_a
## Create #word1_compare variable to store string_a in lower case
#word1_compare = #word1.downcase
## Create #word2_compare variable to store string_b
#word2 = string_b
## Create #word2_compare variable to store string_b in lower case
#word2_compare = #word2.downcase
## Check length of #word1 and #word2 to make sure they are the same length
if #word1.length == #word2.length
=begin
Sort the letters of the #word1 and #word2 variables and compare
them to see if they are anagrams
=end
if #word1_compare.chars.sort.join == #word2_compare.chars.sort.join
puts "#{#word1} and #{#word2} are anagrams!"
else
puts "#{#word1} and #{#word2} are not anagrams!"
end
else
puts "#{#word1} and #{#word2} are not anagrams!"
end
end
end
When I submit the code, I get the following back from the test:
Compilation OK, but 4 out of 4 test cases fail
Sample case: Wrong answer
Words with unique letters: Wrong answer
Words with duplicate letters: Wrong answer
One word is the prefix of another word: Wrong answer
I have tested my code with multiple strings and it seems to work just fine. It looks like it wants me to check for more specific instances (special characters, words with duplicate letters, etc.) but is that really required? Sorry if it's a dumb question, I'm new to Ruby and lost.
Any help would be greatly appreciated!

I think the problem here is you're displaying a message but not returning a true or false value which is what is expected.
After each puts, include the appropriate answer. That way your method will return something useful. Right now I'm presuming it's nil for all cases, since that's what puts returns.

Related

bad value in range argument error - regarding range construction in ruby

I wrote the following snippet.
def add_me(num)
result = 0
(1..num).each { |i| result += i}
result
end
puts add_me(STDIN.gets)
I received an argument error list_sum.rb:6:in 'AddMe': bad value for range (ArgumentError) the line # corresponds to line # in my editor.
I also experimented with things like foo = (1..num).to_a. But still receive the same error. What is going on? Ruby version 2.3.3. What am I missing? I should be able to use variables in ranges, no?
gets returns a string. You need to do gets.to_i, in order to turn the input into a number for your numeric range. Right now you’re trying to make a range where the start is the number 1 and the end is some string, and that is raising an ArgumentError.
Also as an aside, ruby convention would tell you that your function should be named add_me. Ruby uses snake case, and anything that starts with a capital letter is typically assumed to be a class or constant (constant being all caps).

Push an array into another array with Ruby, and return square brackets

I've spent a few hours searching for a way to push an array into another array or into a hash. Apologies in advance if the formatting of this question is bit messy. This is the first time I've asked a question on StackOverflow so I'm trying to get the hang of styling my questions properly.
I have to write some code to make the following test unit past:
class TestNAME < Test::Unit::TestCase
def test_directions()
assert_equal(Lexicon.scan("north"), [['direction', 'north']])
result = Lexicon.scan("north south east")
assert_equal(result, [['direction', 'north'],
['direction', 'south'],
['direction', 'east']])
end
end
The most simple thing I've come up with is below. The first part passes, but then the second part is not returning the expected result when I run rake test.
Instead or returning:
[["direction", "north"], ["direction", "south"], ["direction",
"east"]]
it's returning:
["north", "south", "east"]
Although, if I print the result of y as a string to the console, I get 3 separate arrays that are not contained within another array (as below). Why hasn't it printed the outermost square brackets of the array, y?
["direction", "north"]
["direction", "south"]
["direction", "east"]
Below is the code I've written in an attempt to pass the test unit above:
class Lexicon
def initialize(stuff)
#words = stuff.split
end
def self.scan(word)
if word.include?(' ')
broken_words = word.split
broken_words.each do |word|
x = ['direction']
x.push(word)
y = []
y.push(x)
end
else
return [['direction', word]]
end
end
end
Any feedback about this will be much appreciated. Thank you all so much in advance.
What you're seeing is the result of each, which returns the thing being iterated over, or in this case, broken_words. What you want is collect which returns the transformed values. Notice in your original, y is never used, it's just thrown out after being composed.
Here's a fixed up version:
class Lexicon
def initialize(stuff)
#words = stuff.split
end
def self.scan(word)
broken_words = word.split(/\s+/)
broken_words.collect do |word|
[ 'direction', word ]
end
end
end
It's worth noting a few things were changed here:
Splitting on an arbitrary number of spaces rather than one.
Simplifying to a single case instead of two.
Eliminating the redundant return statement.
One thing you might consider is using a data structure like { direction: word } instead. That makes referencing values a lot easier since you'd do entry[:direction] avoiding the ambiguous entry[1].
If you're not instantiating Lexicon objects, you can use a Module which may make it more clear that you're not instantiating objects.
Also, there is no need to use an extra variable (i.e. broken_words), and I prefer the { } block syntax over the do..end syntax for functional blocks vs. iterative blocks.
module Lexicon
def self.scan str
str.split.map {|word| [ 'direction', word ] }
end
end
UPDATE: based on Cary's comment (I assume he meant split when he said scan), I've removed the superfluous argument to split.

Ruby unjumble words and match to dictionary [duplicate]

This question already has an answer here:
ruby to unjumble words [closed]
(1 answer)
Closed 8 years ago.
I am trying to write ruby code that unscrambles the word entered and then match those word to a dictionary. The goal is to find match those words to dictionary and find a word in the dictionary and print it. This is how my code looks like.
print "Enter scrambled word here:"
Jumble = gets.chomp
a = Jumble.split("")
perms = a.permutation.to_a.collect do |perm|
perm.join
end
return perms
fin = File.open("dict.txt", "r")
while line = fin.gets
word = line.chomp
if word = word.downcase
perms = word
print perms
end
end
fin.close
My code seems to work fine until "return perms". it gives me error saying unexpected return (LocalJumpError). i do not know if my code after that point is correct or not because i cannot get past that point. I somehow need to get those perms and match them with the dictionary. The first word that is found in the dictionary needs to be printed. How do i go about that.
This is what the dictionary looks like:
words_un
Aarhus
Aaron
Ababa
aback
abaft
abandon
abandoned
abandoning
abandonment
abandons
abase
...
Zulus
Zurich
I appreciate the feedback.
return perms
Values (objects) get returned from methods, or functions. Technically you are not in a method, so Ruby has no idea what you are talking about.
Extra: technically you are inside the Object class, and you cannot return things from a class.

Ruby Spell Checker Not Working Properly

I am writing a small project in ruby that takes all of the words from a website and then sorts them short to long.
To verify that what gets sorted is actually valid english I am comparing an array of scraped words to the basic unix/osx words file.
The method to do this is the spell_check method. The problem is that when used on small arrays is works fine, but with larger ones it will let non-words through. Any ideas?
def spell_check (words_array)
dictionary = IO.read "./words.txt"
dictionary = dictionary.split
dictionary.map{|x| x.strip }
words_array.each do |word|
if !(dictionary.include? word)
words_array.delete word
end
end
return words_array
end
I simplified your code, maybe this will work?
def spell_check(words)
lines = IO.readlines('./words.txt').map { |line| line.strip }
words.reject { |word| !lines.include? word }
end
I noticed that you were trying to modify the words_array while you were simultaneously iterating over it with each:
words_array.each do |word|
if !(dictionary.include? word)
words_array.delete word # Delete the word from words_array while iterating!
end
end
I'm not sure if this is the case in Ruby, but in other programming languages like Java and C#, trying to modify a collection, while you're iterating over it at the same time, invalidates the iteration, and either produces unexpected behavior, or just throws an error. Maybe this was your problem with your original code?
Also, the return statement was unnecessary in your original code, because the last statement evaluated in a Ruby block is always returned (unless there's an explicit return that precedes the last statement). It's idiomatic Ruby to leave it out in such cases.

RegEx in Ruby: Just one match?

I'm trying to figure out how to check if a string matches a regular expression, but I want to know if the entire string matches just once. Here's my code but it seems absurdly long
def single_match(test_me, regex)
ret_val = false
test = regex.match(test_me)
if (test.length==1 && test[0].length == test_me.length)
ret_val = true
end
return ret_val
end
is there an easier way to do this?
P.S. Here's the method I'm really trying to write, since people always seem to ask why I want the gun these days:
def is_int(test_me)
return single_match(test_me, /[0-9]*/)
end
Edit Thanks everybody. Here's where I'm really using it, but this regex stuff is always interesting to go through. Thanks for the great and educational answers.
You don't need to do this, your method can be replaced by using the regular expression of /^[0-9]*$/. The ^ tells it match start of a line and $ tells it match end of the line. So it will match: start of line, 0 to any in range of 0 to 9, and finally end of line.
def is_int(test_me)
test_me =~ /^[0-9]*$/
end
And you don't need the return statements, Ruby implicitly returns the last statement.
Edit:
It probably would be easier and look better to use the to_i instance method of String class.
def is_int(test_me)
test_me.to_i.to_s == test_me
end
Edit: (did some tests)
Comparing the performance between the two methods shows that .to_i.to_s == way is 5% faster. So it is up to personal preference to which ever looks better and if you want to handle leading zeroes.
To do what you really want should be even simpler
def is_int(test_me)
test_me.to_i.to_s == test_me
end
This?
def single_match(str, regex)
str.match(regex).to_s == str
end
To answer your original question, for the sake of people finding this page in a search, "scan" will return an array of matches, so if you want to find out how many times some regexp matches, e.g. how many runs of digits there are, you can do:
mystring.scan(/\d+/).size

Resources