Решение на Трета задача от Мая Недялкова

Обратно към всички решения

Към профила на Мая Недялкова

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 19 успешни тест(а)
  • 0 неуспешни тест(а)

Код

require 'bigdecimal'
require 'bigdecimal/util' # добавя String#to_d
class Product
attr_accessor :name, :price, :promotion_type, :details
def get_one_free(amount)
(amount/@details)*@price
end
def package(amount)
t = (amount/@details.keys[0])*@details.keys[0]
t*BigDecimal(@details.values[0].to_s)*BigDecimal("0.01")*price
end
def threshold(amount)
if amount <= @details.keys.first
0
else
t = (amount-@details.keys.first)*price
t*(BigDecimal(@details.values.first.to_s)*BigDecimal("0.01"))
end
end
def initialize(name, price, promotion = nil)
@name, @price = name, price.to_d
if promotion != nil
@promotion_type, @details = promotion.keys.first, promotion.values.first
else
@promotion_type, @details = nil, nil
end
end
def discount(amount)
(@promotion_type.nil?) ? 0 : send(@promotion_type, amount)
end
end
class Coupon
attr_accessor :name, :type, :value
def initialize(name, type, value)
@name, @type, @value = name, type, value.to_s.to_d
end
def discount(price)
if @type == :percent
BigDecimal(@value.to_s)*BigDecimal("0.01")*BigDecimal(price.to_s)
else
(price > @value) ? @value : price
end
end
def price_off(price)
if @type == :percent
10*BigDecimal(price.to_s)/(100-BigDecimal(value.to_s))
else
(price > @value) ? @value : price
end
end
end
class Cart
attr_accessor :using_coupon
def initialize(inventory, coupons)
@cart = Hash.new(0)
@inventory, @coupons, @using_coupon = inventory, coupons, nil
end
def add(product_name, number = 1)
if @inventory.select {|x| x.name == product_name} == [] or number <= 0 or number > 99
raise "Invalid parameters passed."
else
@cart[@inventory.select {|x| x.name == product_name}.first] += number
end
end
def use(coupon_name)
@using_coupon = @coupons.select {|x| x.name == coupon_name}.first
end
def total()
total = total1 - ((@using_coupon.nil?) ? 0 : @using_coupon.discount(total1))
end
def total1()
prices = @cart.map {|product, amount| product.price*amount-product.discount(amount)}
t = prices.inject(:+)
t = 0 unless t
t
end
def invoice()
cart = @cart.to_a
line = '+' + '-'*48 + '+' + '-'*10 + '+' + "\n"
t = line + '| Name' + ' '*39 + 'qty |' + ' '*4 + "price |\n" + line
@cart.each do |key, value|
t += sprintf("| %- 38s", key.name)
t += sprintf("%8d |", value) + sprintf("%9.2f |\n", value*key.price)
t += send(key.promotion_type, key, value) if key.promotion_type != nil
end
t += reduction + line + '| TOTAL' + ' '*42 + '|' + sprintf("%9.2f |\n", total) + line
end
private
def reduction()
t = ""
if u = @using_coupon
if u.type == :percent
t = sprintf("| Coupon %-40s", u.name.to_s+" - "+sprintf("%d", u.value)+"% off")
t += sprintf("|%9.2f |\n", -total1+total)
else
t = sprintf("%-49s",sprintf("| Coupon "+u.name.to_s+" - %.2f off", u.value.to_s))
t += sprintf("|%9.2f |\n", -total1+total)
end
end
t
end
def get_one_free(key, value)
l1 = sprintf("| %-45s", "(buy " + (key.details-1).to_s + ", get 1 free)")
l1 += sprintf("|%9.2f |\n", -key.get_one_free(value))
end
def package(key, value)
percent = sprintf("%d", key.details.values[0])
amount = (key.details.keys[0]).to_s
l1 = sprintf("| %-45s", "(get " + percent + "% off for every " + amount + ")")
l1 += sprintf("|%9.2f |\n", -key.package(value))
end
def threshold(key, value)
ending = case key.details.keys[0]
when 1 then "st)"
when 2 then "nd)"
when 3 then "rd)"
else "th)"
end
percent = "(" + (key.details.values[0]).to_s + "% off of every after the "
l1 = sprintf("| %-45s", percent + (key.details.keys[0]).to_s + ending)
l1 += sprintf("|%9.2f |\n", -key.threshold(value))
end
end
class Inventory
def initialize
@inventory, @coupons = [], []
end
def register(product_name, price, promotion = nil)
if product_name.length > 40 or
price.to_d < 0.01 or
price.to_d > 999.99 or
@inventory.include? product_name
raise "Invalid parameters passed."
else
@inventory << Product.new(product_name, price, promotion)
end
end
def register_coupon(name, k)
@coupons << Coupon.new(name, k.keys.first, k.values.first)
end
def new_cart
Cart.new(@inventory, @coupons)
end
end

Лог от изпълнението

...................

Finished in 0.57063 seconds
19 examples, 0 failures

История (1 версия и 0 коментара)

Мая обнови решението на 07.11.2011 09:14 (преди над 12 години)

+require 'bigdecimal'
+require 'bigdecimal/util' # добавя String#to_d
+
+class Product
+ attr_accessor :name, :price, :promotion_type, :details
+
+ def get_one_free(amount)
+ (amount/@details)*@price
+ end
+
+ def package(amount)
+ t = (amount/@details.keys[0])*@details.keys[0]
+ t*BigDecimal(@details.values[0].to_s)*BigDecimal("0.01")*price
+ end
+
+ def threshold(amount)
+ if amount <= @details.keys.first
+ 0
+ else
+ t = (amount-@details.keys.first)*price
+ t*(BigDecimal(@details.values.first.to_s)*BigDecimal("0.01"))
+ end
+ end
+
+ def initialize(name, price, promotion = nil)
+ @name, @price = name, price.to_d
+ if promotion != nil
+ @promotion_type, @details = promotion.keys.first, promotion.values.first
+ else
+ @promotion_type, @details = nil, nil
+ end
+ end
+
+ def discount(amount)
+ (@promotion_type.nil?) ? 0 : send(@promotion_type, amount)
+ end
+end
+
+class Coupon
+ attr_accessor :name, :type, :value
+
+ def initialize(name, type, value)
+ @name, @type, @value = name, type, value.to_s.to_d
+ end
+
+ def discount(price)
+ if @type == :percent
+ BigDecimal(@value.to_s)*BigDecimal("0.01")*BigDecimal(price.to_s)
+ else
+ (price > @value) ? @value : price
+ end
+ end
+
+ def price_off(price)
+ if @type == :percent
+ 10*BigDecimal(price.to_s)/(100-BigDecimal(value.to_s))
+ else
+ (price > @value) ? @value : price
+ end
+ end
+end
+
+class Cart
+ attr_accessor :using_coupon
+
+ def initialize(inventory, coupons)
+ @cart = Hash.new(0)
+ @inventory, @coupons, @using_coupon = inventory, coupons, nil
+ end
+
+ def add(product_name, number = 1)
+ if @inventory.select {|x| x.name == product_name} == [] or number <= 0 or number > 99
+ raise "Invalid parameters passed."
+ else
+ @cart[@inventory.select {|x| x.name == product_name}.first] += number
+ end
+ end
+
+ def use(coupon_name)
+ @using_coupon = @coupons.select {|x| x.name == coupon_name}.first
+ end
+
+ def total()
+ total = total1 - ((@using_coupon.nil?) ? 0 : @using_coupon.discount(total1))
+ end
+
+ def total1()
+ prices = @cart.map {|product, amount| product.price*amount-product.discount(amount)}
+ t = prices.inject(:+)
+ t = 0 unless t
+ t
+ end
+
+ def invoice()
+ cart = @cart.to_a
+ line = '+' + '-'*48 + '+' + '-'*10 + '+' + "\n"
+ t = line + '| Name' + ' '*39 + 'qty |' + ' '*4 + "price |\n" + line
+ @cart.each do |key, value|
+ t += sprintf("| %- 38s", key.name)
+ t += sprintf("%8d |", value) + sprintf("%9.2f |\n", value*key.price)
+ t += send(key.promotion_type, key, value) if key.promotion_type != nil
+ end
+ t += reduction + line + '| TOTAL' + ' '*42 + '|' + sprintf("%9.2f |\n", total) + line
+ end
+
+ private
+
+ def reduction()
+ t = ""
+ if u = @using_coupon
+ if u.type == :percent
+ t = sprintf("| Coupon %-40s", u.name.to_s+" - "+sprintf("%d", u.value)+"% off")
+ t += sprintf("|%9.2f |\n", -total1+total)
+ else
+ t = sprintf("%-49s",sprintf("| Coupon "+u.name.to_s+" - %.2f off", u.value.to_s))
+ t += sprintf("|%9.2f |\n", -total1+total)
+ end
+ end
+ t
+ end
+
+ def get_one_free(key, value)
+ l1 = sprintf("| %-45s", "(buy " + (key.details-1).to_s + ", get 1 free)")
+ l1 += sprintf("|%9.2f |\n", -key.get_one_free(value))
+ end
+
+ def package(key, value)
+ percent = sprintf("%d", key.details.values[0])
+ amount = (key.details.keys[0]).to_s
+ l1 = sprintf("| %-45s", "(get " + percent + "% off for every " + amount + ")")
+ l1 += sprintf("|%9.2f |\n", -key.package(value))
+ end
+
+ def threshold(key, value)
+ ending = case key.details.keys[0]
+ when 1 then "st)"
+ when 2 then "nd)"
+ when 3 then "rd)"
+ else "th)"
+ end
+ percent = "(" + (key.details.values[0]).to_s + "% off of every after the "
+ l1 = sprintf("| %-45s", percent + (key.details.keys[0]).to_s + ending)
+ l1 += sprintf("|%9.2f |\n", -key.threshold(value))
+ end
+end
+
+class Inventory
+ def initialize
+ @inventory, @coupons = [], []
+ end
+
+ def register(product_name, price, promotion = nil)
+ if product_name.length > 40 or
+ price.to_d < 0.01 or
+ price.to_d > 999.99 or
+ @inventory.include? product_name
+ raise "Invalid parameters passed."
+ else
+ @inventory << Product.new(product_name, price, promotion)
+ end
+ end
+
+ def register_coupon(name, k)
+ @coupons << Coupon.new(name, k.keys.first, k.values.first)
+ end
+
+ def new_cart
+ Cart.new(@inventory, @coupons)
+ end
+end