Last active
December 28, 2018 16:07
-
-
Save israellias/1522e5ca61a8b4e14871a4d8a6d5bd53 to your computer and use it in GitHub Desktop.
Platzi - Reto 8
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Platzi - Reto 8 Diciembre 23 | |
# @author: @israellias | |
# ruby_version: 2.5.3 | |
#regalaconocimiento | |
module Model | |
class Box < Struct.new(:name, :money, :weight) | |
end | |
class Combination < Struct.new(:boxes) | |
def initialize(boxes = nil) | |
self.boxes = boxes || [] | |
end | |
def +(combination) | |
Combination.new(self.boxes + combination.boxes) | |
end | |
def weight | |
boxes.sum(&:weight) | |
end | |
def money | |
boxes.sum(&:money) | |
end | |
def valid?(limit) | |
weight <= limit | |
end | |
end | |
end | |
module App | |
# @return [Array[Model::Box]] | |
def self.setup | |
box_a = Model::Box.new('Caja A', 100, 40) | |
box_b = Model::Box.new('Caja B', 20, 10) | |
box_c = Model::Box.new('Caja C', 40, 120) | |
box_d = Model::Box.new('Caja D', 20, 20) | |
box_e = Model::Box.new('Caja E', 10, 10) | |
[box_a, box_b, box_c, box_d, box_e] | |
end | |
# @param [Array[Model::Box]] boxes | |
# @return [Array[Model::Combination]] | |
def self.combinations(boxes) | |
[Model::Combination.new] + combine(boxes) # empty case + combinations | |
end | |
# @param [Array[Model::Box]] boxes | |
# @return [Array[Model::Combination]] | |
def self.combine(boxes) | |
return [] unless boxes.any? # no one combination here e.g. [] | |
single = Model::Combination.new([boxes.first]) # get combination with the first box e.g. [1] | |
combinations = combine(boxes[1..-1]) # get combinations with the rest of boxes e.g. [[2],[3],[2,3]] # recursive | |
joined = combinations.map {|combination| single + combination} # join the single and combinations into third group of combinations e.g.[[1,2],[1,3],[1,2,3]] | |
[single] + combinations + joined # get all combinations for boxes e.g. [[1],[2],[3],[2,3],[1,2],[1,3],[1,2,3]] | |
end | |
# @param [Array[Model::Box]] boxes | |
# @param [Integer] limit | |
# @return [Model::Combination] | |
def self.choose(boxes, limit) | |
@combinations = combinations(boxes) | |
@combinations.select {|c| c.valid?(limit)}.max_by(&:money) | |
end | |
def self.run(boxes = nil, limit = 150) | |
boxes ||= setup | |
solution = choose(boxes, limit) | |
puts "El Grinch encontró la solución óptima con #{solution.boxes.size} cajas:" | |
solution.boxes.each {|b| puts b.name} | |
puts "Con un peso total de: #{solution.weight} Kg" | |
puts "Y el total de dinero de: #{solution.money} USD" | |
puts 'Desear ver todas las combinaciones posibles(y/n)' | |
if gets.chomp === 'y' | |
@combinations.each do |combination| | |
puts "[#{combination.boxes.map(&:name).join(',')}] => {money: #{combination.money}, weight: #{combination.weight}}" | |
end | |
end | |
puts 'Goodbye!' | |
end | |
end | |
App.run |
Lo importante está en el método App.combine, que se encarga de preparar todas las posibles combinaciones de cajas que pueden entrar en la bolsa (incluida la opcion de ninguna caja)
Este numero de combinaciones es igual a 2^n donde n es el numero de cajas. En este caso las combinaciones posibles fueron de 2^5 = 32 combinaciones que se deben evaluar para determinar la optima.
Ruby permite escribir codigo legible y corto como se puede ver en la linea 71
71: @combinations.select {|c| c.valid?(limit)}.max_by(&:money)
y tambien permite modificar los operadores como se hizo en la linea 15
15: def +(combination)
16: Combination.new(self.boxes + combination.boxes)
17: end
y se utilizo en la linea 61
61: joined = combinations.map {|combination| single + combination}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
El resultado en la terminal es el siguiente