Convert string into array and do operations - ruby-on-rails

I have a string like: "1234567334535674326774324423". I need to create a method to do the following:
Make an array consisting of digits in the string like [1, 2, 3, ..., 2, 3]
Sum all the odd positions of the array
Sum all the even positions of the array
Multiply the odd sum by 3
Sum step 4 and step 3.
Get the minimum number to sum to step 5 to get the sum that is a multiple of 5.
I don't know how to solve this with rails. If anyone can help me, I would be glad.
I have this:
barcode_array = #invoice.barcode.each_char.map {|c| c.to_i}
impares = [barcode_array[0]] + (1...barcode_array.size).step(2).collect { |i| barcode_array[i] }
pares = (2...barcode_array.size).step(2).collect { |i| barcode_array[i] }
suma_impares = impares.inject(:+)
mult_impares = suma_impares * 3
suma total = mult_impares + pares

I solved it. Here is the code if anyone needs it:
barcode_array = #invoice.barcode.each_char.map {|c| c.to_i}
impares = [barcode_array[0]] + (1...barcode_array.size).step(2).collect { |i| barcode_array[i] }
pares = (2...barcode_array.size).step(2).collect { |i| barcode_array[i] }
suma_impares = impares.inject(:+).to_i
mult_impares = suma_impares * 3
suma_pares = pares.inject(:+).to_i
suma_total = mult_impares + suma_pares
verificador = 10 - (suma_total - (suma_total / 10).to_i * 10)
#invoice.barcode = #invoice.barcode.to_s + verificador.to_s

I'm not sure what you mean in step 6, but here's how I would tackle 1-5:
s = '1234567334535674326774324423'
a = s.chars.map(&:to_i) # convert to an array of integers
odd_sum = 0
even_sum = 0
# sum up odds and evens
a.each_with_index {|n, i| n.even? ? even_sum += n : odd_sum += n}
total = even_sum + odd_sum * 3

Related

How to convert a binary number into integer in lua

i have a array of 1 and 0,
for example 10110
values = {1,0,1,1,0}
max = 0
for value = 6,1,-1 do
max = max + 2*index*value
end
but how could get the index of the array in order to calculate the max
Try this:
values = {1,0,1,1,0}
max = 0
for index = 1,#values,1 do
max = max + 2^(#values-index)*values[index]
end
print(max)

Random sum of elements in an array equals to y - ruby [duplicate]

This question already has answers here:
Finding all possible combinations of numbers to reach a given sum
(32 answers)
Closed 6 years ago.
Need to create an array whose sum should be equal to expected value.
inp = [1,2,3,4,5,6,7,8,9,10]
sum = 200
output:
out = [10,10,9,1,3,3,3,7,.....] whose sum should be 200
or
out = [10,7,3,....] Repeated values can be used
or
out = [2,3,4,9,2,....]
I tried as,
arr = [5,10,15,20,30]
ee = []
max = 200
while (ee.sum < max) do
ee << arr.sample(1).first
end
ee.pop(2)
val = max - ee.sum
pair = arr.uniq.combination(2).detect { |a, b| a + b == val }
ee << pair
ee.flatten
Is there any effective way to do it.
inp = [1,2,3,4,5,6,7,8,9,10]
sum = 20
inp.length.downto(1).flat_map do |i|
inp.combination(i).to_a # take all subarrays of length `i`
end.select do |a|
a.inject(:+) == sum # select only those summing to `sum`
end
One might take a random element of resulting array.
result = inp.length.downto(1).flat_map do |i|
inp.combination(i).to_a # take all subarrays of length `i`
end.select do |a|
a.inject(:+) == sum # select only those summing to `sum`
end
puts result.length
#⇒ 31
puts result.sample
#⇒ [2, 4, 5, 9]
puts result.sample
#⇒ [1, 2, 3, 6, 8]
...
Please note, that this approach is not efficient for long-length inputs. As well, if any original array’s member might be taken many times, combination above should be changed to permutation, but this solution is too ineffective to be used with permutation.
I found an answer of this question in the following link:
Finding all possible combinations of numbers to reach a given sum
def subset_sum(numbers, target, partial=[])
s = partial.inject 0, :+
#check if the partial sum is equals to target
puts "sum(#{partial})=#{target}" if s == target
return if s >= target #if we reach the number why bother to continue
(0..(numbers.length - 1)).each do |i|
n = numbers[i]
remaining = numbers.drop(i+1)
subset_sum(remaining, target, partial + [n])
end
end
subset_sum([1,2,3,4,5,6,7,8,9,10],20)

I am trying to do arithmetic on table values and keep getting an error. here is my code

I am trying to perform arithmetic on table values and keep getting an error. Here is my total code. I am basically trying to generate simplex noise. I have created a multidimensional array (table) and am trying to perform operations on the values but i keep getting an error that says I cannot perform arithmetic on a table value. I don't know If I have to convert it to something or what. Please Help.
totalNoiseMap = {}
function simplex_noise(width, height)
simplexnoise = {}
for i = 1,512 do
simplexnoise[i] = {}
for j = 1, 512 do
simplexnoise[i][j] = 0
end
end
frequency = 5.0 / width
for x = 1, width do
for y = 1, height do
simplexnoise[x][y] = noise(x * frequency,y * frequency)
simplexnoise[x][y] = (simplexnoise[x][y] + 1) / 2
end
end
return simplexnoise
end
function noise(x, y, frequency)
return simplex_noise(x / frequency, y / frequency)
end
function generateOctavedSimplexNoise(width,height,octaves,roughness,scale)
totalnoise = {}
for i = 1,512 do
totalnoise[i] = {}
for j = 1, 512 do
totalnoise[i][j] = 0
end
end
layerFrequency = scale
layerWeight = 1
weightSum = 0
for octave = 1, octaves do
for x = 1, width do
for y = 1, height do
totalnoise[x][y] = (totalnoise[x][y] + noise(x * layerFrequency,y * layerFrequency, 2) * layerWeight)
end
end
--Increase variables with each incrementing octave
layerFrequency = layerFrequency * 2
weightSum = weightSum + layerWeight
layerWeight = layerWeight * roughness
end
return totalnoise
end
totalNoiseMap = generateOctavedSimplexNoise(512, 512, 3, 0.4, 0.005)
totalnoise[x][y] + noise(x * layerFrequency,y * layerFrequency, 2) * layerWeight
Here you get table noise(x * layerFrequency,y * layerFrequency, 2), mult it by scalar layerWeight and than add it to scalar totalnoise[x][y].
I can think of how to multiply table by scalar - it should be something like
for i = 1,512 do
for j = 1,512 do
a[i][j] = t[i][j] * scalar
end
end
But I'm unable to get what you're trying to do by adding. Suppose it should be addition of two tables
for i = 1,512 do
for j = 1,512 do
a[i][j] = b[i][j] + c[i][j]
end
end
But it works only with same-sized tables

ArithGeo(arr) CoderByte Ruby: Why doesn't this solution work for certain test case scenarios

Below I have posted the instructions for this problem along with my solution. A few test case scenarios have failed, but seem to be working for most. Can anybody help out at which point I've gone wrong? Any help is much appreciated!!
Using the Ruby language, have the function ArithGeo(arr) take the array of numbers stored in arr and return the string "Arithmetic" if the sequence follows an arithmetic pattern or return "Geometric" if it follows a geometric pattern.
If the sequence doesn't follow either pattern return -1.
An arithmetic sequence is one where the difference between each of the numbers is consistent
Arithmetic example: [2, 4, 6, 8]
In a geometric sequence, each term after the first is multiplied by some constant or common ratio.
Geometric example: [2, 6, 18, 54]
Negative numbers may be entered as parameters, 0 will not be entered, and no array will contain all the same elements.
Code:
def arithGeo(num)
idx = 0
while idx < num.length
if ((num[idx] - num[idx + 1]) == (num[idx + 1] - num[idx + 2]))
return "Arithmetic"
elsif ((num[idx + 1] / num[idx]) == (num[idx + 2] / num[idx + 1]))
return "Geometric"
else
return "-1"
end
idx += 1
end
end
#Test Cases that Failed
p arithGeo([1, 2, 3, 4, 5, 10, 20])
p arithGeo([1, 2, 3, 4, 5, 6, 7, 88, 2])
p arithGeo([10, 110, 210, 310, 410, 511])
OK, lets do a much more "ruby like" way:
def arith?(arr)
check_arr = []
arr.reverse.inject {|memo, num| check_arr << (memo - num); num}
#loop through from highest to lowest, subtracting each from the next and store in check_arr
check_arr.all? {|num| num == check_arr[-1]}
#check that all results are the same in the arr i.e. [2,2,2,2,2]
end
This returns true if all of the operations return the same result, thus a linear progression.
def geo?(arr)
check_arr = []
arr.reverse.inject {|memo, num| check_arr << (memo / num); num}
#loop through from highest to lowest, dividing each by the next and store in check_arr
check_arr.all? {|x| x == check_arr[-1]}
#check that all products are the same in the arr i.e. [3,3,3,3,3]
end
This returns true if all of the operations return the same result, thus a geometric progression.
Now use those methods in your other method
def arith_geo?(arr)
if arith?(arr)
'Arithmetic'
elsif geo?(arr)
'Geometric'
else
-1
end
end
You did use a while but you do not loop over the data, because you write return you will only ever look at the first three numbers and then immediately return the result. You will have to keep the previous result, and make sure the result stays the same to return either geometric or arithmetic.
This should help you to complete the exercise :)
I was able to do the solution in JavaScript and this is what I came up with:
function algoGeo(arr){
var algo = true;
var geo = true;
//first check algo
for(var k = 1; k < arr.length; k++){
if( (arr[0] + (arr[1] - arr[0]) * k) !== arr[k] && algo ){
algo = false;
}
if( arr[0] * Math.pow(arr[1] / arr[0], k) !== arr[k] && geo){
geo = false;
}
}
return algo ? "Arithmetic" : geo ? "Geometric" : -1;
}
var arr = [5,12,19,26];
console.log(algoGeo(arr));
def ArithGeo(arr)
diff1 = []
diff2 = []
arr.each_index do |x|
if(x + 1 < arr.length)
diff1 << arr[x + 1] - arr[x]
diff2 << arr[x + 1] / arr[x]
end
end
diff1.uniq.size == 1 ? "Arithmetic" : diff2.uniq.size == 1 ? "Geometric" : -1
end
A little late but this is what i came up with when trying to solve this same question.

Ruby/Rails while loop not breaking correctly?

I am working on a client's site, and I'm writing an amortization schedule calculator in in ruby on rails. For longer loan term calculations, it doesn't seem to be breaking when the balance reaches 0
Here is my code:
def calculate_amortization_results
p = params[:price].to_i
i = params[:rate].to_d
l = params[:term].to_i
j = i/(12*100)
n = l * 12
m = p * (j / (1 - (1 + j) ** (-1 * n)))
#loanAmount = p
#rateAmount = i
#monthlyAmount = m
#amort = []
#interestAmount = 0
while p > 0
line = Hash.new
h = p*j
c = m-h
p = p-c
line["interest"] = h
line["principal"] = c
if p <= 0
line["balance"] = 0
else
line["balance"] = p
end
line["payment"] = h+c
#amort.push(line)
#interestAmount += h
end
end
And here is the view:
- #amort.each_with_index do |a, i|
%li
.m
= i+1
.i
= number_to_currency(a["interest"], :unit => "$")
.p
= number_to_currency(a["principal"], :unit => "$")
.pp
= number_to_currency(a["payment"], :unit => "$")
.b
= number_to_currency(a["balance"], :unit => "$")
What I am seeing is, in place of $0.00 in the final payment balance, it shows "-$-inf", iterates one more loop, then displays $0.00, but shows "-$-inf" for interest. It should loop until p gets to 0, then stop and set the balance as 0, but it isn't. Any idea what I've done wrong?
The calculator is here. It seems to work fine for shorter terms, like 5 years, but longer terms cause the above error.
Edit:
Changing the while loop to n.times do
and then changing the balance view to
= number_to_currency(a["balance"], :unit => "$", :negative_format => "$0.00")
Is a workaround, but i'd like to know why the while loop wouldn't work correctly
in Ruby the default for numerical values is Fixnum ... e.g.:
> 15 / 4
=> 3
You will see weird rounding errors if you try to use Fixnum values and divide them.
To make sure that you use Floats, at least one of the numbers in the calculation needs to be a Float
> 15.0 / 4
=> 3.75
> 15 / 4.0
=> 3.75
You do two comparisons against 0 , which should be OK if you make sure that p is a Float.
As the other answer suggests, you should use "decimal" type in your database to represent currency.
Please try if this will work:
def calculate_amortization_results
p = params[:price].to_f # instead of to_i
i = params[:rate].to_f # <-- what is to_d ? use to_f
l = params[:term].to_i
j = i/(12*100.0) # instead of 100
n = l * 12
m = p * (j / (1 - (1 + j) ** (-1 * n))) # division by zero if i==0 ==> j==0
#loanAmount = p
#rateAmount = i
#monthlyAmount = m
#amort = []
#interestAmount = 0.0 # instead of 0
while p > 0
line = Hash.new
h = p*j
c = m-h
p = p-c
line["interest"] = h
line["principal"] = c
if p <= 0
line["balance"] = 0
else
line["balance"] = p
end
line["payment"] = h+c
#amort.push(line)
#interestAmount += h
end
end
If you see "inf" in your output, you are doing a division by zero somewhere.. better check the logic of your calculation, and guard against division by zero.
according to Wikipedia the formula is:
http://en.wikipedia.org/wiki/Amortization_calculator
to improve rounding errors, it's probably better to re-structure the formula like this:
m = (p * j) / (1 - (1 + j) ** (-1 * n) # these are two divisions! x**-1 == 1/x
which is equal to:
m = (p * j) + (p * j) / ((1 + j) ** n) - 1.0)
which is equal to: (use this one)
q = p * j # this is much larger than 1 , so fewer rounding errors when dividing it by something
m = q + q / ((1 + j) ** n) - 1.0) # only one division
I think it has something to do with the floating point operations precision. It has already been discussed here: Ruby number precision with simple arithmetic and it would be better to use decimal format for financial purposes.
The answer could be computing the numbers in the loop, but with precomputed number of iterations and from the scratch.

Resources