This is my PigLatin code and it works well but I need make it interactive with ARGV, it should be:
$ ruby pig_latin.rb pig banana trash apple elephant
=> igpay ananabay ashtray appleway elephantway
def pig_latin(input)
first_char = input[0,1]
vowels = "aeiouAEIOU"
if vowels.include?(first_char)
word = input[1..-1] + first_char + "way"
else
word = input[1..-1] + first_char + "ay"
end
end
Add this at the end of the program:
if __FILE__ == $0 # if file is being run as script from command line
puts(ARGV.map { |string| pig_latin(string) }.join(" "))
end
ARGV is an array of strings. You can use map to apply the pig_latin changes, and then print them on the same line, joined by " "
The benefit of using if __FILE__ == $0 is that it doesn't require your program to use ARGV. E.g. you could still use it with require.
Here's a cleaned up version that's more Ruby-like:
def pig_latin(input)
case (first_char = input[0,1])
when /aeiou/i
# Uses a simple regular expression to detect vowels
input[1..-1] + first_char + "way"
else
input[1..-1] + first_char + "ay"
end
end
# Transform the input arguments into their Pig Latin equivalents
# and combine into a single string by joining with spaces.
piglatined = ARGV.map do |arg|
pig_latin(arg)
end.join(' ')
puts piglatined
Related
I'm trying to reverse a string using the code:
puts("Hi now it's going to be done!")
string = gets.chomp.to_s
i = string.length
while i >= 0
puts(string[i])
i = i - 1
end
It prints the string in backward order, but each word is on a single line. How can I keep all of them on a single line?
puts adds a newline to the end of the output if one isn't already present.
print does not. So do this:
while i >=0
print string[i]
i=i-1
end
puts
The final puts is because you want any further printing to be on a new line.
Try this:
"Hi now it's going to be done!".chars.inject([]) { |s, c| s.unshift(c) }.join
Or This is a little easier to follow:
string = 'Hi now it's going to be done!'
string.reverse!
I'm new to programming and I'm working with Ruby as my starter language. The below code works, but if someone inputs more than one word, the pigatize method only works on the first word and adds the additional ay or way to the last word. How do i get it to apply to each word a user inputs?
# If the first letter is a vowel, add "way" to the end
# If the first letter is a consonant, move it to the end and add "ay"
class PigLatin
VOWELS = %w(a e i o u)
def self.pigatize(text)
if PigLatin.vowel(text[0])
pigalatin = text + 'way'
else
piglatin = text[1..-1] + text[0] + 'ay'
end
end
def self.vowel(first_letter)
VOWELS.include?(first_letter)
end
end
puts 'Please enter a word and I will translate it into Pig Latin. Ippyyay!.'
text = gets.chomp
puts "Pigatized: #{PigLatin.pigatize(text)}"
Chiefly, you need to split the input string into words with String#split, using an expression like:
text.split(' ')
That produces an array of words, which you can loop over with an .each block and run the algorithm on each word, then reassemble them with += and a space at the end + ' '
Incorporating these things into your existing code looks like the following (with comments):
class PigLatin
VOWELS = %w(a e i o u)
def self.pigatize(text)
# Declare the output string
piglatin = ''
# Split the input text into words
# and loop with .each, and 'word' as the iterator
# variable
text.split(' ').each do |word|
if PigLatin.vowel(word[0])
# This was misspelled...
# Add onto the output string with +=
# and finish with an extra space
piglatin += word + 'way' + ' '
else
# Same changes down here...
piglatin += word[1..-1] + word[0] + 'ay' + ' '
end
end
# Adds a .chomp here to get rid of a trailing space
piglatin.chomp
end
def self.vowel(first_letter)
VOWELS.include?(first_letter)
end
end
puts 'Please enter a word and I will translate it into Pig Latin. Ippyyay!.'
text = gets.chomp
puts "Pigatized: #{PigLatin.pigatize(text)}"
There are other ways to handle this than adding to the string with +=. You could, for example add words onto an array with an expression like:
# piglatin declared as an array []
# .push() adds words to the array
piglatin.push(word + 'way')
Then when it's time to output it, use Array#join to connect them back with spaces:
# Reassemble the array of pigatized words into a
# string, joining the array elements by spaces
piglatin.join(' ')
There are alternatives to .each..do for the loop. You could use a for loop like
for word in text.split(' ')
# stuff...
end
...but using the .each do is a bit more idiomatic and more representative of what you'll usually find in Ruby code, though the for loop is more like you'd find in most other languages besides Ruby.
Code:
class Comparer
words = "asdf-asdf-e-e-a-dsf-bvc-onetwothreefourfive-bob-john"
foundWords = []
File.foreach('words.txt') do |line|
substr = "#{line}"
if words.include? substr
puts "Found " + substr
foundWords << substr
end
end
wordList = foundWords.join("\n").to_s
puts "Words found: " + wordList
end
words.txt:
one
blah-blah-blah
123-5342-123123
onetwo
onetwothree
onetwothreefour
I'd like the code to return all instances of include?, however when the code is run, wordList only contains the last line of words.txt ("onetwothreefour".) Why don't the other lines in words.txt get factored?
Because all other lines you expect to be found, they have "hidden" newline character at the end. You can see for yourself.
File.foreach('words.txt') do |line|
puts line.inspect
# or
p line
end
You can get rid of newlines by using chomp! method on line.
File.foreach('words.txt') do |line|
line.chomp!
# proceed with your logic
end
I've written a method for adding ay to the ends of words if they begin with a vowel. If the words begin with a consonant it will move the consonants to the end of the word and then add ay.
My issue with this is that my result is returned in an array for example:
translate("happy animals")
Instead of getting "appyhay animalsay"
I get ["appyhay", "animalsay"]
I tried joining them at the end, but when I run the test it says that the join method could not be found?
Is this just a mess or am I getting close?
Many thanks for any insight :)
def translate(word)
multiplewords = word.split(" ")
multiplewords.map! do |x|
separated = x.split("")
if !'aeiou'.include?(separated[0])
while !'aeiou'.include?(separated[0])
letter = separated.shift
separated << letter
separated
end
final = separated.join("") + "ay"
else
final = separated.join("") + "ay"
end
end
end
translate("happy animals") => ['appyhay', 'animlasay']
Answer needed: "appyhay animalsay"
You should join it at the last part. I tried to simplify it a bit as well.
#!/usr/bin/env ruby
def translate(word)
word.split(" ").map do |x|
separated = x.split("")
if !'aeiou'.include?(separated[0])
while !'aeiou'.include?(separated[0])
letter = separated.shift
separated << letter
end
end
separated.join("") + "ay"
end.join(' ')
end
puts translate("happy animals")
Output:
appyhay animalsay
I am trying to solve the "pig latin problem" in the Test-First Ruby lessons.
In this program I am basically trying to translate a string with the following rules:
If a word begins with a vowel sound, add an "ay" sound to the end of the word.
If a word begins with a consonant sound, move it to the end of the word, and then add an "ay" sound to the end of the word.
For this I wrote the following code which worked fine:
def translate(word)
words=word.split(" ")
words.each do |x|
if ["a","e","i","o","u"].include?x[0,1]
x << ("ay")
else
x << ("#{x[0,1]}ay")
x[0,1]=""
end
end
words.join(" ")
end
However, the problem also states that when translating words with 2, or 3 consonants in the beginning, it should move them all at the end of the word, and then add "ay".
For that I ended an until loop into the else statement:
def translate(word)
words=word.split(" ")
words.each do |x|
if ["a","e","i","o","u"].include?x[0,1]
x << ("ay")
else
until ["a","e","i","o","u"].include?x[0,1]
x << ("#{x[0,1]}")
x[0,1]=""
end
x << ("#{x[0,1]}ay")
end
end
words.join(" ")
end
This is giving me this result:
translate("the bridge over the river kwai")
=> "etheay idgebriay overay etheay iverriay aikwaay"
So, it is running the until loop one extra time and adding the first vowel in the word to the end as well. However, it is not removing this vowel from the first position.
What am I doing wrong?
It's this line: x << ("#{x[0,1]}ay").
You've already shaved off the consonants from the beginning of the word so that it starts with a vowel, and then you're adding that vowel ("#{x[0,1]}") to the end along with the ay.
So, replace x << ("#{x[0,1]}ay") with just x << "ay" and it should work.
(NOTE: technically this is not an answer)
Your original code is not very idiomatic. You're running while loops and mutating strings in-place. You don't see that in good ruby code. May I offer you an improved version?
def vowel?(str)
["a","e","i","o","u"].include?(str)
end
def translate_word(word)
first_vowel_idx = word.chars.find_index{|c| vowel?(c)}
leading_consonants = word[0..first_vowel_idx-1]
rest_of_the_word = word[first_vowel_idx..-1]
rest_of_the_word + leading_consonants + 'ay'
end
def translate(sentence)
words = sentence.split(" ")
words.map{|w| translate_word(w) }.join(" ")
end
translate("the bridge over the river kwai") # => "ethay idgebray overoveray ethay iverray aikway"