String include weird behavior - ruby

I was doing a code golf (use the minimum number of characters) and I had the following working Python solution. I was trying to shorten my code by re-writing it to Ruby but my Ruby code would always print false.
The code had to read two strings, to ignore the case and to tell whether it was possible to obtain one string by rotating the other string. The output had to be either true or false. Do you have any idea what I did wrong in Ruby?
Python 3 (64 characters) - Works
a=input().lower()
b=input().lower()
print(str(a in 2*b).lower())
Ruby (47 characters) - Always prints "false"
a=gets.upcase
b=gets.upcase
p (b*2).include? a
With the examples I can think of, the Ruby code works correctly, but for some reason, it didn't work on the code golf site (codingame.com, the problem was proposed by user "10100111001").

In Ruby gets includes the \n at the end. You'd have to .chomp it away before doing anything.
a=gets.chomp.upcase
b=gets.chomp.upcase
p (b*2).include? a
By the way, this is not the right way to "tell whether it was possible to obtain one string by rotating the other string", it only partially solves the problem, hope you know that.

Related

Count the number of sentences in a paragraph using Ruby

I have gotten to the point where I can split and count sentences with simple end of sentence punctuation like ! ? .
However, I need it to work for complex sentences such as:
"Learning Ruby is a great endeavor!!!! Well, it can be difficult at times..."
Here you can see the punctuation repeats itself.
What I have so far, that works with simple sentences:
def count_sentences
sentence_array = self.split(/[.?!]/)
return sentence_array.count
end
Thank you!
It's pretty easy to adapt your code to be a little more forgiving:
def count_sentences
self.split(/[.?!]+/).count
end
There's no need for the intermediate variable or return.
Note that empty strings will also be caught up in this, so you may want to filter those out:
test = "This is junk! There's a space at the end! "
That would return 3 with your code. Here's a fix for that:
def count_sentences
self.split(/[.?!]+/).grep(/\S/).count
end
That will select only those strings that have at least one non-space character.
class String
def count_sentences
scan(/[.!?]+(?=\s|\z)/).size
end
end
str = "Learning Ruby is great!!!! The course cost $2.43... How much??!"
str.count_sentences
#=> 3
(?=\s|\z)/) is a positive lookahead, requiring the match to be immediately followed by a whitespace character or the end of the string.
String#count might be easiest.
"Who will treat me to a beer? I bet, alexnewby will!".count('.!?')
Compared to tadman's solution, no intermediate array needs to be constructed. However it yields incorrect results if, for instance, a run of periods or exclamation mark is found in the string:
"Now thinking .... Ah, that's it! This is what we have to do!!!".count('.!?')
=> 8
The question therefore is: Do you need absolute, exact results, or just approximate ones (which might be sufficient, if this is used for statistical analysis of, say, large printed texts)? If you need exact results, you need to define, what is a sentence, and what is not. Think about the following text - how many sentences are in it?
Louise jumped out of the ground floor window.
"Stop! Don't run away!", cried Andy. "I did not
want to eat your chocolate; you have to believe
me!" - and, after thinking for a moment, he
added: "If you come back, I'll buy you a new
one! Large one! With hazelnuts!".
BTW, even tadman's solution is not exact. It would give a count of five for the following single sentence:
The IP address of Mr. Sloopsteen's dishwasher is 192.168.101.108!

Ruby: "undefined method" error; how to use gsub more effectively?

So I'm trying to find a way to Donald Duck-ify statements inputed by users (judge me later).
This is my code so far:
puts "Wanna get Donald Duck-ified?"
print "Type some text here:"
user_input = gets.chomp
if user_input.gsub!(/s/,"th").gsub!(/ce/,"th").gsub!(/ci/,"th").gsub!(/cy/,"th")
puts "Boop - there go your s's and soft c's!"
else
puts "Dang, you didn't have any s's or soft c's!"
end
puts "#{user_input}"
Upon testing it with some input of my own ("square cycle caesar circle", specifically), I'm getting "undefined method `gsub!' for nil:NilClass" as an error.
How is gsub! undefined? If the code runs with user_input.gsub!(/s/,"th") on it own, without any other methods behind it, it works fine. Once a second method is added, the else code runs and only replacements for "s" are made. All four and I get the error above.
Does there happen to be another way of substituting multiple patterns (as named by the Ruby docs) with a single replacement? I've spent the last hours researching the problem and I still can't totally tell what the issue is.
New to Ruby. Encouraged and motivated.
Many thanks in advance.
Don't use #gsub! chained. (Actually, don't use #gsub! at all for most code.)
[gsub!] Performs the substitutions of String#gsub in place, returning str, or nil if no substitutions were performed.
Switch the code to #gsub which doesn't cause side-effects (yay!) and always returns a string (yay!) - simply compare the result with the original (unmodified) string.
Also, one could use the gsub form that accepts a hash (since Ruby 1.9.something). This has a subtle difference that replaced values will not be themselves replaced, although it doesn't matter here.
user_input.gsub(/s|ce|ci|cy/, { "s"=>"th", "ce"=>"th", "ci"=>"th", "cy"=>"th" })
# or since all are replaced with "th" (which I just noticed =^_^=) ..
user_input.gsub(/s|ce|ci|cy/, "th")
(I still recommend against gsub! because I find side effects upon strings disconcerting. However, it would work reliably when used with the non-chained forms above.)
Ruby's gsub! returns nil if it performs no substitutions. This means you can't reliably chain it like you do. If you want to verify that any of the gsubs have made any change, you can chain non-destructive gsubs (without the bang; return a new string instead of modifying the current one) instead:
input = gets.chomp
replaced = input.gsub(/s/,"th").gsub(/ce/,"th").gsub(/ci/,"th").gsub(/cy/,"th")
if input == replaced
...

Unicode - the right thing to do

I'm working on something which processes UTF-8 encoding, and I found myself asking the question:
What should I do when I encounter a byte which never occur inside a
UTF-8 encoded string?
i.e. 0x1111111X
For example, I'm writing a small snippet of code which looks at the current place in the stream of bytes, and tells you how many bytes are used to represent the code point at that place in the stream.
0x0XXXXXXX just 1
0x10XXXXXX oops, we are in a continuation byte,
search back upstream to find the leading byte
0x11XXXXXX count the
number of leading 1s, that's the answer
0x1111111X err, this is not
possible in UTF-8!!! what to do!?!?
I'm thinking of returning an error value, but wondering if I should, as a side effect, replace it with some more predictable error glyph (I mean the code point representing said glyph). And later when I do something more complicated, like jumping through the string and find that the leading byte does not have the correct number of continuation bytes after it... I'm thinking I should "fix" that up too.
Is it standard practice to leave wrongly encoded strings broken, or to change them and make them be wrong but at least play nice?
The most common way is to just throw a meaningful error if the input is not correct and stop.
There are a lot of good reasons to do so:
speed: if you try to fix errors this often cause your
function to be slower even on correct inputs
simplicity: your code can become really complicated if you try to fix any error
maintainability and correctness: it's just easier to ensure the function works correctly
when you stop whenever the input does not match the specification you are working with. Since you have only to check input according to specification.
purpose: any time you get to such a point like here you have to think about:
what is the purpose of my function? Why I came up with the idea to write it?
Also: a function fixcode which fixes the uft8 could be used also at an other place, so it makes total sense to separate fixing (purpose, simplicity, maintainability and correctness argument again).
Even if you expect an error, I would prefer to separate the encode and fixcode since
your can reuse fixcode in outer contexts.
If you are really thinking about fixing the utf8 code while encoding I would use a pattern like this:
try {
q = encode(s);
} catch(encodingerror) {
log(encodingerror);
t = fixcode(s);
q = encode(t);
}

Calculating Event Horizons in Ruby

this is my first post here. I started using Ruby just 2 days ago and think it is an amazing language, however I have been getting stuck. My problem is I am wanting to calculate the event horizon of a black hole given an input defined in the code as "m" This will then be put into a calculation and the size then printed out to the screen. I did need it to be in binary and thats where I am having the issue.
Here is my code so far.
#Event Horizon Calculation Program
G = 6.67*10**-11
m = 20
C = 200000
R = G*m/(C**2)
puts "Here is the result in Binary."
R.to_i(2)
puts R
Now I do realise that the number are not accurate, that dosen't matter at the moment. I just need the function to work.
Thankyou,
Ross.
Your post is not even in a format of asking a question, but guessing from what you wrote, it seems that you are asking how to change your code so that it accepts an input to m and outputs the result. My answer is based on this assumption.
In order to take an input, use the 'gets' method. So, you may want to replace your 'm = 20' line with:
m = gets.to_f
'gets' accepts an input as a string, so you need to convert it to a numeric. to_f changes a string into a float. You can use to_i instead if you want an integer.
You have a line 'R.to_i(2)', and it seems like you want to output this, but you have two problems here. First of all, whatever that creates, it is only creating something in that position, and does not change the value of R, so, in effect, it actually does nothing. Second, ruby can accept numerals in source code written in different bases such decimal, binary, hex, etc., but it only has one internal representation, and you cannot output a numeral in binary. For your purpose, you need to convert it to a string that corresponds to a binary expression. For that, use the 'to_s' method. In fact, the 'to_i' method does not take an argument. Delete your line 'R.to_i(s)', and replace the line 'puts R' with:
puts R.to_s(2)

Error in rounding off values using .round in Ruby

The following piece of code works perfectly in script/console but returns the following error when i compile the same in a ruby script.:
:in `round': wrong number of arguments (1 for 0) (ArgumentError)
tf={"ph"=>{0=>1.33333333333333, 1=>1.5}, "fee"=>{0=>1.66666666666667}, "test"=>{0=>1.16666666666667, 1=>1.25}, "what"=>{0=>2.0, 1=>2.0}, "for"=>{0=>1.5}, "is"=>{0=>1.83333333333333, 1=>1.75}}
tf.each{|k,v| v.each{|k1,v1| tf[k][k1]=(v1.round(5))}}
Any Ideas ? Cheers !
Float#round seems to work differently in Ruby 1.8 and Ruby 1.9: in 1.8 it complains about the given argument, in 1.9 returns back float properly rounded to the given number of decimals.
But, as the article linked in the other answer wisely says:
you should consider the reason you’re
performing the rounding (or
equivalent) operation. If it’s for
presentation reasons only a better way
might be to use a format string
instead, and leave the original data
intact.
From what it looks like, you are not supposed to pass an argument to the round method. You have passed 5 to it.
If you are trying to round it to 5 decimal places, there is no builtin method for that (that I'm aware of). This is a page that explains how to do so: http://solutions.hans-eric.com/rounding-off-floating-point-numbers-in-ruby

Resources