Ruby wrong result durning vectors calculations - ruby

We are trying to implement "Calculating coefficients of interpolating polynomial using Neville's algorithm."
This is our Vector Class:
class Wektor < Array
attr_accessor :coordinatesAmount
def initialize(length)
super(length, 0)
#coordinatesAmount = length
end
def SetVector(w)
for i in (0...coordinatesAmount) do
self[i] = w[i]
end
return self
end
def MultiplyBy(n)
for i in (0...coordinatesAmount) do
self[i] *= n
end
return self
end
def DivideBy(n)
for i in (0...coordinatesAmount) do
self[i] /= n
end
return self
end
def Sub(w)
for i in (0...coordinatesAmount) do
self[i] -= w[i]
end
return self
end
def Add(w)
for i in (0...coordinatesAmount) do
self[i] += w[i]
end
return self
end
def ShiftRight
coordinatesAmount.downto(1) { |i|
self[i-1] = self[i-2]
}
self[0] = 0
return self
end
This is our calculation part:
require_relative 'wektor.rb'
#Coefficients
def Coefficients(i, j, tabX, tabY, pyramid)
#mnozymy przez Xj
length = pyramid[i][j-1].length
temp = Wektor.new(length).SetVector(pyramid[i][j-1])
temp.MultiplyBy(tabX[j])
pyramid[i][j].SetVector(temp)
#odjęcie Pi,j-1 przesuniętego o 1 w prawo
temp = Wektor.new(length).SetVector(pyramid[i][j-1])
temp.ShiftRight
pyramid[i][j].Sub(temp)
#dodanie Pi+1, j przesuniętego o 1 w prawo
temp = Wektor.new(length).SetVector(pyramid[i+1][j])
temp.ShiftRight
pyramid[i][j].Add(temp)
#odjęcie Pi+1, j pomnożonego przez Xi
temp = Wektor.new(length).SetVector(pyramid[i+1][j])
temp.MultiplyBy(tabX[i])
pyramid[i][j].Sub(temp)
#podzielenie przez (Xj - Xi)
pyramid[i][j].DivideBy(tabX[j] - tabX[i])
return pyramid[i][j]
end
#CalculateResult
def CalculatePolynomialResult(x,y,n)
pyramid = Hash.new {|h,k| h[k] = Wektor.new(n)}
for i in 0...n do
for j in 0...n-i do
if (j != i+j) then
next
end
pyramid[j][j] = Wektor.new(n)
pyramid[j][j].push(y[j])
end
end
for i in 0...n do
for j in 0...n-i do
if (j == i+j) then
next
end
pyramid[j][i+j] = Wektor.new(n)
Coefficients(j, i+j, x, y, pyramid)
end
end
return pyramid[0][n-1]
end
We are facing the problem when the Coefficients method is calculating something we still get zeros. There is no exception error but our Vector are zeros. I added a link for our Source at Math Overflow to explain what is going on.
This is the same code but written in C#, to play with .NET.
Any ideas why our vectors are useless? Like something is overwriting them or maybe with some value/reference? We are unable to track that issue.

Related

How to implement Java's Comparable module in Ruby

I'm currently going over Robert Sedgewick's Algorithms book. In the book for the implementation of a Priority Queue there is the use of the Comparable module. While going over the top k frequent elements leetcode problem I noticed that there would be an error in my Ruby implementation.
def top_k_frequent(nums, k)
ans = []
h = Hash.new(0)
nums.each do |num|
h[num] += 1
end
heap = Heap.new
h.each do |k,v|
heap.insert({k => v})
end
k.times do
a = heap.del_max
ans.push(a.keys[0])
end
ans
end
class Heap
def initialize
#n = 0
#pq = []
end
def insert(v)
#pq[#n += 1] = v
swim(#n)
end
def swim(k)
while k > 1 && less((k / 2).floor, k)
swap((k / 2).floor, k)
k = k/2
end
end
def swap(i, j)
temp = #pq[i]
#pq[i] = #pq[j]
#pq[j] = temp
end
def less(i, j)
#pq[i].values[0] < #pq[j].values[0]
end
def del_max
max = #pq[1]
swap(1, #n)
#n -= 1
#pq[#n + 1] = nil
sink(1)
max
end
def sink(k)
while 2 * k <= #n
j = 2 * k
if !#pq[j + 1].nil?
j += 1 if j > 1 && #pq[j].values[0] < #pq[j + 1].values[0]
end
break if !less(k, j)
swap(k, j)
k = j
end
end
end
Above is the Java Priority Queue implementation.
Ruby's comparable operator is <=> which will return one of -1, 0, 1 and nil (nil mean could not compare).
In order to compare two objects , both need to implement a method def <=>(other). This is not on Object, so is not available on any objects that don't implement it or extend from a class that does implement it. Numbers and Strings, for example, do have an implementation. Hashes do not.
I think in your case, the issue is slightly different.
When you call queue.insert(my_hash) what you're expecting is for the algorithm to break up my_hash and build from that. Instead, the algorithm takes the hash as a single, atomic object and inserts that.
If you add something like:
class Tuple
attr_accessor :key, :value
def initialize(key, value)
#key = key
#value = value
end
def <=>(other)
return nil unless other.is_a?(Tuple)
value <=> other.value
end
end
then this will allow you to do something like:
hsh = { 1 => 3, 2 => 2, 3 => 1}
tuples = hsh.map { |k, v| Tuple.new(k, v) }
tuples.each { |tuple| my_heap.insert(tuple) }
you will have all of your data in the heap.
When you retrieve an item, it will be a tuple, so you can just call item.key and item.value to access the data.

How to create a bubble sort of a double-linked list for Ruby

I have been implementing a bubble sort for a doubly linked list:
def sort2(list) #bubble sort
for i in 0...list.length
for j in 0...list.length-1-i
if list.get(j+1)<list.get(j)
list.swap(j+1, j)
end
end
end
end
I don't have any idea how implement a bucket-sort. We can only use methods like:
get(i) - which return value of i element
swap(i, j) - which swaps two elements
length(list) - return length of list
This is the code for get, swap and length:
def swap(i,j)
if i > j
i, j = j, i
elsif j == i
return
end
tmp = nil
list = #ListE.next #first element
for it in 0...j
if i == it
tmp = list
end
list = list.next
end
tmp.v, list.v = list.v, tmp.v
end
def get(i)
a = #ListE
while i>0
a = a.next
i-=1
end
return a.next.v
end
def length()
list = #ListE.next
length_of_list = 0
while list.v != nil
length_of_list += 1
list = list.next
end
return length_of_list
end
This is my attempt at an insertion sort:
def sort3(list) #insertion sort
for i in 1...list.length
j = i
while j > 0 and list.get(j-1) > list.get(j)
list.swap(j-1, i)
j -= 1
end
end
end

Ruby Program to solve Circular Primes below number x

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

Need to make this more Ruby-like

I'm new to Ruby and I seem to be comfortable using while loops. But I would like to simplify my code by possibly using the 'each' method. How would I do this for this particular block of code?
sum_array = []
i = 0
while i < array.length - 1
j = i + 1
while j < array.length
sum = array[i] + array[j]
if sum != 0
sum_array << sum
end
j += 1
end
i += 1
end
sum_array = array.combination(2).map{|n, m| n + m}.reject(&:zero?)
array = (1..10).to_a # test array [1,2,3,4,....10]
sum_array = []
(0...array.length).each do |i| # from 0 to array.length-1
(i+1...array.length).each do |j| # from i+1 to array.length-1
sum = array[i] + array[j]
sum_array << sum unless sum == 0 # brief condition
end
end
def sum_array(input)
[].tap do |sums|
input.each_with_index do |x, index|
tail = input[index.next..-1]
tail.each do |y|
sum = x + y
sums << sum unless sum.zero?
end
end
end
end
puts sum_array([1,2,0,0])
# => [3,1,1,2,2]
You could do this:
sum_array = []
array.each_index do |i|
sum_array += (i+1...array.length).collect { |j| array[i] + array[j] }
end
sum_array.reject!(&:zero?)

more ruby way of doing project euler #2

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

Resources