tetromino 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +49 -0
- data/LICENSE.txt +21 -0
- data/README.md +200 -0
- data/Rakefile +6 -0
- data/bin/console +11 -0
- data/bin/setup +8 -0
- data/lib/tetromino.rb +19 -0
- data/lib/tetromino/args.rb +8 -0
- data/lib/tetromino/box.rb +29 -0
- data/lib/tetromino/exceptions.rb +23 -0
- data/lib/tetromino/item.rb +50 -0
- data/lib/tetromino/packer.rb +63 -0
- data/lib/tetromino/packing.rb +1 -0
- data/lib/tetromino/placement.rb +1 -0
- data/lib/tetromino/space.rb +43 -0
- data/lib/tetromino/version.rb +3 -0
- data/tetromino.gemspec +41 -0
- metadata +140 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f213c2b8801c9305548c310584cc79c250cb01db
|
4
|
+
data.tar.gz: 8a26aa1a26d3fe24cd4af2855337e208617d6824
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f72956ce3244720a88cf4be9e921a34204534dd1a83bfba8e9bee685d7cda22fd310d3ce096c4b0dd2e53b203c0f001fedd75bdc2384b325fc67d25001b47314
|
7
|
+
data.tar.gz: d76fa657f1e0cc53670d20c681744f6bb2360d1ad3b411739feed4270470570790170611fba21470e11973666040a7ddfb85e602cbf37ad59629aabbb77afb91
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
tetromino (0.1.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
coderay (1.1.2)
|
10
|
+
diff-lcs (1.3)
|
11
|
+
docile (1.3.1)
|
12
|
+
json (2.1.0)
|
13
|
+
method_source (0.9.0)
|
14
|
+
pry (0.11.3)
|
15
|
+
coderay (~> 1.1.0)
|
16
|
+
method_source (~> 0.9.0)
|
17
|
+
rake (10.5.0)
|
18
|
+
rspec (3.7.0)
|
19
|
+
rspec-core (~> 3.7.0)
|
20
|
+
rspec-expectations (~> 3.7.0)
|
21
|
+
rspec-mocks (~> 3.7.0)
|
22
|
+
rspec-core (3.7.1)
|
23
|
+
rspec-support (~> 3.7.0)
|
24
|
+
rspec-expectations (3.7.0)
|
25
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
26
|
+
rspec-support (~> 3.7.0)
|
27
|
+
rspec-mocks (3.7.0)
|
28
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
29
|
+
rspec-support (~> 3.7.0)
|
30
|
+
rspec-support (3.7.1)
|
31
|
+
simplecov (0.16.1)
|
32
|
+
docile (~> 1.1)
|
33
|
+
json (>= 1.8, < 3)
|
34
|
+
simplecov-html (~> 0.10.0)
|
35
|
+
simplecov-html (0.10.2)
|
36
|
+
|
37
|
+
PLATFORMS
|
38
|
+
ruby
|
39
|
+
|
40
|
+
DEPENDENCIES
|
41
|
+
bundler (~> 1.16)
|
42
|
+
pry (~> 0.11.0)
|
43
|
+
rake (~> 10.0)
|
44
|
+
rspec (~> 3.0)
|
45
|
+
simplecov (~> 0.16.1)
|
46
|
+
tetromino!
|
47
|
+
|
48
|
+
BUNDLED WITH
|
49
|
+
1.16.2
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 deliver.ee
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
[](https://badge.fury.io/rb/tetromino)
|
2
|
+
|
3
|
+
# Tetromino
|
4
|
+
|
5
|
+
## Introduction
|
6
|
+
|
7
|
+
First fit heuristic algorithm for 4D bin packing problem solver (4dbpp).
|
8
|
+
An implementation of the "4D" bin packing problem i.e. given a list of items,
|
9
|
+
how many boxes do you need to fit them all in taking into account physical
|
10
|
+
dimensions and weights.
|
11
|
+
|
12
|
+
This project is a complete rewrite of [box_packer](https://github.com/mushishi78/box_packer)
|
13
|
+
|
14
|
+
It also provide 2 additional "real life" features:
|
15
|
+
* Coerce items that can't be stacked.
|
16
|
+
* Coerce items that are not invertible.
|
17
|
+
|
18
|
+
...Especially if you need to pack (big) fragile items.
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
Add this line to your application's Gemfile:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
gem 'tetromino'
|
26
|
+
```
|
27
|
+
|
28
|
+
And then execute:
|
29
|
+
|
30
|
+
$ bundle
|
31
|
+
|
32
|
+
Or install it yourself as:
|
33
|
+
|
34
|
+
$ gem install tetromino
|
35
|
+
|
36
|
+
## Usage
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
tetromino = Tetromino.packer(dimensions: [40, 30, 20]) # Define the size of your box
|
40
|
+
tetromino.add_item!(dimensions: [40, 30, 10]) # Fill it up with item
|
41
|
+
tetromino.add_item!(dimensions: [10, 40, 30]) # ...Moarrr item!
|
42
|
+
tetromino.pack! # Pack your stuff
|
43
|
+
tetromino.packed_successfully? # => true
|
44
|
+
```
|
45
|
+
### Dimensions
|
46
|
+
|
47
|
+
Dimensions **should always** be declared in the following order:
|
48
|
+
`[depth, width, height]`
|
49
|
+
|
50
|
+
### Detailed results
|
51
|
+
|
52
|
+
You can also get the results of the algorithm.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
results = tetromino.results
|
56
|
+
=> [#<struct Tetromino::Packing
|
57
|
+
placements=
|
58
|
+
[
|
59
|
+
#<struct Tetromino::Placement
|
60
|
+
dimensions=[40, 30, 10],
|
61
|
+
position=[0, 0, 0],
|
62
|
+
weight=0>,
|
63
|
+
#<struct Tetromino::Placement
|
64
|
+
dimensions=[40, 30, 10],
|
65
|
+
position=[0, 0, 10],
|
66
|
+
weight=0>
|
67
|
+
],
|
68
|
+
weight=0.0,
|
69
|
+
spaces=
|
70
|
+
[
|
71
|
+
#<struct Tetromino::Space
|
72
|
+
dimensions=[0, 30, 20],
|
73
|
+
position=[40, 0, 0]>,
|
74
|
+
#<struct Tetromino::Space
|
75
|
+
dimensions=[40, 0, 20],
|
76
|
+
position=[0, 30, 0]>,
|
77
|
+
#<struct Tetromino::Space
|
78
|
+
dimensions=[0, 30, 10],
|
79
|
+
position=[40, 0, 10]>,
|
80
|
+
#<struct Tetromino::Space
|
81
|
+
dimensions=[40, 0, 10],
|
82
|
+
position=[0, 30, 10]>,
|
83
|
+
#<struct Tetromino::Space
|
84
|
+
dimensions=[40, 30, 0],
|
85
|
+
position=[0, 0, 20]>
|
86
|
+
]>
|
87
|
+
]
|
88
|
+
```
|
89
|
+
|
90
|
+
### Placements
|
91
|
+
|
92
|
+
Placements represent how your items have been organized into your box(es) (dimensions & positions).
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
results.placements
|
96
|
+
```
|
97
|
+
|
98
|
+
### Spaces
|
99
|
+
|
100
|
+
These are the empty spaces remaining in your box(es).
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
results.spaces
|
104
|
+
```
|
105
|
+
|
106
|
+
### Weight
|
107
|
+
|
108
|
+
This is the total weight of the packed items.
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
results.weight
|
112
|
+
```
|
113
|
+
|
114
|
+
## Advanced usages
|
115
|
+
|
116
|
+
### Weight coercion
|
117
|
+
|
118
|
+
You can define a weight limit constraint on your box(es).
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
begin
|
122
|
+
tetromino = Tetromino.packer(dimensions: [40, 30, 20], max_weight: 4)
|
123
|
+
tetromino.add_item!(dimensions: [40, 15, 20], weight: 2)
|
124
|
+
tetromino.add_item!(dimensions: [40, 15, 20], weight: 3)
|
125
|
+
tetromino.pack!
|
126
|
+
tetromino.packed_successfully? # => false
|
127
|
+
rescue Tetromino::Exceptions::Error => error
|
128
|
+
puts error.message # => Maximum boxes quantity exceeded
|
129
|
+
end
|
130
|
+
```
|
131
|
+
|
132
|
+
### Multiple boxes
|
133
|
+
|
134
|
+
You can try to pack your items in multiple boxes.
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
tetromino = Tetromino.packer(dimensions: [40, 30, 20], boxes_limit: 2)
|
138
|
+
tetromino.add_item!(dimensions: [40, 30, 20])
|
139
|
+
tetromino.add_item!(dimensions: [30, 20, 40])
|
140
|
+
tetromino.pack!
|
141
|
+
tetromino.packed_successfully? # => true
|
142
|
+
```
|
143
|
+
|
144
|
+
### Not stackable items
|
145
|
+
|
146
|
+
You can define if your items can't be stacked.
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
begin
|
150
|
+
tetromino = Tetromino.packer(dimensions: [40, 30, 20])
|
151
|
+
tetromino.add_item!(dimensions: [40, 30, 10], stackable: false)
|
152
|
+
tetromino.add_item!(dimensions: [40, 30, 10], stackable: false)
|
153
|
+
tetromino.pack!
|
154
|
+
tetromino.packed_successfully? # => false
|
155
|
+
rescue Tetromino::Exceptions::Error => error
|
156
|
+
puts error.message # => Maximum boxes quantity exceeded
|
157
|
+
end
|
158
|
+
```
|
159
|
+
|
160
|
+
### Not invertible items
|
161
|
+
|
162
|
+
You can define if your items can't be leaned.
|
163
|
+
(impossible to permute height with depth or width)
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
begin
|
167
|
+
tetromino = Tetromino.packer(dimensions: [40, 30, 20])
|
168
|
+
tetromino.add_item!(dimensions: [40, 30, 10], invertible: false)
|
169
|
+
tetromino.add_item!(dimensions: [40, 10, 30], invertible: false)
|
170
|
+
tetromino.pack!
|
171
|
+
tetromino.packed_successfully? # => false
|
172
|
+
rescue Tetromino::Exceptions::Error => error
|
173
|
+
puts error.message # => Maximum boxes quantity exceeded
|
174
|
+
end
|
175
|
+
```
|
176
|
+
|
177
|
+
### Parameters combinations
|
178
|
+
|
179
|
+
You can combine all the parameters at once:
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
tetromino = Tetromino.packer(dimensions: [40, 30, 20], boxes_limit: 2, max_weight: 5)
|
183
|
+
tetromino.add_item!(dimensions: [40, 30, 10], invertible: false, stackable: false, weight: 2)
|
184
|
+
tetromino.add_item!(dimensions: [30, 40, 10], invertible: false, stackable: false, weight: 3)
|
185
|
+
tetromino.pack!
|
186
|
+
tetromino.packed_successfully? # => true
|
187
|
+
```
|
188
|
+
|
189
|
+
## Errors handling
|
190
|
+
|
191
|
+
Tetromino will always raise an error if it is unable to pack your items with
|
192
|
+
the given constraints.
|
193
|
+
|
194
|
+
## Contributing
|
195
|
+
|
196
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/deliver-ee/tetromino.
|
197
|
+
|
198
|
+
## License
|
199
|
+
|
200
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "tetromino"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
require "pry"
|
10
|
+
Pry.start
|
11
|
+
|
data/bin/setup
ADDED
data/lib/tetromino.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "tetromino/args"
|
2
|
+
require "tetromino/box"
|
3
|
+
require "tetromino/exceptions"
|
4
|
+
require "tetromino/item"
|
5
|
+
require "tetromino/packer"
|
6
|
+
require "tetromino/packing"
|
7
|
+
require "tetromino/placement"
|
8
|
+
require "tetromino/space"
|
9
|
+
require "tetromino/version"
|
10
|
+
|
11
|
+
module Tetromino
|
12
|
+
extend Forwardable
|
13
|
+
def_delegator :@box, :add_item, :pack!
|
14
|
+
|
15
|
+
def self.packer(dimensions: [0, 0, 0], max_weight: nil, boxes_limit: 1)
|
16
|
+
box = Tetromino::Box.new(dimensions, max_weight)
|
17
|
+
Tetromino::Packer.new(box, boxes_limit)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module Tetromino
|
2
|
+
BOX_ARGS = %i[dimensions max_weight].freeze
|
3
|
+
ITEM_ARGS = %i[dimensions weight stackable invertible packed].freeze
|
4
|
+
PACKER_ARGS = %i[box boxes_limit].freeze
|
5
|
+
PACKING_ARGS = %i[placements weight spaces].freeze
|
6
|
+
PLACEMENT_ARGS = %i[dimensions position weight].freeze
|
7
|
+
SPACE_ARGS = %i[dimensions position].freeze
|
8
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Tetromino::Box = Struct.new(*Tetromino::BOX_ARGS) do
|
2
|
+
attr_reader :items
|
3
|
+
|
4
|
+
def depth
|
5
|
+
dimensions[0]
|
6
|
+
end
|
7
|
+
|
8
|
+
def width
|
9
|
+
dimensions[1]
|
10
|
+
end
|
11
|
+
|
12
|
+
def height
|
13
|
+
dimensions[2]
|
14
|
+
end
|
15
|
+
|
16
|
+
def volume
|
17
|
+
dimensions.inject(:*)
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_weight_limit?
|
21
|
+
not max_weight.nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
def append!(item:)
|
25
|
+
@items = [] if @items.nil?
|
26
|
+
@items << item if item.is_a?(Tetromino::Item)
|
27
|
+
item
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Tetromino
|
2
|
+
module Exceptions
|
3
|
+
class Error < StandardError; end
|
4
|
+
|
5
|
+
class TooHeavyItem < Error
|
6
|
+
def message
|
7
|
+
'Item is too big to fit in the box'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class CannotFitInBoxes < Error
|
12
|
+
def message
|
13
|
+
'Maximum boxes quantity exceeded'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class NothingToPack < Error
|
18
|
+
def message
|
19
|
+
'There are no items to pack'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
Tetromino::Item = Struct.new(*Tetromino::ITEM_ARGS) do
|
2
|
+
include Comparable
|
3
|
+
|
4
|
+
def depth
|
5
|
+
dimensions[0]
|
6
|
+
end
|
7
|
+
|
8
|
+
def width
|
9
|
+
dimensions[1]
|
10
|
+
end
|
11
|
+
|
12
|
+
def height
|
13
|
+
dimensions[2]
|
14
|
+
end
|
15
|
+
|
16
|
+
def volume
|
17
|
+
dimensions.inject(:*)
|
18
|
+
end
|
19
|
+
|
20
|
+
def <=> (other)
|
21
|
+
other.volume <=> self.volume
|
22
|
+
end
|
23
|
+
|
24
|
+
def place(space:)
|
25
|
+
permutations = []
|
26
|
+
permutations << [depth, width, height]
|
27
|
+
permutations << [width, depth, height]
|
28
|
+
|
29
|
+
if invertible
|
30
|
+
permutations << [depth, height, width]
|
31
|
+
permutations << [width, height, depth]
|
32
|
+
permutations << [height, width, depth]
|
33
|
+
permutations << [height, depth, width]
|
34
|
+
end
|
35
|
+
|
36
|
+
permutations.each do |perm|
|
37
|
+
next unless perm[0] <= space.dimensions[0] &&
|
38
|
+
perm[1] <= space.dimensions[1] &&
|
39
|
+
perm[2] <= space.dimensions[2]
|
40
|
+
|
41
|
+
# Consider that all remaining space above is filled
|
42
|
+
perm[2] = space.dimensions[2] unless stackable
|
43
|
+
|
44
|
+
return Tetromino::Placement.new(perm, space.position, weight)
|
45
|
+
end
|
46
|
+
|
47
|
+
return nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
Tetromino::Packer = Struct.new(*Tetromino::PACKER_ARGS) do
|
2
|
+
attr_reader :results
|
3
|
+
|
4
|
+
def add_item!(dimensions: [], weight: 0, stackable: true, invertible: true)
|
5
|
+
item = Tetromino::Item.new(dimensions, weight, stackable, invertible, false)
|
6
|
+
self.box.append!(item: item)
|
7
|
+
end
|
8
|
+
|
9
|
+
def items
|
10
|
+
box.items
|
11
|
+
end
|
12
|
+
|
13
|
+
def pack!
|
14
|
+
raise Tetromino::Exceptions::NothingToPack if items.nil? || items.empty?
|
15
|
+
@results = []
|
16
|
+
|
17
|
+
items.sort!.each do |item|
|
18
|
+
if box.has_weight_limit? && (item.weight.to_f > box.max_weight.to_f)
|
19
|
+
raise Tetromino::Exceptions::TooHeavyItem
|
20
|
+
end
|
21
|
+
|
22
|
+
@results.each do |packing|
|
23
|
+
next if box.has_weight_limit? && \
|
24
|
+
(packing.weight.to_f + item.weight.to_f > box.max_weight.to_f)
|
25
|
+
|
26
|
+
packing.spaces.each do |space|
|
27
|
+
next unless placement = item.place(space: space)
|
28
|
+
|
29
|
+
packing.placements += [placement]
|
30
|
+
packing.weight += item.weight.to_f
|
31
|
+
packing.spaces -= [space]
|
32
|
+
packing.spaces += space.break_up(placement: placement)
|
33
|
+
item.packed = true
|
34
|
+
break
|
35
|
+
end
|
36
|
+
|
37
|
+
break if item.packed
|
38
|
+
end
|
39
|
+
next if item.packed
|
40
|
+
|
41
|
+
space = Tetromino::Space.new(box.dimensions, [0, 0, 0])
|
42
|
+
|
43
|
+
placement = item.place(space: space)
|
44
|
+
item.packed = true unless placement.nil?
|
45
|
+
|
46
|
+
packing = Tetromino::Packing.new(
|
47
|
+
[placement],
|
48
|
+
item.weight.to_f,
|
49
|
+
space.break_up(placement: placement)
|
50
|
+
)
|
51
|
+
|
52
|
+
@results += [packing]
|
53
|
+
end
|
54
|
+
|
55
|
+
raise Tetromino::Exceptions::CannotFitInBoxes unless packed_successfully?
|
56
|
+
|
57
|
+
@results
|
58
|
+
end
|
59
|
+
|
60
|
+
def packed_successfully?
|
61
|
+
items.all?(&:packed) && (results.count <= boxes_limit)
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Tetromino::Packing = Struct.new(*Tetromino::PACKING_ARGS)
|
@@ -0,0 +1 @@
|
|
1
|
+
Tetromino::Placement = Struct.new(*Tetromino::PLACEMENT_ARGS)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
Tetromino::Space = Struct.new(*Tetromino::SPACE_ARGS) do
|
2
|
+
def break_up(placement:)
|
3
|
+
return [] if placement.nil?
|
4
|
+
[
|
5
|
+
Tetromino::Space.new(
|
6
|
+
[
|
7
|
+
dimensions[0] - placement.dimensions[0],
|
8
|
+
dimensions[1],
|
9
|
+
dimensions[2]
|
10
|
+
],
|
11
|
+
[
|
12
|
+
position[0] + placement.dimensions[0],
|
13
|
+
position[1],
|
14
|
+
position[2]
|
15
|
+
]
|
16
|
+
),
|
17
|
+
Tetromino::Space.new(
|
18
|
+
[
|
19
|
+
placement.dimensions[0],
|
20
|
+
dimensions[1] - placement.dimensions[1],
|
21
|
+
dimensions[2]
|
22
|
+
],
|
23
|
+
[
|
24
|
+
position[0],
|
25
|
+
position[1] + placement.dimensions[1],
|
26
|
+
position[2]
|
27
|
+
]
|
28
|
+
),
|
29
|
+
Tetromino::Space.new(
|
30
|
+
[
|
31
|
+
placement.dimensions[0],
|
32
|
+
placement.dimensions[1],
|
33
|
+
dimensions[2] - placement.dimensions[2]
|
34
|
+
],
|
35
|
+
[
|
36
|
+
position[0],
|
37
|
+
position[1],
|
38
|
+
position[2] + placement.dimensions[2]
|
39
|
+
]
|
40
|
+
)
|
41
|
+
]
|
42
|
+
end
|
43
|
+
end
|
data/tetromino.gemspec
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "tetromino/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "tetromino"
|
8
|
+
spec.version = Tetromino::VERSION
|
9
|
+
spec.authors = ["deliver.ee"]
|
10
|
+
spec.email = ["1337@deliver.ee"]
|
11
|
+
|
12
|
+
spec.summary = %q{
|
13
|
+
First fit heuristic algorithm for 4D
|
14
|
+
bin packing problem solver (4dbpp)
|
15
|
+
}
|
16
|
+
spec.description = %q{
|
17
|
+
An implementation of the "4D" bin packing
|
18
|
+
problem i.e. given a list of items, how many boxes
|
19
|
+
do you need to fit them all in taking into account
|
20
|
+
physical dimensions and weights.
|
21
|
+
It also allow to declare items that are not stackables
|
22
|
+
nor invertibles (ie. you need to pack fragile items).
|
23
|
+
}
|
24
|
+
spec.homepage = "https://github.com/deliver-ee/tetromino"
|
25
|
+
spec.license = "MIT"
|
26
|
+
|
27
|
+
# Specify which files should be added to the gem when it is released.
|
28
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
29
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
30
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
31
|
+
end
|
32
|
+
spec.bindir = "exe"
|
33
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
34
|
+
spec.require_paths = ["lib"]
|
35
|
+
|
36
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
37
|
+
spec.add_development_dependency "pry", "~> 0.11.0"
|
38
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
39
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
40
|
+
spec.add_development_dependency "simplecov", "~> 0.16.1"
|
41
|
+
end
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tetromino
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- deliver.ee
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-06-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.16'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.11.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.11.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.16.1
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.16.1
|
83
|
+
description: "\n An implementation of the \"4D\" bin packing\n
|
84
|
+
\ problem i.e. given a list of items, how many boxes\n do
|
85
|
+
you need to fit them all in taking into account\n physical
|
86
|
+
dimensions and weights.\n It also allow to declare items
|
87
|
+
that are not stackables\n nor invertibles (ie. you need to
|
88
|
+
pack fragile items).\n "
|
89
|
+
email:
|
90
|
+
- 1337@deliver.ee
|
91
|
+
executables: []
|
92
|
+
extensions: []
|
93
|
+
extra_rdoc_files: []
|
94
|
+
files:
|
95
|
+
- ".gitignore"
|
96
|
+
- ".rspec"
|
97
|
+
- ".travis.yml"
|
98
|
+
- Gemfile
|
99
|
+
- Gemfile.lock
|
100
|
+
- LICENSE.txt
|
101
|
+
- README.md
|
102
|
+
- Rakefile
|
103
|
+
- bin/console
|
104
|
+
- bin/setup
|
105
|
+
- lib/tetromino.rb
|
106
|
+
- lib/tetromino/args.rb
|
107
|
+
- lib/tetromino/box.rb
|
108
|
+
- lib/tetromino/exceptions.rb
|
109
|
+
- lib/tetromino/item.rb
|
110
|
+
- lib/tetromino/packer.rb
|
111
|
+
- lib/tetromino/packing.rb
|
112
|
+
- lib/tetromino/placement.rb
|
113
|
+
- lib/tetromino/space.rb
|
114
|
+
- lib/tetromino/version.rb
|
115
|
+
- tetromino.gemspec
|
116
|
+
homepage: https://github.com/deliver-ee/tetromino
|
117
|
+
licenses:
|
118
|
+
- MIT
|
119
|
+
metadata: {}
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
requirements: []
|
135
|
+
rubyforge_project:
|
136
|
+
rubygems_version: 2.6.13
|
137
|
+
signing_key:
|
138
|
+
specification_version: 4
|
139
|
+
summary: First fit heuristic algorithm for 4D bin packing problem solver (4dbpp)
|
140
|
+
test_files: []
|