Sum of first nth term of series [duplicate] - ruby

This question already has answers here:
Why is division in Ruby returning an integer instead of decimal value?
(7 answers)
Closed 3 years ago.
I am not understanding why my code isn't looping, for any input I give I get the result of "1.00"
I feel like I am being silly and missing something very obvious.
This series is shown in other places most often as 1/3n+1
But if series_sum(1) = "1.00"
then 3+1 = 4 giving you 1/4 to add to your sum for input of 1 which doesn't make sense
def series_sum(n)
sum = 0
if n == 0
return "0.00"
else
for i in 1..n
sum += 1/(1+(3*(i-1)))
end
end
return "%.2f" % sum.to_s
end
for series_sum(1) should be "1.00"
series_sum(2) should be "1.25"
series_sum(3) should be "1.39"
etc
My code gives "1.00" for any input
Why won't this code run the loop and perform the sum?

When you have expression like z = x/y, in ruby it does specify type for output based on operand provided for division. If x & y both are integer, output calculated is also integer and float value is removed.
So to obtain output as float, you need to have one operand at least as float value which can be found using to_f on variable. Here you need to change only,
- sum += 1/(1+(3*(i-1)))
+ sum += 1.0/(1+(3*(i-1)))

Related

Ruby prime number sum

I am trying to take the sum of the n first prime numbers. I found a way of showing the first 100, but I don't know how to get rid of 1 and how to make a sum with the numbers. I was thinking about storing them into an array, but I can not figure it out.
num = 1
last = 100
while (num <= last)
condition = true
x = 2
while (x <= num / 2)
if (num % x == 0)
condition = false
break
end
x = x + 1
end
primes = [] # Here
if condition
puts num.to_s
primes << num.to_s # Here
end
num = num + 1
end
puts primes.inject(:+) # Here
Based on what I understood from what you guys are saying I added these lines (the ones commented # Here). It still does not print the sum of them. What I meant with getting rid of 1 is that I know that 1 is not considered a prime number, and I do not get how to make it without 1. Thank you very much guys for your time and answers, and please understand that I am just starting to study this.
If you want to add a list of numbers together you can use the following:
list_of_prime_numbers.inject(0) {|total,prime| total + prime}
This will take the list of numbers, and add them one by one to an accumulator (total) that was injected into the loop (.inject(0)), add it to the current number (prime) and then return the total which then becomes the value of total in the next iteration.
I'm not quite sure what you mean by:
I don't know how to get rid of 1
but if you mean to not use the first number (which is 1 in a list of primes starting from 0)
then you could do:
list_of_prime_numbers[1...list_of_prime_numbers.length].
inject(0) {|total,prime| total + prime}
Which would only get all the numbers except the first up to but not including the length of the array
and as for getting the number into the array you could push it into the array like so:
list_of_prime_numbers << prime_number
You can make use of Prime Enumerable in ruby
require 'prime'
((1..100).select { |number| Prime.prime?(number) }).inject(:+)
OR
Prime.each(100).inject(:+)
Hope this helps.

How to round float number with while loop in MATLAB?

I have a rather unorthodox homework assignment where I am to write a simple function where a double value is rounded to an integer with using only a while loop.
The main goal is to write something similar to the round function.
I made some progress where I should add or subtract a very small double value and I would eventually hit a number that will become an integer:
while(~isinteger(inumberup))
inumberup=inumberup+realmin('double');
end
However, this results in a never-ending loop. Is there a way to accomplish this task?
I'm not allowed to use round, ceil, floor, for, rem or mod for this question.
Assumption: if statements and the abs function are allowed as the list of forbidden functions does not include this.
Here's one solution. What you can do is keep subtracting the input value by 1 until you get to a point where it becomes less than 1. The number produced after this point is the fractional component of the number (i.e. if our number was 3.4, the fractional component is 0.4). You would then check to see if the fractional component, which we will call f, is less than 0.5. If it is, that means you need to round down and so you would subtract the input number with f. If the number is larger than 0.5 or equal to 0.5, you would add the input number by (1 - f) in order to go up to the next highest number. However, this only handles the case for positive values. For negative values, round in MATLAB rounds towards negative infinity, so what we ought to do is take the absolute value of the input number and do this subtraction to find the fractional part.
Once we do this, we then check to see what the fractional part is equal to, and then depending on the sign of the number, we either add or subtract accordingly. If the fractional part is less than 0.5 and if the number is positive, we need to subtract by f else we need to add by f. If the fractional part is greater than or equal to 0.5, if the number is positive we need to add by (1 - f), else we subtract by (1 - f)
Therefore, assuming that num is the input number of interest, you would do:
function out = round_hack(num)
%// Repeatedly subtract until we get a value that less than 1
%// i.e. the fractional part
%// Also make sure to take the absolute value
f = abs(num);
while f > 1
f = f - 1;
end
%// Case where we need to round down
if f < 0.5
if num > 0
out = num - f;
else
out = num + f;
end
%// Case where we need to round up
else
if num > 0
out = num + (1 - f);
else
out = num - (1 - f);
end
end
Be advised that this will be slow for larger values of num. I've also wrapped this into a function for ease of debugging. Here are a few example runs:
>> round_hack(29.1)
ans =
29
>> round_hack(29.6)
ans =
30
>> round_hack(3.4)
ans =
3
>> round_hack(3.5)
ans =
4
>> round_hack(-0.4)
ans =
0
>> round_hack(-0.6)
ans =
-1
>> round_hack(-29.7)
ans =
-30
You can check that this agrees with MATLAB's round function for the above test cases.
You can do it without loop: you can use num2str to convert the number into a string, then find the position of the . in the string and extract the string fron its beginning up to the position of the .; then you convert it back to a numebr with str2num
To round it you have to check the value of the first char (converted into a number) after the ..
r=rand*100
s=num2str(r)
idx=strfind(num2str(r),'.')
v=str2num(s(idx+1))
if(v <= 5)
rounded_val=str2num(s(1:idx-1))
else
rounded_val=str2num(s(1:idx-1))+1
end
Hope this helps.
Qapla'

Why does .to_s break this code?

I'm working on a Codewars Ruby problem, and don't understand the error I'm seeing. Here are the instructions:
Coding decimal numbers with factorials is a way of writing out numbers
in a base system that depends on factorials, rather than powers of
numbers. In this system, the last digit is always 0 and is in base 0!.
The digit before that is either 0 or 1 and is in base 1!. The digit
before that is either 0, 1, or 2 and is in base 2!. More generally,
the nth-to-last digit in always 0, 1, 2, ..., or n and is in base n!.
Example : decimal number 463 is coded as "341010"
because 463 (base 10) = 3×5! + 4×4! + 1×3! + 0×2! + 1×1! + 0×0!
If we are limited to digits 0...9 the biggest number we can code is
10! - 1.
So we extend 0..9 with letters A to Z. With these 36 digits we can
code up to 36! − 1 = 37199332678990121746799944815083519999999910
(base 10)
We code two functions, the first one will code a decimal number and
return a string with the factorial representation :
"dec2FactString(nb)"
the second one will decode a string with a factorial representation
and produce the decimal representation : "factString2Dec(str)".
Given numbers will be positive.
Note
You can hope tests with Big Integers in Clojure, Python, Ruby, Haskel
but not with Java and others where the number "nb" in
"dec2FactString(nb)" is at most a long.
Ref: http://en.wikipedia.org/wiki/Factorial_number_system
def dec2FactString(nb)
if nb <= 0 then
num = 1
else
num = (nb * dec2FactString(nb - 1))
end
return num
end
Note that this method is only the first half of the problem. This code appears to work inasmuch as it returns the correct factorial, as a Fixnum when using this test:
Test.assert_equals(dec2FactString(4), "24")
Since the instructions ask for a string, I'd normally think that just adding ".to_s" to the num variable would take care of that, but instead I'm seeing a consistent "String can't be coerced into Fixnum (TypeError)" error message. I've tried pushing the output to an array and printing from there, but saw the same error.
I read up on Fixnum a little, and I understand the error in terms of adding a Fixnum to a string won't work, but I don't think I'm doing that in this case - I just want to convert the Fixnum output into a string. Am I missing something?
Observe - this code breaks and produces the error below it:
def dec2FactString(nb)
if nb <= 0 then
num = 1
else
num = (nb * dec2FactString(nb - 1))
end
return num.to_s
end
Example from description
`*': String can't be coerced into Fixnum (TypeError)
from `dec2FactString'
from `dec2FactString'
from `dec2FactString'
from `dec2FactString'
from `block in
'
from `block in describe'
from `measure'
from `describe'
from `
'
You're calling this function recursively. If you calculated the factorial of 1 and left to_s in there, it'd be fine since you're not reusing the variable.
However, if you do place to_s in there, what would you expect the result of num = (nb * dec2FactString(nb - 1)) to be? dec2FactString would be returning a str instead of a Fixnum, and you can't/shouldn't be able to do multiplication between a number and a string.
What you could do is split the responsibilities of stringification and calculation by creating two methods - one that delegates to the recursive function, and one that coerces its result into a string.
def dec2FactString(nb)
return fact(nb).to_s
end
def fact(nb)
if nb <= 0 then
1
else
nb * fact(nb - 1)
end
end
Firstly, Factorial is only defined on non-negative numbers and so your first test is incorrect (if nb <= 0). The recursion should stop when the number is 0 and should return 1 at that point.
Because your recursion returns a string and not a number, you cannot multiply the string by a Fixnum in the next round of recursion. Your recursion can be expanded via the substitution method to the following.
dec2FactString(5)
5 * dec2FactString(4)
5 * 4 * dec2FactString(3)
5 * 4 * 3 * dec2FactString(2)
5 * 4 * 3 * 2 * dec2FactString(1)
5 * 4 * 3 * 2 * 1 * dec2FactString(0)
5 * 4 * 3 * 2 * 1 * "1"
... That is the point where the recursion ends in an error since dec2FactString(0) returns "1"
It would be far better to break it into two functions. One that calculates factorial recursively and one that converts the final answer to a string. Also, you don't need to explicitly return a value in Ruby. The last line of a function is the return value.
I won't give you the complete code as you won't learn anything. As a few hints, do some research on tail call optimisation, recursion and return values in Ruby. This will allow you to craft a better implementation of the recursive function.
Happy coding!

Floating point integers in Ruby

Trying to make a small script to calculate the incrementally increasing value of a base number by 2%.
Having trouble with, I think, the way I'm handling the floating point.
The script should calculate each number up to a preset value, but it just goes on infinitely.
require 'bigdecimal'
def multiplication sum, count
print "Original Sum: #{sum}\n"
until sum == 100 do
float = BigDecimal('1.02')
next_sum = (sum * float.round(3))
print "#{count}: #{next_sum}\n"
count += 1
sum = next_sum
end
end
multiplication 2, 1
Your script is looping until sum is exactly 100, which might not happen if it jumps from a value less to a value greater. Change the loop condition to this:
until sum >= 100 do
Also, "floating point integer" is a contradiction in terms.

Comparing two Integers by their divisibility

For instance:
8 > 10 = true, since 8 is divisible by 2 three times and 10 only once.
How can I compare two integers from any range of numbers? Are the modulo and divide operator capable of doing this task?
Use binary caculate to judge it
def devided_by_two(i)
return i.to_s(2).match(/0*$/).to_s.count('0')
end
To make integer divisibility by 2, just transcode it to binary and judge how many zero from end of banary number. The code I provide can be more simple I think.
Yes, they are capable. A number is even if, when you divide it by two, the remainder is zero.
Hence, you can use a loop to continuously divide by two until you get an odd number, keeping a count of how many times you did it.
The (pseudo-code) function for assigning a "divisibility by two, continuously" value to a number would be something like:
def howManyDivByTwo(x):
count = 0
while x % 2 == 0:
count = count + 1
x = x / 2 # make sure integer division
return count
That shouldn't be too hard to turn into Ruby (or any procedural-type language, really), such as:
def howManyDivByTwo(x)
count = 0
while x % 2 == 0
count = count + 1
x = x / 2
end
return count
end
print howManyDivByTwo(4), "\n"
print howManyDivByTwo(10), "\n"
print howManyDivByTwo(11), "\n"
print howManyDivByTwo(65536), "\n"
This outputs the correct:
2
1
0
16
Astute readers will have noticed there's an edge case in that function, you probably don't want to try passing zero to it. If it was production code, you'd need to catch that and act intelligently since you can divide zero by two until the cows come home, without ever reaching an odd number.
What value you return for zero depends on needs you haven't specified in detail. Theoretically (mathematically), you should return infinity but I'll leave that up to you.
Notice that you will likely mess up much of your code if you redefine such basic method. Knowing that, this is how it's done:
class Integer
def <=> other
me = self
return 0 if me.zero? and other.zero?
return -1 if other.zero?
return 1 if me.zero?
while me.even? and other.even?
me /= 2
other /= 2
end
return 0 if me.odd? and other.odd?
return -1 if me.odd?
return 1 if other.odd? # This condition is redundant, but is here for symmetry.
end
end

Resources