Skip to content

Instantly share code, notes, and snippets.

@lolgear
Created October 27, 2017 20:25
Show Gist options
  • Save lolgear/9c60ffdf12189b014ef8a7bcae3e7f68 to your computer and use it in GitHub Desktop.
Save lolgear/9c60ffdf12189b014ef8a7bcae3e7f68 to your computer and use it in GitHub Desktop.
This is simple resource counter that count an amount of time to produce the specific resource represented as vector
# Space describe the dependencies between coordinates
class Space
attr_accessor :basis, :normalized_basis
def add(lhs, rhs)
# pp "left -> #{lhs}"
# pp "right -> #{rhs}"
max = [lhs.count, rhs.count].max
result = Array.new(max, 0).each_with_index.map { |e, i|
# puts "left -> #{lhs[i]} right -> #{rhs[i]} e -> #{e}"
e += lhs[i] if i < lhs.count
e += rhs[i] if i < rhs.count
e
}
result
end
# def add(lhs, rhs)
# pp "left -> #{lhs}"
# pp "right -> #{rhs}"
# [lhs, rhs].transpose.map{|x| x.reduce(:+)}
# end
def initialize(basis = nil)
@basis = basis || self.class.default_basis
end
# def normalize(vector)
# items = vector
# # now we should take basis and substract it from vector.
# # for that reason we do next thing:
# result = vector
# basis_normalization = []
# basis_normalization = basis.reduce([]) do |e, total|
# total = [total, e].transpose.map{|x| x.reduce(:+)}
# total
# end
# [result, basis_normalization].transpose.map{|x| x.reduce(:+)}
# end
#
# def normalized_vector_component_at_index(vector, index)
# basis_vector = basis[index]
# value = vector[index]
# if basis_vector.empty?
# value
# else
# the_result = []
# basis_vector.each_with_index do |v, i|
# the_result << normalized_vector_component_at_index(basis_vector, i) * v
# end
# end
# end
def normalized_basis
@normalized_basis ||=
self.basis.each_with_index.map do |x, i|
puts "e_#{i+1} normalization started #{x}"
vector = normalized(x)
puts "e_#{i+1} normalized = #{vector}"
end
end
def normalized(vector)
# [0, 0, 0, 0, 1, 1] - this is a vector
# we need to expand it with basis
# so, we need for each item in vector return something
# for example, for vector above we should return:
# [[],[],[],[]] empty array of array for first values
# and
# 1 * [0,0,0,2,2]
# and
# 1 * [2,0,0,2]
# we should also
zeroed_vector = Array.new(vector.count, 0)
vector.each_with_index.map do |value, index|
unless value
[]
else
# find basis
pp "vector: #{vector} at index: #{index} value: #{value}"
basis_vector = find_basis_vector_at_index(index)
pp "e_#{index+1} -> #{basis_vector}"
normalized_basis_vector = normalized(basis_vector)
vector_result = normalized_basis_vector.map{|k| k * value}
vector_result = add(zeroed_vector, vector_result)
vector_result[index] += value
pp "vector_result! #{vector_result} add value: #{value} at index: #{index}"
vector_result
end
end
end
def find_basis_vector_at_index(index)
basis[index]
end
class << self
def default_basis
[
[], # e1
[], # e2
[2, 1], # e3 = 2 * e1 + e2
[], # e4
[0, 2, 0, 1], # e5 = 2 * e2 + e4
[0, 0, 0, 2, 2], # e6 = 2 * e4 + 2 * e5
[2, 0, 0, 2] # e7 = 2 * e1 + 2 * e4
]
end
end
end
# Measure calculates distance between elements
# Each element should be a vector?
class Measure
attr_accessor :space
attr_accessor :rules
def initialize(space = nil)
@space = space || Space.new
end
def find_rule_at_index(index)
rules[index]
end
def scalar_product(lhs, rhs)
# do something
0
end
def norm(lhs)
scalar_product(lhs, [0])
end
end
class TimeMeasure < Measure
def with_rules(rules = nil)
@rules = rules || self.class.default_rules
self
end
def scalar_product(lhs, rhs)
vector = space.add(lhs, rhs)
time = vector.each_with_index.map do |value,index|
# for each vector component we independently calculate time by traversing into basis.
# after that we return the time
basis_vector = space.find_basis_vector_at_index(index)
time_value = find_rule_at_index(index)
puts "index -> #{index} value -> #{value}"
puts "basis_vector -> #{basis_vector}"
puts "time_value -> #{time_value}"
puts "\n"
if value == 0
0
elsif basis_vector.empty?
time_value * value
else
time_value * value + value * norm(basis_vector)
end
end
total = time.max
end
class << self
def default_rules
# how much time does every item costs.
[
1,
2 * 2,
5 * 2,
8 * 2,
12 * 2,
20 * 2,
16 * 2,
]
end
end
end
class TimeWithSpawnsMeasure < TimeMeasure
attr_accessor :spawns
def with_spawns(spawns = nil)
@spawns = spawns || self.class.default_spawns
self
end
def find_spawn_at_index(index)
spawns[index] || 1
end
class << self
def default_spawns
[
5,
5,
5,
5,
5,
5,
5,
]
end
end
def scalar_product(lhs,rhs)
vector = space.add(lhs, rhs)
time = vector.each_with_index.map do |value,index|
# for each vector component we independently calculate time by traversing into basis.
# after that we return the time
basis_vector = space.find_basis_vector_at_index(index)
time_value = find_rule_at_index(index)
spawn_value = find_spawn_at_index(index)
puts "index -> #{index} value -> #{value}"
puts "basis_vector -> #{basis_vector}"
puts "time_value -> #{time_value}"
puts "spawn_value -> #{spawn_value}"
puts "\n"
if value == 0
0
elsif basis_vector.empty?
time_value * (value / spawn_value.to_f).ceil
else
(time_value + norm(basis_vector)) * (value / spawn_value.to_f).ceil
end
end
total = time.max
end
end
def MainWork
time = TimeWithSpawnsMeasure.new.with_rules.with_spawns
it = time.norm([0,0,0,0,0,1,0])
puts "\n\nRESULT: #{(it * 0.5)} min"
end
MainWork()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment