I am trying to implement the quick sort algorithm using ruby. See what I did:
class Array
def quick_sort #line 14
less=[];greater=[]
if self.length<=1
self[0]
else
i=1
while i<self.length
if self[i]<=self[0]
less << self[i]
else
greater << self[i]
end
i=i+1
end
end
less.quick_sort + self[0] + greater.quick_sort #line 29
end
end
[1,3,2,5,4].quick_sort #line 32
This generated the error:
bubble_sort.rb:29:in `quick_sort': stack level too deep (SystemStackError)
from bubble_sort.rb:29:in `quick_sort'
from bubble_sort.rb:32
Why is this happening?
I think the problem in your example was you needed an explicit return.
if self.length<=1
self[0]
should have been
return [] if self == []
and
less.quick_sort + self[0] + greater.quick_sort #line 29
should have been
less.quick_sort + [self[0]] + greater.quick_sort #line 29
Here is a working example
class Array
def quick_sort
return [] if self == []
pivotal = self.shift;
less, greater = [], []
self.each do |x|
if x <= pivotal
less << x
else
greater << x
end
end
return less.quick_sort + [pivotal] + greater.quick_sort
end
end
[1,3,2,5,4].quick_sort # => [1, 2, 3, 4, 5]
less.quick_sort + self[0] + greater.quick_sort
This line is outside of the if statement, so it gets executed whether self.length<=1 is true or not. Consequently the method recurses infinitely, which causes the stack to overflow.
It should also be pointed out that self[0] does not return an array (unless self is an array of arrays), so it does not make sense to use Array#+ on it. Nor does it make sense as a return value for your quick_sort method.
In that part you should not handle the "=" case. Only < and > should be handled. Therefore your algorithm never stops and causes an infinite recursion.
if self[i]<=self[0]
less << self[i]
else
greater << self[i]
end
Related
I'm working on project Euler #35. I am getting the wrong number returned and I can't find where I have done wrong!
def is_prime?(num)
(2..Math.sqrt(num)).each { |i| return false if num % i == 0}
true
end
def is_circular?(num)
len = num.to_s.length
return true if len == 1
(len - 1).times do
new_n = cycle(num)
break unless is_prime?(new_n)
end
end
def cycle(num)
ary = num.to_s.split("")
return ary.rotate!.join.to_i
end
def how_many
circulars = []
(2..1000000).each do |num|
if is_prime?(num) && is_circular?(num)
circulars << num
end
end
p circulars.count
end
how_many #=> 14426
The returned number is '14426'. I am only returning the circular primes, supposedly the correct answer is '55'
I have edited your code with few fixes in Ruby way. Your mistake was including corect set of [a, b, c] three times to count, instead of counting them as a one circular prime number. Your answer was correct, while 55 is the number of unique sets.
require 'prime'
class Euler35
def is_circular?(num)
circulars_for(num).all?{ |el| ::Prime.instance.prime?(el) }
end
def circulars_for(a)
a.to_s.split("").length.times.map{|el| a.to_s.split("").rotate(el).join.to_i }
end
def how_many
circulars = []
::Prime.each(1_000_000) do |num|
continue if circulars.include?(num)
if is_circular?(num)
circulars << circulars_for(num)
end
end
circulars.count
end
end
puts Euler35.new.how_many # => 55
I rewrote the map method:
def my_map(input, &block)
mod_input = []
x = -1
while x < input.length - 1
x = x + 1
if block == nil
return input
break
end
mod_input.push(block.call(input[x]))
end
return mod_input
end
I need to call this code as I would call map or reverse. Does anyone know the syntax for that?
Are you asking how you put a method into a module? That's trivial:
module Enumerable
def my_map(&block)
mod_input = []
x = -1
while x < length - 1
x = x + 1
if block == nil
return self
break
end
mod_input.push(block.call(self[x]))
end
return mod_input
end
end
[1, 2, 3, 4, 5].my_map(&2.method(:*))
# => [2, 4, 6, 8, 10]
Or are you asking how to make your method an Enumerable method? That's more involved: your method currently uses many methods that are not part of the Enumerable API. So, even if you make it a member of the Enumerable module, it won't be an Enumerable method. Enumerable methods can only use each or other Enumerable methods. You use length and [] both of which are not part of the Enumerable interface, for example, Set doesn't respond to [].
This would be a possible implementation, using the Enumerable#inject method:
module Enumerable
def my_map
return enum_for(__method__) unless block_given?
inject([]) {|res, el| res << yield(el) }
end
end
[1, 2, 3, 4, 5].my_map(&2.method(:*))
# => [2, 4, 6, 8, 10]
A less elegant implementation using each
module Enumerable
def my_map
return enum_for(__method__) unless block_given?
[].tap {|res| each {|el| res << yield(el) }}
end
end
[1, 2, 3, 4, 5].my_map(&2.method(:*))
# => [2, 4, 6, 8, 10]
Note that apart from being simply wrong, your code is very un-idiomatic. There is also dead code in there.
the break is dead code: the method returns in the line just before it, therefore the break will never be executed. You can just get rid of it.
def my_map(&block)
mod_input = []
x = -1
while x < length - 1
x = x + 1
if block == nil
return self
end
mod_input.push(block.call(self[x]))
end
return mod_input
end
Now that we have gotten rid of the break, we can convert the conditional into a guard-style statement modifier conditional.
def my_map(&block)
mod_input = []
x = -1
while x < length - 1
x = x + 1
return self if block == nil
mod_input.push(block.call(self[x]))
end
return mod_input
end
It also doesn't make sense that it is in the middle of the loop. It should be at the beginning of the method.
def my_map(&block)
return self if block == nil
mod_input = []
x = -1
while x < length - 1
x = x + 1
mod_input.push(block.call(self[x]))
end
return mod_input
end
Instead of comparing an object against nil, you should just ask it whether it is nil?: block.nil?
def my_map(&block)
return self if block.nil?
mod_input = []
x = -1
while x < length - 1
x = x + 1
mod_input.push(block.call(self[x]))
end
return mod_input
end
Ruby is an expression-oriented language, the value of the last expression that is evaluated in a method body is the return value of that method body, there is no need for an explicit return.
def my_map(&block)
return self if block.nil?
mod_input = []
x = -1
while x < length - 1
x = x + 1
mod_input.push(block.call(self[x]))
end
mod_input
end
x = x + 1 is more idiomatically written x += 1.
def my_map(&block)
return self if block.nil?
mod_input = []
x = -1
while x < length - 1
x += 1
mod_input.push(block.call(self[x]))
end
mod_input
end
Instead of Array#push with a single argument it is more idiomatic to use Array#<<.
def my_map(&block)
return self if block.nil?
mod_input = []
x = -1
while x < length - 1
x += 1
mod_input << block.call(self[x])
end
mod_input
end
Instead of Proc#call, you can use the .() syntactic sugar.
def my_map(&block)
return self if block.nil?
mod_input = []
x = -1
while x < length - 1
x += 1
mod_input << block.(self[x])
end
mod_input
end
If you don't want to store, pass on or otherwise manipulate the block as an object, there is no need to capture it as a Proc. Just use block_given? and yield instead.
def my_map
return self unless block_given?
mod_input = []
x = -1
while x < length - 1
x += 1
mod_input << yield(self[x])
end
mod_input
end
This one is opinionated. You could move incrementing the counter into the condition.
def my_map
return self unless block_given?
mod_input = []
x = -1
while (x += 1) < length
mod_input << yield(self[x])
end
mod_input
end
And then use the statement modifier form.
def my_map
return self unless block_given?
mod_input = []
x = -1
mod_input << yield(self[x]) while (x += 1) < length
mod_input
end
Also, your variable names could use some improvements. For example, what does mod_input even mean? All I can see is that it is what you output, so why does it even have "input" in its name? And what is x?
def my_map
return self unless block_given?
result = []
index = -1
result << yield(self[index]) while (index += 1) < length
result
end
This whole sequence of initializing a variable, then mutating the object assigned to that variable and lastly returning the object can be simplified by using the K Combinator, which is available in Ruby as Object#tap.
def my_map
return self unless block_given?
[].tap {|result|
index = -1
result << yield(self[index]) while (index += 1) < length
}
end
The entire while loop is useless. It's just re-implementing Array#each, which is a) unnecessary because Array#each already exists, and b) means that your my_map method will only work with Arrays but not other Enumerables (for example Set or Enumerator). So, let's just use each instead.
def my_map
return self unless block_given?
[].tap {|result|
each {|element|
result << yield(element)
}
}
end
Now it starts to look like Ruby code! What you had before was more like BASIC written in Ruby syntax.
This pattern of first creating a result object, then modifying that result object based on each element of a collection and in the end returning the result is very common, and it even has a fancy mathematical name: Catamorphism, although in the programming world, we usually call it fold or reduce. In Ruby, it is called Enumerable#inject.
def my_map
return self unless block_given?
inject([]) {|result, element|
result << yield(element)
}
end
That return self is strange. map is supposed to return a new object! You don't return a new object, you return the same object. Let's fix that.
def my_map
return dup unless block_given?
inject([]) {|result, element|
result << yield(element)
}
end
And actually, map is also supposed to return an Array, but you return whatever it is that you called map on.
def my_map
return to_a unless block_given?
inject([]) {|result, element|
result << yield(element)
}
end
But really, if you look at the documentation of Enumerable#map, you will find that it returns an Enumerator and not an Array when called without a block.
def my_map
return enum_for(:my_map) unless block_given?
inject([]) {|result, element|
result << yield(element)
}
end
And lastly, we can get rid of the hardcoded method name using the Kernel#__method__ method.
def my_map
return enum_for(__method__) unless block_given?
inject([]) {|result, element|
result << yield(element)
}
end
Now, that looks a lot better!
class Array
def my_map(&block)
# your code, replacing `input` with `self`
end
end
The code itself is not really idiomatic Ruby - while is very rarely used for iteration over collections, and if you don't need to pass a block somewhere else, it is generally cleaner to use block_given? instead of block.nil? (let alone block == nil), and yield input[x] instead of block.call(input[x]).
I am triggering endless recursion when trying to make a method that pulls up tiles when they are a zero. I have been testing by entering the following in irb:
class Board
attr_accessor :size, :board
def initialize(size = gets.chomp.to_i)
#size = size
#board = (1..#size).map { |x| ["L"] * #size }
end
def print_board
#board.map { |row| puts row.join }
end
end
class Mine
attr_accessor :proxi, :row, :col
def initialize(proxi)
#proxi = proxi
#row = 0
#col = 0
#random = Random.new
check_position
end
def check_position
if #proxi.board[#row - 1][#col - 1] != "L"
#row = #random.rand(1..#proxi.board.length)
#col = #random.rand(1..#proxi.board[0].length)
check_position
else
map_position
end
end
def map_position
#proxi.board[#row - 1][#col - 1] = "*"
end
end
b = Board.new(20)
m = (1..b.size * 2).map { |i| i = Mine.new(b) }
class Detector
attr_accessor :board, :proxi, :row, :col, :value
def initialize(board, proxi)
#board = board
#proxi = proxi
#row = 0
#col = 0
#value = 0
end
def mine?
if #proxi.board[#row - 1][#col - 1] == "*"
true
else
false
end
end
def detect
(#row - 1..#row + 1).each do |r|
(#col - 1..#col + 1).each do |c|
unless (r - 1 < 0 || r - 1 > #proxi.size - 1) || (c - 1 < 0 || c - 1 > #proxi.size - 1)
#value += 1 if #proxi.board[r - 1][c - 1] == "*"
end
end
end
end
def map_position
#proxi.board[#row - 1][#col - 1] = #value
#board.board[#row - 1][#col - 1] = #value
end
def recursion
if #proxi.board[#row - 1][#col - 1] == 0
(#row - 1..#row + 1).each do |r|
(#col - 1..#col + 1).each do |c|
unless (r - 1 < 0 || r - 1 > #proxi.size - 1) || (c - 1 < 0 || c - 1 > #proxi.size - 1)
#row, #col = r, c
detect
map_position
recursion
end
end
end
end
end
def reset
#row, #col, #value = 0, 0, 0
end
end
d = Detector.new(b, b)
b.print_board
If the output has plenty of free space in the upper right corner proceed to pasting the next part, else repaste.
d.row = 1
d.col = 1
d.mine?
d.detect
d.map_position
d.recursion
b.print_board
It will error out with a stack level too deep error at the recursion method. I know this is because it is having issues ending the recursive pattern. I thought my two unless statements deterring it from searching off the board would limit it to the area in the board. Plus the mines would force it to be limited in zeros it can expose. Maybe it is somehow writing spaces off the board or overwriting things on the board?
You don’t need a recursion here. Simply check each position for mines around:
Please always use 0-based arrays to eliminate lots of #blah - 1.
In detect you need to return immediately if there is a mine and set the #value otherwise:
def detect
return if #proxi.board[#row][#col] == '*'
value = 0 # no need to be global anymore
(#row - 1..#row + 1).each do |r|
(#col - 1..#col + 1).each do |c|
unless r < 0 || r >= #proxi.size || c < 0 || c >= #proxi.size
value += 1 if #proxi.board[r][c] == "*"
end
end
end
#proxi.board[#row][#col] = value
end
Now you don’t need map_position method at all. Simply check all the cells:
def check
(0..#proxi.size - 1).each do |r|
(0..#proxi.size - 1).each do |c|
#row, #col = r, c
detect
end
end
end
Hope it helps.
Exceeding the stack size is usually an indication that your recursion does not have the correct terminating condition. In your case, what mechanism is in place to prevent recursion from being called multiple times with the same #row #col pair? Note that of the 9 pairs that (#row - 1..#row + 1) (#col - 1..#col + 1) produce, one of those pairs is #row #col itself. The function will call itself infinitely many times!
A simple way to solve this would be to have something like a revealed array that keeps track of visited cells. Then recursion would mark each cell it visits as visited and return immediately if it is called on an already visited cell.
Additionally, your use of instance variables is extremely fragile here. Recursion relies on the fact that each function call has its own scope, but every call of recursion shares the same instance variables - which you're using to pass arguments! You should be using method arguments to keep the scopes distinct.
I'm asked to write the ruby program that generate the output based the given command,
The full description
I'm really new in ruby (maybe few hours that I have started ruby)
When I run the program I get into infinite loop, I don't understand why.
Thank you.
What I have done so far:
# MyVector Class
class MyVector
def initialize (a)
if !(a.instance_of? Array)
raise "ARGUMENT OF INITIALIZER MUST BE AN ARRAY"
else
#array = a
end
end
def array
#array
end
def to_s
#array.to_s
end
def length
#array.length
end
def [](i)
#array[i]
end
def each2(a)
raise Error, "INTEGER IS NOT LIKE VECTOR" if a.kind_of?(Integer)
Vector.Raise Error if length != a.length
return to_enum(:each2, a) unless block_given?
length.times do |i|
yield #array[i], a[i]
end
self
end
def * (a)
Vector.Raise Error if length != a.length
p = 0
each2(a) {|a1, a2|p += a1 * a2}
p
end
end
# MyMatrix Class
class MyMatrix
def initialize a
#array=Array.new(a.length)
i=0
while(i<a.length)
#array[i]=MyVector.new(a[i])
end
end
def to_s
#array.to_s
end
def transpose
size=vectors[0].length
arr= Array.new(size)
i=0
while i<size
a=Array.new(vector.length)
j=0
while j<a.length
a[j]=vectors[j].arr[i]
j+=1
end
arr[i]=a
i+=1
end
arr[i]=a
i+=1
end
def *m
if !(m instance_of? MyMatrix)
raise Error
a=Array.new(#array.length)
i=0
while (i<#array.length)
a[i]=#array[i]*m
i=i+1
end
end
end
end
Input:
Test code
v = MyVector.new([1,2,3])
puts "v = " + v.to_s
v1 = MyVector.new([2,3,4])
puts "v1 = " + v1.to_s
puts "v * v1 = " + (v * v1).to_s
m = MyMatrix.new([[1,2], [1, 2], [1, 2]])
puts "m = " + m.to_s + "\n"
puts "v * m = " + (v * m).to_s
m1 = MyMatrix.new([[1, 2, 3], [2, 3, 4]])
puts "m1 = " + m1.to_s + "\n"
puts "m * m1 = " + (m * m1).to_s
puts "m1 * m = " + (m1 * m).to_s
Desired Output:
v = 1 2 3
v1 = 2 3 4
v * v1 = 20
m =
1 2
1 2
1 2
v * m = 6 12
m1 =
1 2 3
2 3 4
m * m1 =
5 8 11
5 8 11
5 8 11
m1 * m =
6 12
9 18
To answer the infinite loop issue, it looks like you forgot to add a i += 1 in the #initialize method of Matrix class.
However, you will encounter more errors further in the code since, for example, you're checking length of the Matrix object which is undefined, and iterating over the Matrix object in each2 defined inside of the Vector class which needs the object to be an Enumerable (Array/Hash etc). These will throw an error as the Matrix class is not an Enumerator. These are some good resources to help you learn how the powerful Enumerator module works.
Once you get familiar with the syntax and structure, be sure to use the Pry tool. It will be your best friend for debugging Ruby code.
I'm trying to learn Ruby, and am going through some of the Project Euler problems. I solved problem number two as such:
def fib(n)
return n if n < 2
vals = [0, 1]
n.times do
vals.push(vals[-1]+vals[-2])
end
return vals.last
end
i = 1
s = 0
while((v = fib(i)) < 4_000_000)
s+=v if v%2==0
i+=1
end
puts s
While that works, it seems not very ruby-ish—I couldn't come up with any good purely Ruby answer like I could with the first one ( puts (0..999).inject{ |sum, n| n%3==0||n%5==0 ? sum : sum+n }).
For a nice solution, why don't you create a Fibonacci number generator, like Prime or the Triangular example I gave here.
From this, you can use the nice Enumerable methods to handle the problem. You might want to wonder if there is any pattern to the even Fibonacci numbers too.
Edit your question to post your solution...
Note: there are more efficient ways than enumerating them, but they require more math, won't be as clear as this and would only shine if the 4 million was much higher.
As demas' has posted a solution, here's a cleaned up version:
class Fibo
class << self
include Enumerable
def each
return to_enum unless block_given?
a = 0; b = 1
loop do
a, b = b, a + b
yield a
end
end
end
end
puts Fibo.take_while { |i| i < 4000000 }.
select(&:even?).
inject(:+)
My version based on Marc-André Lafortune's answer:
class Some
#a = 1
#b = 2
class << self
include Enumerable
def each
1.upto(Float::INFINITY) do |i|
#a, #b = #b, #a + #b
yield #b
end
end
end
end
puts Some.take_while { |i| i < 4000000 }.select { |n| n%2 ==0 }
.inject(0) { |sum, item| sum + item } + 2
def fib
first, second, sum = 1,2,0
while second < 4000000
sum += second if second.even?
first, second = second, first + second
end
puts sum
end
You don't need return vals.last. You can just do vals.last, because Ruby will return the last expression (I think that's the correct term) by default.
fibs = [0,1]
begin
fibs.push(fibs[-1]+fibs[-2])
end while not fibs[-1]+fibs[-2]>4000000
puts fibs.inject{ |sum, n| n%2==0 ? sum+n : sum }
Here's what I got. I really don't see a need to wrap this in a class. You could in a larger program surely, but in a single small script I find that to just create additional instructions for the interpreter. You could select even, instead of rejecting odd but its pretty much the same thing.
fib = Enumerator.new do |y|
a = b = 1
loop do
y << a
a, b = b, a + b
end
end
puts fib.take_while{|i| i < 4000000}
.reject{|x| x.odd?}
.inject(:+)
That's my approach. I know it can be less lines of code, but maybe you can take something from it.
class Fib
def first
#p0 = 0
#p1 = 1
1
end
def next
r =
if #p1 == 1
2
else
#p0 + #p1
end
#p0 = #p1
#p1 = r
r
end
end
c = Fib.new
f = c.first
r = 0
while (f=c.next) < 4_000_000
r += f if f%2==0
end
puts r
I am new to Ruby, but here is the answer I came up with.
x=1
y=2
array = [1,2]
dar = []
begin
z = x + y
if z % 2 == 0
a = z
dar << a
end
x = y
y = z
array << z
end while z < 4000000
dar.inject {:+}
puts "#{dar.sum}"
def fib_nums(num)
array = [1, 2]
sum = 0
until array[-2] > num
array.push(array[-1] + array[-2])
end
array.each{|x| sum += x if x.even?}
sum
end