Roman Number Calculator - arrays

I have to make an assignment wherein I have to implement the Roman Numerals along with the rules that are followed while doing calculations on them, contained in this link
http://www.periodni.com/roman_numerals_converter.html
I don't want the code, just help. I have gone with two approaches till now:
Using constants, I have declared the roman numerals as constants, and then after getting the input, I am left with the choice to decode the string input, which I later dropped.
Using hash. I have declared a hash with the numerals, then after getting the input, I am converting the string using to_sym method into there corresponding value. After this, I have taken an array containing the decimals of the roman numerals, and I intend to compare those with the input.
I am stuck at this part. I don't know how to compare here. Also, I don't want to sort the input array, because then calculations would go wrong.
Can anyone help me with how to proceed? Not the code, just steps.
This is what I have done so far:
class Conversion
hash ={ :I => 1, :V => 5, :X => 10, :L => 50, :C => 100, :D => 500, :M => 1000}
result = 0
value = []
hash_values = hash.values
puts "enter input string"
input = gets.chomp.upcase.split(//)
input.each do |i|
value <<  hash[i.to_sym]
end
for i in value do
if value[i] > value[i+1]
result = result + value[i]
else
result = result + (value[i+1] - value[i])
end
end
puts result
end
If u run the code, you'll see that while I try to compare in the last loop it is taking the index for calculations. Same happened when I tried doing the same using two hashes. I can't use any gem or external libraries cause that is the requirement.

The idea is to create a tree where every node have two childrens: the left one is what to substract and the right one is what to add.
Once you get a string, you find the most valued letter and make it the first node like this:
XLIX
L
/ \
X IX
Then you run this function recursively on the children nodes until the node is trivial (like XX or III).
The final step is to recursively calculate the result.

Related

How remove comma in array of string to convert in array of float

I have an array of strings:
my_array = ["$8,579.06", "$166.37", "$0.226463", "$346.31", "$275.27"]
I want to get a new array:
my_array = [8,579.06, 166.37, 0.226463, 346.31, 275.27]
I want to remove the $ and convert the values into floats, so I did this:
my_array.map! { |v| v.delete_prefix("$").to_f}
But that returned:
my_array = [8.0, 166.37, 0.226463, 346.31, 275.27]
I think it's because of the comma but my array is huge.
How do I remove all the commas of each value without removing the ones separating the different indexes in my array?
I think this goes according to the docs:
... Extraneous characters past the end of a valid number are ignored...
You're getting just "8.0" because all the remaining characters after the 8 are ignored, as the comma can not be interpreted as a floating-point number. Which would be the same that doing "8".to_f and gives 8.0.
To avoid that you can try removing the commas per element inside the array:
["$8,579.06", "$166.37", "$0.226463", "$346.31", "$275.27"].map { |e| e.delete_prefix("$").delete(',').to_f }
# [8579.06, 166.37, 0.226463, 346.31, 275.27]
I'd do this:
ary = ["$8,579.06", "$166.37", "$0.226463", "$346.31", "$275.27"]
ary.map { |i| i.delete('$,').to_f }
# => [8579.06, 166.37, 0.226463, 346.31, 275.27]
delete is the magic part. It strips any characters named in the parameter from the string.
Commas in the viewable/screen display of numbers to denote thousands are a human artifice, to make it easier for us to gauge the magnitude of the number. Computers don't need them.
Assign the returned value from map to a variable or chain to it.
And, as a heads-up, be aware that different regions around the world use two different ways to denote thousands and the decimal point. Some use 1,000.00 and some are 1.000,00. Assuming that a string representation of currency has commas for thousands and a period for the fractional part is the source of a bug, quite a major bug if you're dealing with money, especially if you're doing financial calculations for loans. In your example you could write code to determine the values are U.S. based because of $, but without that you'd have a harder time telling. So if this is something you anticipate having to do I'd strongly recommend researching the problems and solutions.

How to get the maximum value from hash

I want to get the maximum value from the hash but i keep getting the first one
Crypto_name = ["Bitcoin", "Ethereum", "Project-x", "Fake"]
Crypto_price = ["$5500.6", "$538.9", "$0.25", "$46000.09"]
$crypto = Crypto_name.zip(Crypto_price).to_h
def largest_hash_key
puts $crypto.max_by{|a,b| b.to_i}
end
largest_hash_key
As per the format of each string within crypto_price, you'd need to remove any non-digit character, with those 4 elements, $ is the one you don't need.
max can help you:
$crypto.max { |value| value.last.delete('$').to_f }
# "$46000.09"
By removing the $ you get a "convertible" to float number, which you can then compare.
I blindly assume that "$" is the only one character that's not needed among them. But it won't be always this way.
Perhaps
$crypto.max_by{|a,b| b.tr('^0-9''.','').to_f}
I think this works with any symbols and in any order.

How to substring of a string in matlab array

I have a matlab cell array of size 20x1 elements. And all the elements are string like 'a12345.567'.
I want to substitute part of the string (start to 9th index) of all the cells.
so that the element in matrix will be like 'a12345.3'.
How can I do that?
You can use cellfun:
M = { 'a12345.567'; 'b12345.567' }; %// you have 20 entries like these
MM = cellfun( #(x) [x(1:7),'3'], M, 'uni', 0 )
Resulting with
ans =
a12345.3
b12345.3
For a more advanced string replacement functionality in Matlab, you might want to explore strrep, and regexprep.
Another method that you can use is regexprep. Use regular expressions and find the positions of those numbers that appear after the . character, and replace them with whatever you wish. In this case:
M = { 'a12345.567'; 'b12345.567' }; %// you have 20 entries like these - Taken from Shai
MM = regexprep(M, '\d+$', '3');
MM =
'a12345.3'
'b12345.3'
Regular expressions is a framework that finds substrings within a larger string that match a particular pattern. In our case, \d is the regular expression for a single digit (0-9). The + character means that we want to find at least one or more digits chained together. Finally the $ character means that this pattern should appear at the end of the string. In other words, we want to find a pattern in each string such that there is a number that appears at the end of the string. regexprep will find these patterns if they exist, and replace them with whatever string you want. In this case, we chose 3 as per your example.

Script to calculate the product of numbers in all possible combinations

I have a db of numbers (percentages) which I want to calculate the product for each of the possible combinations of all the numbers and their difference from a 100%.
So for example, for the following numbers:
0.3, 0.4, 0.6, 0.7
I want to calculate the following:
(1-0.3)*(1-0.4)*(1-0.6)*(1-0.7)
0.3*0.4*0.6*0.7
0.3*(1-0.4)*(1-0.6)*(1-0.7)
(1-0.3)*(1-0.4)*(1-0.6)*0.7
(1-0.3)*0.4*(1-0.6)*(1-0.7)
(1-0.3)*(1-0.4)*0.6*(1-0.7)
0.3*(1-0.4)*(1-0.6)*0.7
0.3*(1-0.4)*0.6*(1-0.7)
(1-0.3)*(1-0.4)*0.6*0.7
(1-0.3)*0.4*(1-0.6)*0.7
(1-0.3)*0.4*0.6*(1-0.7)
0.3*0.4*(1-0.6)*(1-0.7)
(1-0.3)*0.4*0.6*0.7
0.3*(1-0.4)*0.6*0.7
0.3*0.4*(1-0.6)*0.7
0.3*0.4*0.6*(1-0.7)
I want to be able to build this for any n numbers (here I gave an example for 4 numbers, but there can be hundreds and thousands of these). How is it called? Is there a command for them? Is there a known script somewhere?
In the end I will need to sum them all up. And use them individually as well.
I do not think there is a pre-defined command for this in any language, but most languages will allow you to write a recursive function for this. For example, in Haskell you could use:
calculate [] = [[]]
calculate (x:xs) = let rec = calculate xs
pos = map (x:) rec
neg = map ((1 - x):) rec
in pos ++ neg
You can try this out here and run your example with the line:
main = print (calculate [0.3, 0.4, 0.6, 0.7])
Note that this calculate function takes a list of percentages as input and returns a list of lists, each of which represents a line in your desired result. This result can then be used to calculate your intermediate and final result.
The function works as follows. If your input is an empty list, return a list with an empty list. If the input has elements, separate the first element (x) from the remainder of the list (xs) and calculate the result on the remainder of the list. The result of this is a list with lists of percentages which is stored in rec.
To calculate the result value, prepend x to each list in rec (stored in pos) and prepend 1-x to each list in rec (stored in neg). As the result we return one list which is the concatenation of pos and neg.

Algorithm - check if any string in an array of strings is a prefix of any other string in the same array

I want to check if any string in an array of strings is a prefix of any other string in the same array. I'm thinking radix sort, then single pass through the array.
Anyone have a better idea?
I think, radix sort can be modified to retrieve prefices on the fly. All we have to do is to sort lines by their first letter, storing their copies with no first letter in each cell. Then if the cell contains empty line, this line corresponds to a prefix. And if the cell contains only one entry, then of course there are no possible lines-prefices in it.
Here, this might be cleaner, than my english:
lines = [
"qwerty",
"qwe",
"asddsa",
"zxcvb",
"zxcvbn",
"zxcvbnm"
]
line_lines = [(line, line) for line in lines]
def find_sub(line_lines):
cells = [ [] for i in range(26)]
for (ine, line) in line_lines:
if ine == "":
print line
else:
index = ord(ine[0]) - ord('a')
cells[index] += [( ine[1:], line )]
for cell in cells:
if len(cell) > 1:
find_sub( cell )
find_sub(line_lines)
If you sort them, you only need to check each string if it is a prefix of the next.
To achieve a time complexity close to O(N2): compute hash values for each string.
Come up with a good hash function that looks something like:
A mapping from [a-z]->[1,26]
A modulo operation(use a large prime) to prevent overflow of integer
So something like "ab" gets computed as "12"=1*27+ 2=29
A point to note:
Be careful what base you compute the hash value on.For example if you take a base less than 27 you can have two strings giving the same hash value, and we don't want that.
Steps:
Compute hash value for each string
Compare hash values of current string with other strings:I'll let you figure out how you would do that comparison.Once two strings match, you are still not sure if it is really a prefix(due to the modulo operation that we did) so do a extra check to see if they are prefixes.
Report answer

Resources