Given a mathematical equation that has *,+,-,/, reverse it - ruby

I'm working on a low level Ruby challenge and it seems very straight forward however I can't figure out how to reverse the string and keep the integer the same.
The question wants me to reverse as follows:
solve("a+b-c/d*30") = "30*d/c-b+a"
My answer:
def solve(eq)
eq.reverse
end
Output:
Expected: "y/b*100", instead got: "y/b*001"
Thank you in advance.

If variable names may contain more than one letter you may wish to split the string on the four operators.
def solve(eq)
eq.split(/([+*\/-])/).reverse.join
end
solve("az+b-c/d*30")
#=> "30*d/c-b+az"
See String#split, particularly the third paragraph.

My solution:
def solve(eq)
eq.split(/(\d*)/).reverse.join
end
source = "a+b-c/d*30"
wanted = "30*d/c-b+a"
p wanted
p solve(source)
p wanted == solve(source)
I take the source string and split it up with /(\d*)/)
I get:
["a", "", "+", "", "b", "", "-", "", "c", "", "/", "", "d", "", "*", "30"]
See the 30 as one string in the end. \d* catches all numbers as one expression. The () means, that the splitt-parameters should be part of the result.
This array is reversed and joined again.

Related

How to input m values in n times(n lines) by Ruby?

I have some Ruby exercises and i have problem with inputs.
I want to know how to input M values in 1 lines with space between 2 values,
and do N lines like that.
Have anyone can help me? Please!
If you want to get an user input then you could consider using gets, this way:
# a stores what the user introduces, in this case "a b c"
a = gets.chomp
# => "a b c"
If for instance you want to allow the user to enter many values, separated by a whitespace or any other, then you can use split, like in:
# in this case split without arguments takes the input as string, and divides it within every whitespace ang gives you them in an array.
a = gets.chomp.split
=> ["a", "b", "c"]
Then you already have the way to get the user input for M values in 1 lines with space between 2 values. If you'd like to repeat this, then you could use times, specifying the amount of times you want this be done, i.e:
# This will store what the user introduces, splitted as before, and each array will be inside a "main" array.
# If for instance the input is 1 2 3 the first time, a b c the second time, then you get
a = 2.times.map do
gets.chomp.split
end
p a
# => [["1", "2", "3"], ["a", "b", "c"]]

How do I efficiently tell which of a sequence of regular expressions match a given string?

I'm working on a Ruby project in which the user can configure a list of regular expressions and associate each expression with some action to be performed. This list of expressions is then tested against some given input string, and the handler(s) of the matching expression(s) will be executed. The code basically looks like this:
#mapping = {
/^[A-Za-z]+$/ => Proc.new { puts "Got word" },
/^\d+$/ => Proc.new { puts "Got number" },
/^.$/ => Proc.new { puts "Got single character" }
}
def run_handlers(s)
#mapping.each { |regexp, handler| handler.call if regexp =~ s.to_s }
end
# Prints 'Got word'
run_handlers("StackOverflow")
# Prints 'Got number' as well as 'Got single character'
run_handlers(4)
Alas, this performs rather poorly when there are many (a couple thousand) handlers. Performing a linear search over all handlers seems a bit wasteful, but since the expressions are user-configurable I cannot exploit some specific traits of the expressions easily. I wonder whether there's a more efficient way to do this.
One idea I was toying with is to merge multiple regular expressions (i.e. multiple state machines) into one big state machine which is able to run more efficiently. I'm aware of the union method to merge regular expressions, but since I need to execute a different set of handlers depending on which expression match, that does not seem to be of any use.
I was thinking that maybe the expressions can internally be managed like a tree structure (much like a Trie such that the program does not actually need to try all the regular expressions but can quickly drop entire sets of expressions.
Maybe there is some existing code for this kind of problem already? I suppose various web frameworks deal with the same kind of issue when getting a request and having to decide which route to select.
You can use parenthesis to capture parts of a Regular Expression match. Have a look at this:
['1','a','Z'].each {|x| p /((\d)|([a-z])|([A-Z]))/.match(x).to_a }
Where I am passing three strings to the regex /((\d)|([a-z])|([A-Z]))/ via its match method. I'm then converting the output to an array so that it is easy to compare.
It contains three regex elements:
(\d) # any number
([a-z]) # lowercase letters
([A-Z]) # uppercase letters
Note that each is enclosed within parenthesis.
They are all then enclosed within an OR block: (a|b|c)
It outputs:
["1", "1", "1", nil, nil]
["a", "a", nil, "a", nil]
["Z", "Z", nil, nil, "Z"]
The first match is the match for the complete regex, and the second is for the outer OR block.
So it is the third to fifth matches that are of interest. They match the inner elements.
The main issue I think you may have with this, is if the inner elements themselves have OR blocks and capture blocks. For example, have a look at this variant of my code:
['1','a','Z'].each {|x| p /((\d)|(([a-g])|([h-z]))|([A-Z]))/.match(x).to_a }
In this I've split the second element into two (([a-g])|([h-z])).
As you can see from the output, that throws out the results:
["1", "1", "1", nil, nil, nil, nil]
["a", "a", nil, "a", "a", nil, nil]
["Z", "Z", nil, nil, nil, nil, "Z"]
So if you have no control on the structure of each regex element, I don't think you'll be able to predict the structure of the output.

How to write a Ruby program using only "a-z", "A-Z", ".", "\n" and " "

I am trying to resolve some Ruby challenge and I have big problem with some low level (I suppose?) digits characters conversion.
Just imagine, that you need to write program, that prints on your screen sentence ex.:
"Jon Doe was born in 2017!"
using only following characters [a-zA-Z.\n ] (small & big letters, dot, space and new line)
In fact, I have no idea how should I even start to look for the answer.
Is it some kind of using pack / unpack method? or is there any trival solution that I can't find?
There is a reason why "write program" was bolded. Question is, what is the simplest definition of program in Ruby?
Writing a program that prints a string using only letters, dot, space and newline might seem impossible at first, but it is actually not that hard.
Lowercase and uppercase letters allow you to invoke Kernel methods (like print and puts) as well as keywords like nil, false and true. A dot allows you to invoke methods with an explicit receiver. Space allows you to pass an argument to a method. Newline separates commands.
Let's try to get an "a":
false #=> false
false.inspect #=> "false"
false.inspect.chars #=> ["f", "a", "l", "s", "e"]
false.inspect.chars.rotate #=> ["a", "l", "s", "e", "f"]
false.inspect.chars.rotate.first #=> "a"
Now lets print "abc":
print false.inspect.chars.rotate.first
print false.inspect.chars.rotate.first.succ
print false.inspect.chars.rotate.first.succ.succ
puts
Output:
abc
You get the idea.
And yes, it's also possible to print spaces, punctuation and numbers using a similar approach. But I leave that to you. Take a look at the available methods and be creative.
Additional points for figuring out how to print a string without using space, just [a-zA-Z.\n].

How to use String#scan using regular expressions by digit length and keep odd remainder as element

I want to separate a string in units of three, but also have the remainder as a separate element.
def separate(string)
string.scan(/\w{3}/)
end
So, if I pass in "BENISME" I want it to return [BEN][ISM] and then also [E]
I know there is an easy answer to this, but for the life of me I just cant figure it out! What would I add to this to return the remaining E?
def separate(string)
string.scan(/\w{1,3}/) # => ["BEN", "ISM", "E"]
end
Basically, {n,m} in regexen means "any amount of times between n and m."
This will always take the maximum amount of characters it can (it will always give you three characters if possible), because regex is "greedy," and always tries to take as much as possible. Unless you use the non-greedy modifier, like so:
string.scan(/\w{1,3}?/) # => ["B", "E", "N", "I", "S", "M", "E"]
Why use regular expressions at all? You could do each_slice on the character array:
def separate(string)
string.chars.each_slice(3).map(&:join).to_a
end

Trying to split a string (ruby)

I'm new to Ruby. I'm trying to make some simple calculator program. So, basically what it's supposed to do is you input something like
4+2
and it outputs 6. Simple, right? So I thought. I'm trying to split a string at all the operation characters, so I made this quick regex thinking it would work. It didn't.
class Calculator
def add(a,b)
return a+b
end
def sub(a,b)
return a-b
end
def div(a,b)
return a/b
end
def mul(a,b)
return a*b
end
end
operation = gets.split("[\/\+\-\*]")
print(operation)
sleep()
the sleep() is there to pause the console so I can take a look at my outputs. But right now, it's outputting ["4+2\n"]?? I don't know what I'm doing wrong. I need some help. (it should output ["4","+","2"]). Thanks in advance.
You don't need to escape every character inside of your character class. Consider the following:
operation = gets.gsub(/[^\d\/*+-]/, '').split(/([\/*+-])/)
or
operation = gets.split(/([\/*+-])/).map(&:strip)
For a regular expression you want to use / instead of ":
operation = gets.split(/[\/\+\-\*]/) # ["4", "2\n"]
There's an extra newline remove that with strip:
operation = gets.strip.split(/[\/\+\-\*]/) # ["4", "2"]
But we lost the operator. Looking at the docs for split:
If pattern contains groups, the respective matches will be returned
in the array as well.
Adding () in our regex creates a group. So then we have:
operation = gets.strip.split(/([\/\+\-\*])/) # ["4", "+", "2"]
You can try the following code.
operation = gets.chomp.gsub(/[\/\+\-\*]/, ';\0;').split(";")
print(operation)
Execution result:
4+2/3*9-0
["4", "+", "2", "/", "3", "*", "9", "-", "0"]

Resources