New to StackOverflow here. I'm working on the first Euler problem and have run into an issue where I can get the statement to iterate through the array. It seems like it has something to do with the way I have the while loop setup but I can't figure it out.
Here's my code:
#euler problem 1
numbers = [3,5]
sum = 0
i=1
total=0
numbers.each do |number|
while i * number < 10
adder = i * number
total += adder
i += 1
puts total
end
end
puts total
The output is 3
9
18
18
Any idea why it isn't processing the 5 in the array numbers?
Your problem is that i is declared outside the block so when number is five, i is already four and the while loop's condition fails immediately because 20 < 10 is false. Try it like this:
numbers = [3,5]
sum = 0
total=0
numbers.each do |number|
i = 1
while i * number < 10
#...
end
end
puts total
If you put a little puts in your code you'll see what's going on:
i = 1
numbers.each do |number|
puts "#{number}\ti = #{i}"
while i * number < 10
puts "\ti = #{i}"
adder = i * number
total += adder
i += 1
end
end
That will give you this output:
3 i = 1
i = 1
i = 2
i = 3
5 i = 4
and you'll see the problem with i.
Related
I'm just learning Ruby :) and Im trying to create a simple prime-number program where all the primes of a number are printed.
I'm getting errors where the prime and nonprime numbers are mixed up
(ie: input of 9 will get you all nonprimes).
I'm sorry for such a beginner question - I'm struggling alot and need some help :)
puts "Enter a number please "
num = gets.chomp.to_i
i = 2
number = 2
while i < num
if number % i == 0
prime = false
end
i += 1
end
if prime == true
puts "#{number} is prime"
else
puts "#{number} is not prime"
end
number += 1
end
while i < num
if number % i == 0
prime = false
end
i += 1
end
# ...
It looks like that first end is meant to be an else.
It's easier to catch these things when you simplify your code, e.g. this method reduces to this (although there are other issues with it):
i = 2
number = 2
while i < num
(number % i).zero? ? prime = false : i += 1
puts "#{number} is #{'not ' unless prime}prime"
number += 1
end
End error is because of else
while i < num
if number % i == 0
prime = false
else
i += 1
end
if you have a short If - neater is writing it like:
if-condition ? 1 : 0
and in your case while is.. not the nicest choice - you should use range
(1...3).map{|x| puts(x) }
{} - allows multiline(with do end end)
this prints [1,2]
(1..3).map{|x| x*2 }
would be [2,4,9]
This should be enough hints of how to play around with your code without ruining the process.
I'm learning ruby and practicing with codewars, and I've come to a challenge that I feel I mainly understand (rudimentarily) but I'm unable to figure out how to continue looping over the method until I reach the result I'm looking for.
The challenge is asking to reduce a number, by multiplying its digits, until the multiplication results in a single digit. In the end it wants you to return the number of times you had to multiply the number until you arrived at a single digit. Example -> given -> 39; 3 * 9 = 27, 2 * 7 = 14, 1 * 4 = 4; answer -> 3
Here's my code :
def persistence(n)
if n < 10
return 0
end
arr = n.to_s.split("")
sum = 1
count = 0
arr.each do |num|
sum *= num.to_i
if num == arr[-1]
count += 1
end
end
if sum < 10
return count
else
persistence(sum)
end
end
Thanks for your help!
Your function is looking great with recursion but you are reseting the count variable to 0 each time the loop runs, I think if you use an auxiliar method it should run ok:
this is in base of your code with minor improvements:
def persistence(n)
return 0 if n < 10
count = 0
multiply_values(n, count)
end
def multiply_values(n, count)
arr = n.to_s.chars
sum = 1
arr.each do |num|
sum *= num.to_i
if num == arr[-1]
count += 1
end
end
if sum < 10
return count
else
multiply_values(sum, count)
end
end
a shorter solution could be to do:
def persistence(n)
return 0 if n < 10
multiply_values(n, 1)
end
def multiply_values(n, count)
sum = n.to_s.chars.map(&:to_i).reduce(&:*)
return count if sum < 10
multiply_values(sum, count + 1)
end
and without recursion:
def persistence(n)
return 0 if n < 10
count = 0
while n > 10
n = n.to_s.chars.map(&:to_i).reduce(&:*)
count += 1
end
count
end
Let's look at a nicer way to do this once:
num = 1234
product = num.to_s.split("").map(&:to_i).reduce(&:*)
Breaking it down:
num.to_s.split("")
As you know, this gets us ["1", "2", "3", "4"]. We can easily get back to [1, 2, 3, 4] by mapping the #to_i method to each string in that array.
num.to_s.split("").map(&:to_i)
We then need to multiply them together. #reduce is a handy method. We can pass it a block:
num.to_s.split("").map(&:to_i).reduce { |a, b| a * b }
Or take a shortcut:
num.to_s.split("").map(&:to_i).reduce(&:*)
As for looping, you could employ recursion, and create product_of_digits as a new method for Integer.
class Integer
def product_of_digits
if self < 10
self
else
self.to_s.split("").map(&:to_i).reduce(&:*).product_of_digits
end
end
end
We can now simply call this method on any integer.
1344.product_of_digits # => 6
I'm trying to code the 'Sieve of Eratosthenes' in Ruby and I'm having difficulty in the second 'while' loop. I want to test to see if integers[j] % integers[0] == 0, but the compiler keeps giving me a nil:Nil Class error at this line. I can't figure out the problem.
n = gets.chomp.to_i
puts
while n < 2
puts 'Please enter an integer >= 2.'
puts
n = gets.chomp.to_i
puts
end
integers = []
i = 0
while i <= n - 3
integers[i] = i + 2
i += 1
end
primes = []
j = 1
while integers != []
primes.push integers[0]
while j <= integers.length
if integers[j] % integers[0] == 0
integers.delete(integers[j])
end
j += 1
end
integers.shift
j = 1
end
puts integers
puts
puts primes
Thanks in advance for any help!
It's an off-by-one error. You're testing for j <= integers.length. So, for example, if you array has five items, the last iteration will be integers[5]. But the last index in a five-item array is 4 (because it starts at 0). You want j < integers.length.
I need some feedback to figure out why I cant puts or print anything from my methods on the screen. This is a simple script I wrote to solve the problem of finding the 1001st prime number. Thanks
def primes
# iterates through numbers until it has the 1001th prime number and returns it.
# I chose to create the num_primes variable instead of counting the number of
# elements in in_prime_array every iteration
# based upon a guess that it would be faster to check.
is_prime_array = []
num_primes = 0
i = 2
loop do
is_prime_array << i && num_primes += 1 if is_prime?(i) == true
i += 1
break if num_primes == 1001
end
is_prime_array[1001]
end
def is_prime? (num)
# Checks to see if the individual number given is a prime number or not.
i = 2
loop do
if i == num
return true
elsif num % i == 0
return false
else
i += 1
end
end
end
Thanks for any help!
EDIT
I took your advice and tried this pice of code:
def is_prime? (num)
# Checks to see if the individual number given is a prime number or not.
i = 2
loop do
if i == num
return true
elsif num % i == 0
return false
else
i += 1
end
end
end
i = 0
count = 0
loop do
count += 1 if is_prime?(x)
puts "#{i}" if count == 1001
break
end
It still returns nothing. Hummm
i = 0
count = 0
loop do
if is_prime(i)
count += 1
end
if count == 10001
puts "#{i}"
break
end
end
Simple method :)
It's an off-by-one error. If you have 1001 elements in an array, the last element will be at index 1000.
Where you have
is_prime_array[1001]
Change it to
is_prime_array[1000]
And you can do this:
puts primes
=> 7927
You could also have
is_prime_array.last
instead of a specific index number.
What are you trying to "puts"? The first thing I notice is that there is no call to primes in the file, so nothing will happen if you try to run this code by itself. Maybe that's why you don't see anything printed.
Here's an example of how to print a few variables inside your loop:
loop do
...
puts "At iteration #{i}, we have prime=#{is_prime?(i)}"
If you don't know, enclosing a statement with #{<statement goes here>} inside a string is the same as appending the return value of <statement goes here> to the string at that position. This is the same as "Str " + blah + " rest of str" in a language like Java.
I'm brand new to programming and Ruby is my first language. One exercise I'm working on is to create a multiplication table that does the following:
1x1 = 1
1x2 = 2
(etc)
2x1 = 2
2x2 = 4
I figured I'd do this by creating a nested while loop:
a = 1
b = 1
while a <= 5
while b <= 5
puts "#{a} * #{b} = #{a * b}"
b += 1
end
a += 1
end
When I run the script it prints the first set of times table (1x1 - 1x5) then stops. It doesn't iterate the parent loop. What am I doing wrong?
You state that you're a novice so a while loop is ok for now. But when you improve both your programming and Ruby skills you should be able to write more idiomatic code. Something along those lines:
puts [*1..5].product([*1..5]).map { |x, y| "#{x} * #{y} = #{x*y}" }.join("\n")
You never reset your b to 1. Look at the second while loop:
while b <= 5:
...
b += 1
At the end of this loop, b = 6, and the loop exits. Then a += 1 is executed, and our outer loop begins. On all the next inner loop iterations, b = 6 however, and therefore isn't executed. Thus you need:
...
end
a += 1
b = 1
The "bookkeeping error" explained in the accepted answer is an easy one to make. It is one of the reasons the each method is generally preferred to a while loop:
(1..5).each do |a|
(1..5).each do |b|
puts "#{a} * #{b} = #{a * b}"
end
end
No bookkeeping!
class MultiplicationTable
i=1
j=5
while i <= j
(1..12).each do |x|
puts "#{i} * #{x} = #{i*x}"
end
i+=1
end
end