@jetta/blocks-allocator 0.2.1-2 → 0.2.1-3
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.
- package/package.json +1 -1
- package/src/allocation_flow/leftover_catalog_retry.js +67 -0
- package/src/allocation_flow/run_allocation_iteration.js +4 -25
- package/src/space_and_block_chooser/compound_first_with_leftover_fill.js +2 -2
- package/src/space_and_block_chooser/leftover_sku_hashes.js +159 -0
- package/src/space_and_block_chooser/leftover_space_memory.js +21 -5
- package/src/space_and_block_chooser/leftover_unitary_admission.js +89 -0
- package/src/space_and_block_chooser/leftover_unitary_blocks.js +73 -98
- package/src/space_and_block_chooser/leftover_unitary_empty_spaces.js +2 -2
package/package.json
CHANGED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const leftover_unitary_blocks = require('../space_and_block_chooser/leftover_unitary_blocks')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Records a stall, unless this is the one-shot retry that admits hidden unitaries.
|
|
5
|
+
* @param {object} context
|
|
6
|
+
* @param {object[]} effective_item_list
|
|
7
|
+
* @param {Record<string, number>} amounts_before
|
|
8
|
+
* @param {object} empty_space
|
|
9
|
+
* @param {string} fingerprint
|
|
10
|
+
* @param {object[]} block_list
|
|
11
|
+
* @returns {boolean} True when any effective item amount decreased.
|
|
12
|
+
*/
|
|
13
|
+
function update_skip_state_after_attempt(
|
|
14
|
+
context,
|
|
15
|
+
effective_item_list,
|
|
16
|
+
amounts_before,
|
|
17
|
+
empty_space,
|
|
18
|
+
fingerprint,
|
|
19
|
+
block_list
|
|
20
|
+
)
|
|
21
|
+
{
|
|
22
|
+
if (amount_decreased(effective_item_list, amounts_before))
|
|
23
|
+
{
|
|
24
|
+
context.space_skip_state.clear_stalls()
|
|
25
|
+
context.recovery_state.count = 0
|
|
26
|
+
return true
|
|
27
|
+
}
|
|
28
|
+
if (defer_stall_for_hidden_unitaries(context, block_list))
|
|
29
|
+
{
|
|
30
|
+
return false
|
|
31
|
+
}
|
|
32
|
+
context.space_skip_state.record_stall(empty_space, fingerprint)
|
|
33
|
+
return false
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {object[]} effective_item_list
|
|
38
|
+
* @param {Record<string, number>} amounts_before
|
|
39
|
+
* @returns {boolean}
|
|
40
|
+
*/
|
|
41
|
+
function amount_decreased(effective_item_list, amounts_before)
|
|
42
|
+
{
|
|
43
|
+
return effective_item_list.some(item => item.get_amount() < amounts_before[item.get_id()])
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Opens the leftover catalog once when a no-progress attempt used only remembered unitaries.
|
|
48
|
+
* @param {object} context
|
|
49
|
+
* @param {object[]} block_list
|
|
50
|
+
* @returns {boolean} True when the space must be retried before it is stalled.
|
|
51
|
+
*/
|
|
52
|
+
function defer_stall_for_hidden_unitaries(context, block_list)
|
|
53
|
+
{
|
|
54
|
+
const session = context.chooser_session?.obligate_compound_session
|
|
55
|
+
const remembered_only = leftover_unitary_blocks.blocks_are_remembered_unitaries_only(
|
|
56
|
+
block_list ?? [],
|
|
57
|
+
session
|
|
58
|
+
)
|
|
59
|
+
if (!remembered_only)
|
|
60
|
+
{
|
|
61
|
+
return false
|
|
62
|
+
}
|
|
63
|
+
session.admit_non_remembered_unitaries = true
|
|
64
|
+
return true
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = { update_skip_state_after_attempt }
|
|
@@ -9,6 +9,7 @@ const {
|
|
|
9
9
|
update_item_continuation_lock
|
|
10
10
|
} = require('./item_continuation_lock_gate')
|
|
11
11
|
const { empty_space_stacks_on_tie_ratio_supporter } = require('../Allocation_Optimization/tie_ratio/tie_ratio_orientation_below_empty_space')
|
|
12
|
+
const { update_skip_state_after_attempt } = require('./leftover_catalog_retry')
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Runs one allocation iteration: chooser, LP attempt, skip-state update.
|
|
@@ -69,7 +70,8 @@ async function run_allocation_iteration(context, container, locked_item)
|
|
|
69
70
|
effective_item_list,
|
|
70
71
|
amounts_before,
|
|
71
72
|
empty_space,
|
|
72
|
-
fingerprint
|
|
73
|
+
fingerprint,
|
|
74
|
+
block_list
|
|
73
75
|
)
|
|
74
76
|
update_item_continuation_lock(context, wall_output.single_slot_allocated_item_ids)
|
|
75
77
|
context.picking_continuity.update_from_wall(wall_output.last_allocated_item_id)
|
|
@@ -117,29 +119,6 @@ function update_compound_probe_session(context, block_list, effective_item_list,
|
|
|
117
119
|
}
|
|
118
120
|
}
|
|
119
121
|
|
|
120
|
-
/**
|
|
121
|
-
* @param {object} context
|
|
122
|
-
* @param {object[]} effective_item_list
|
|
123
|
-
* @param {Record<string, number>} amounts_before
|
|
124
|
-
* @param {object} empty_space
|
|
125
|
-
* @param {string} fingerprint
|
|
126
|
-
* @returns {boolean} True when any effective item amount decreased.
|
|
127
|
-
*/
|
|
128
|
-
function update_skip_state_after_attempt(context, effective_item_list, amounts_before, empty_space, fingerprint)
|
|
129
|
-
{
|
|
130
|
-
const progressed = effective_item_list.some(
|
|
131
|
-
item => item.get_amount() < amounts_before[item.get_id()]
|
|
132
|
-
)
|
|
133
|
-
if (progressed)
|
|
134
|
-
{
|
|
135
|
-
context.space_skip_state.clear_stalls()
|
|
136
|
-
context.recovery_state.count = 0
|
|
137
|
-
return true
|
|
138
|
-
}
|
|
139
|
-
context.space_skip_state.record_stall(empty_space, fingerprint)
|
|
140
|
-
return false
|
|
141
|
-
}
|
|
142
|
-
|
|
143
122
|
/**
|
|
144
123
|
* @param {object[]} block_list
|
|
145
124
|
* @returns {void}
|
|
@@ -152,4 +131,4 @@ function assert_blocks_available(block_list)
|
|
|
152
131
|
}
|
|
153
132
|
}
|
|
154
133
|
|
|
155
|
-
module.exports = { run_allocation_iteration }
|
|
134
|
+
module.exports = { run_allocation_iteration, update_skip_state_after_attempt }
|
|
@@ -24,10 +24,10 @@ async function resolve_after_compound_probe(
|
|
|
24
24
|
)
|
|
25
25
|
{
|
|
26
26
|
const compound_block_list = compound_blocks_from_list(pre_selected_block_list)
|
|
27
|
-
const leftover_block_list = leftover_unitary_blocks(
|
|
27
|
+
const leftover_block_list = leftover_unitary_blocks.from_session(
|
|
28
28
|
pre_selected_block_list,
|
|
29
29
|
compound_block_list,
|
|
30
|
-
filter_data.obligate_compound_session
|
|
30
|
+
filter_data.obligate_compound_session
|
|
31
31
|
)
|
|
32
32
|
leftover_unitary_blocks.remember_leftover_sku_hashes(
|
|
33
33
|
filter_data.obligate_compound_session,
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
const { cube_map_function } = require('../Blocks_Preparation/Cube_Map_Function')
|
|
2
|
+
const round = require('../tools/Rounder')
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Stores leftover SKU shape hashes while compounds still remain.
|
|
6
|
+
* @param {{ leftover_sku_shape_hashes?: string[] }|undefined} session
|
|
7
|
+
* @param {object[]} leftover_block_list
|
|
8
|
+
* @param {object[]} compound_block_list
|
|
9
|
+
* @returns {void}
|
|
10
|
+
*/
|
|
11
|
+
function remember_leftover_sku_hashes(session, leftover_block_list, compound_block_list)
|
|
12
|
+
{
|
|
13
|
+
if (!session || compound_block_list.length === 0 || leftover_block_list.length === 0)
|
|
14
|
+
{
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
if (session.leftover_sku_shape_hashes?.length > 0)
|
|
18
|
+
{
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
session.leftover_sku_shape_hashes = [...leftover_sku_shape_hashes(leftover_block_list)]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Width/height/length hashes for leftover 1-slot blocks, including swapped floor axes.
|
|
26
|
+
* @param {object[]} leftover_block_list
|
|
27
|
+
* @returns {Set<string>}
|
|
28
|
+
*/
|
|
29
|
+
function leftover_sku_shape_hashes(leftover_block_list)
|
|
30
|
+
{
|
|
31
|
+
const hashes = new Set()
|
|
32
|
+
for (const block of leftover_block_list)
|
|
33
|
+
{
|
|
34
|
+
add_slot_orientation_hashes(hashes, block)
|
|
35
|
+
}
|
|
36
|
+
return hashes
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {Set<string>} hashes
|
|
41
|
+
* @param {object} block
|
|
42
|
+
* @returns {void}
|
|
43
|
+
*/
|
|
44
|
+
function add_slot_orientation_hashes(hashes, block)
|
|
45
|
+
{
|
|
46
|
+
if (typeof block.get_slot_list !== 'function')
|
|
47
|
+
{
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
const slot_list = block.get_slot_list()
|
|
51
|
+
if (slot_list.length !== 1 || typeof slot_list[0].get_width !== 'function')
|
|
52
|
+
{
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
hashes.add(cube_map_function(slot_list[0]))
|
|
56
|
+
hashes.add(swapped_length_width_hash(slot_list[0]))
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @param {object} slot
|
|
61
|
+
* @returns {string}
|
|
62
|
+
*/
|
|
63
|
+
function swapped_length_width_hash(slot)
|
|
64
|
+
{
|
|
65
|
+
return round(slot.get_length()) + ';' + round(slot.get_height()) + ';' + round(slot.get_width())
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @param {Set<string>|string[]|undefined} remembered_sku_hashes
|
|
70
|
+
* @returns {Set<string>}
|
|
71
|
+
*/
|
|
72
|
+
function to_hash_set(remembered_sku_hashes)
|
|
73
|
+
{
|
|
74
|
+
if (!remembered_sku_hashes)
|
|
75
|
+
{
|
|
76
|
+
return new Set()
|
|
77
|
+
}
|
|
78
|
+
if (remembered_sku_hashes instanceof Set)
|
|
79
|
+
{
|
|
80
|
+
return remembered_sku_hashes
|
|
81
|
+
}
|
|
82
|
+
return new Set(remembered_sku_hashes)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @param {object[]} compound_block_list
|
|
87
|
+
* @returns {Set<string>}
|
|
88
|
+
*/
|
|
89
|
+
function compound_slot_shape_hashes(compound_block_list)
|
|
90
|
+
{
|
|
91
|
+
const hashes = new Set()
|
|
92
|
+
for (const block of compound_block_list)
|
|
93
|
+
{
|
|
94
|
+
add_compound_slot_hashes(hashes, block)
|
|
95
|
+
}
|
|
96
|
+
return hashes
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @param {Set<string>} hashes
|
|
101
|
+
* @param {object} block
|
|
102
|
+
* @returns {void}
|
|
103
|
+
*/
|
|
104
|
+
function add_compound_slot_hashes(hashes, block)
|
|
105
|
+
{
|
|
106
|
+
if (typeof block.get_slot_list !== 'function')
|
|
107
|
+
{
|
|
108
|
+
return
|
|
109
|
+
}
|
|
110
|
+
for (const slot of block.get_slot_list())
|
|
111
|
+
{
|
|
112
|
+
add_measured_slot_hash(hashes, slot)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @param {Set<string>} hashes
|
|
118
|
+
* @param {object} slot
|
|
119
|
+
* @returns {void}
|
|
120
|
+
*/
|
|
121
|
+
function add_measured_slot_hash(hashes, slot)
|
|
122
|
+
{
|
|
123
|
+
if (typeof slot.get_width !== 'function')
|
|
124
|
+
{
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
hashes.add(cube_map_function(slot))
|
|
128
|
+
hashes.add(swapped_length_width_hash(slot))
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @param {object} block
|
|
133
|
+
* @param {Set<string>} remembered
|
|
134
|
+
* @returns {boolean}
|
|
135
|
+
*/
|
|
136
|
+
function is_unitary_matching_hashes(block, remembered)
|
|
137
|
+
{
|
|
138
|
+
if (typeof block.get_slot_list !== 'function')
|
|
139
|
+
{
|
|
140
|
+
return false
|
|
141
|
+
}
|
|
142
|
+
const slot_list = block.get_slot_list()
|
|
143
|
+
if (slot_list.length !== 1 || typeof slot_list[0].get_width !== 'function')
|
|
144
|
+
{
|
|
145
|
+
return false
|
|
146
|
+
}
|
|
147
|
+
return remembered.has(cube_map_function(slot_list[0]))
|
|
148
|
+
|| remembered.has(swapped_length_width_hash(slot_list[0]))
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
module.exports = {
|
|
152
|
+
remember_leftover_sku_hashes,
|
|
153
|
+
leftover_sku_shape_hashes,
|
|
154
|
+
to_hash_set,
|
|
155
|
+
compound_slot_shape_hashes,
|
|
156
|
+
is_unitary_matching_hashes,
|
|
157
|
+
cube_map_function,
|
|
158
|
+
swapped_length_width_hash
|
|
159
|
+
}
|
|
@@ -56,12 +56,10 @@ function skip_probe_or_leftover_resolution(filter_data, empty_space_list, pre_se
|
|
|
56
56
|
{
|
|
57
57
|
const session = filter_data.obligate_compound_session
|
|
58
58
|
const leftover_spaces = spaces_matching_remembered_leftover(empty_space_list, session)
|
|
59
|
-
const leftover_block_list = leftover_unitary_blocks(
|
|
59
|
+
const leftover_block_list = leftover_unitary_blocks.from_session(
|
|
60
60
|
pre_selected_block_list,
|
|
61
|
-
pre_selected_block_list
|
|
62
|
-
|
|
63
|
-
),
|
|
64
|
-
session?.leftover_sku_shape_hashes
|
|
61
|
+
compound_blocks(pre_selected_block_list),
|
|
62
|
+
session
|
|
65
63
|
)
|
|
66
64
|
if (leftover_spaces.length > 0 && leftover_block_list.length > 0)
|
|
67
65
|
{
|
|
@@ -75,6 +73,24 @@ function skip_probe_or_leftover_resolution(filter_data, empty_space_list, pre_se
|
|
|
75
73
|
return skip_probe_resolution(empty_space_list, pre_selected_block_list)
|
|
76
74
|
}
|
|
77
75
|
|
|
76
|
+
/**
|
|
77
|
+
* @param {object[]} block_list
|
|
78
|
+
* @returns {object[]}
|
|
79
|
+
*/
|
|
80
|
+
function compound_blocks(block_list)
|
|
81
|
+
{
|
|
82
|
+
return block_list.filter(is_compound_block)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @param {object} block
|
|
87
|
+
* @returns {boolean}
|
|
88
|
+
*/
|
|
89
|
+
function is_compound_block(block)
|
|
90
|
+
{
|
|
91
|
+
return typeof block.get_slot_list === 'function' && block.get_slot_list().length > 1
|
|
92
|
+
}
|
|
93
|
+
|
|
78
94
|
function space_bbox(space)
|
|
79
95
|
{
|
|
80
96
|
if (typeof space.get_x !== 'function')
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const {
|
|
2
|
+
to_hash_set,
|
|
3
|
+
is_unitary_matching_hashes
|
|
4
|
+
} = require('./leftover_sku_hashes')
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 1-slot blocks whose shape is outside the remembered leftover allow-list.
|
|
8
|
+
* @param {object[]} pre_selected_block_list
|
|
9
|
+
* @param {Set<string>|string[]} [remembered_sku_hashes]
|
|
10
|
+
* @returns {object[]}
|
|
11
|
+
*/
|
|
12
|
+
function unitaries_outside_remembered_hashes(pre_selected_block_list, remembered_sku_hashes)
|
|
13
|
+
{
|
|
14
|
+
const remembered = to_hash_set(remembered_sku_hashes)
|
|
15
|
+
return pre_selected_block_list.filter(block => is_hidden_unitary(block, remembered))
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Remembered matches plus every other 1-slot block, in pre-selected order.
|
|
20
|
+
* @param {object[]} pre_selected_block_list
|
|
21
|
+
* @param {object[]} remembered_matches
|
|
22
|
+
* @param {Set<string>|string[]|undefined} remembered_sku_hashes
|
|
23
|
+
* @returns {object[]}
|
|
24
|
+
*/
|
|
25
|
+
function unite_with_hidden_unitaries(pre_selected_block_list, remembered_matches, remembered_sku_hashes)
|
|
26
|
+
{
|
|
27
|
+
const hidden = new Set(
|
|
28
|
+
unitaries_outside_remembered_hashes(pre_selected_block_list, remembered_sku_hashes)
|
|
29
|
+
)
|
|
30
|
+
const remembered = new Set(remembered_matches)
|
|
31
|
+
return pre_selected_block_list.filter(block => remembered.has(block) || hidden.has(block))
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* True when every block is a remembered 1-slot and the one-shot release has not run.
|
|
36
|
+
* @param {object[]} block_list
|
|
37
|
+
* @param {{ leftover_sku_shape_hashes?: string[], admit_non_remembered_unitaries?: boolean }|undefined} session
|
|
38
|
+
* @returns {boolean}
|
|
39
|
+
*/
|
|
40
|
+
function blocks_are_remembered_unitaries_only(block_list, session)
|
|
41
|
+
{
|
|
42
|
+
if (!session || session.admit_non_remembered_unitaries === true || block_list.length === 0)
|
|
43
|
+
{
|
|
44
|
+
return false
|
|
45
|
+
}
|
|
46
|
+
const remembered = to_hash_set(session.leftover_sku_shape_hashes)
|
|
47
|
+
if (remembered.size === 0)
|
|
48
|
+
{
|
|
49
|
+
return false
|
|
50
|
+
}
|
|
51
|
+
return block_list.every(block => is_unitary_matching_hashes(block, remembered))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @param {object} block
|
|
56
|
+
* @param {Set<string>} remembered
|
|
57
|
+
* @returns {boolean}
|
|
58
|
+
*/
|
|
59
|
+
function is_hidden_unitary(block, remembered)
|
|
60
|
+
{
|
|
61
|
+
if (!is_single_slot_block(block))
|
|
62
|
+
{
|
|
63
|
+
return false
|
|
64
|
+
}
|
|
65
|
+
if (remembered.size === 0)
|
|
66
|
+
{
|
|
67
|
+
return true
|
|
68
|
+
}
|
|
69
|
+
return !is_unitary_matching_hashes(block, remembered)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @param {object} block
|
|
74
|
+
* @returns {boolean}
|
|
75
|
+
*/
|
|
76
|
+
function is_single_slot_block(block)
|
|
77
|
+
{
|
|
78
|
+
if (typeof block.get_slot_list !== 'function')
|
|
79
|
+
{
|
|
80
|
+
return false
|
|
81
|
+
}
|
|
82
|
+
return block.get_slot_list().length === 1
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
module.exports = {
|
|
86
|
+
unitaries_outside_remembered_hashes,
|
|
87
|
+
unite_with_hidden_unitaries,
|
|
88
|
+
blocks_are_remembered_unitaries_only
|
|
89
|
+
}
|
|
@@ -1,114 +1,90 @@
|
|
|
1
|
-
const {
|
|
2
|
-
|
|
1
|
+
const {
|
|
2
|
+
remember_leftover_sku_hashes,
|
|
3
|
+
leftover_sku_shape_hashes,
|
|
4
|
+
to_hash_set,
|
|
5
|
+
compound_slot_shape_hashes,
|
|
6
|
+
is_unitary_matching_hashes,
|
|
7
|
+
cube_map_function,
|
|
8
|
+
swapped_length_width_hash
|
|
9
|
+
} = require('./leftover_sku_hashes')
|
|
10
|
+
const {
|
|
11
|
+
unite_with_hidden_unitaries,
|
|
12
|
+
unitaries_outside_remembered_hashes,
|
|
13
|
+
blocks_are_remembered_unitaries_only
|
|
14
|
+
} = require('./leftover_unitary_admission')
|
|
3
15
|
|
|
4
16
|
/**
|
|
5
17
|
* 1-slot blocks of leftover SKUs: not used by remaining compounds, or remembered after compounds are gone.
|
|
18
|
+
* When `admit_other_unitaries` is true, other 1-slot blocks are included without changing stored hashes.
|
|
6
19
|
* @param {object[]} pre_selected_block_list
|
|
7
20
|
* @param {object[]} compound_block_list
|
|
8
21
|
* @param {Set<string>|string[]} [remembered_sku_hashes]
|
|
22
|
+
* @param {boolean} [admit_other_unitaries]
|
|
9
23
|
* @returns {object[]}
|
|
10
24
|
*/
|
|
11
|
-
function leftover_unitary_blocks(
|
|
25
|
+
function leftover_unitary_blocks(
|
|
26
|
+
pre_selected_block_list,
|
|
27
|
+
compound_block_list,
|
|
28
|
+
remembered_sku_hashes,
|
|
29
|
+
admit_other_unitaries
|
|
30
|
+
)
|
|
12
31
|
{
|
|
13
|
-
const
|
|
14
|
-
|
|
32
|
+
const remembered_matches = remembered_or_current_unitaries(
|
|
33
|
+
pre_selected_block_list,
|
|
34
|
+
compound_block_list,
|
|
35
|
+
remembered_sku_hashes
|
|
36
|
+
)
|
|
37
|
+
if (admit_other_unitaries !== true)
|
|
15
38
|
{
|
|
16
|
-
return
|
|
39
|
+
return remembered_matches
|
|
17
40
|
}
|
|
18
|
-
return
|
|
19
|
-
|
|
41
|
+
return unite_with_hidden_unitaries(
|
|
42
|
+
pre_selected_block_list,
|
|
43
|
+
remembered_matches,
|
|
44
|
+
remembered_sku_hashes
|
|
20
45
|
)
|
|
21
46
|
}
|
|
22
47
|
|
|
23
48
|
/**
|
|
24
|
-
*
|
|
25
|
-
* @param {
|
|
26
|
-
* @param {object[]} leftover_block_list
|
|
49
|
+
* Applies the session allow-list, including hidden unitaries after the one-shot release.
|
|
50
|
+
* @param {object[]} pre_selected_block_list
|
|
27
51
|
* @param {object[]} compound_block_list
|
|
52
|
+
* @param {{ leftover_sku_shape_hashes?: string[], admit_non_remembered_unitaries?: boolean }|undefined} session
|
|
53
|
+
* @returns {object[]}
|
|
28
54
|
*/
|
|
29
|
-
function
|
|
55
|
+
function leftover_unitary_blocks_from_session(pre_selected_block_list, compound_block_list, session)
|
|
30
56
|
{
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return
|
|
38
|
-
}
|
|
39
|
-
session.leftover_sku_shape_hashes = [...leftover_sku_shape_hashes(leftover_block_list)]
|
|
57
|
+
return leftover_unitary_blocks(
|
|
58
|
+
pre_selected_block_list,
|
|
59
|
+
compound_block_list,
|
|
60
|
+
session?.leftover_sku_shape_hashes,
|
|
61
|
+
session?.admit_non_remembered_unitaries === true
|
|
62
|
+
)
|
|
40
63
|
}
|
|
41
64
|
|
|
42
65
|
/**
|
|
43
|
-
*
|
|
44
|
-
* @param {object[]}
|
|
45
|
-
* @
|
|
66
|
+
* @param {object[]} pre_selected_block_list
|
|
67
|
+
* @param {object[]} compound_block_list
|
|
68
|
+
* @param {Set<string>|string[]|undefined} remembered_sku_hashes
|
|
69
|
+
* @returns {object[]}
|
|
46
70
|
*/
|
|
47
|
-
function
|
|
48
|
-
{
|
|
49
|
-
const hashes = new Set()
|
|
50
|
-
for (const block of leftover_block_list)
|
|
51
|
-
{
|
|
52
|
-
add_slot_orientation_hashes(hashes, block)
|
|
53
|
-
}
|
|
54
|
-
return hashes
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function add_slot_orientation_hashes(hashes, block)
|
|
58
|
-
{
|
|
59
|
-
if (typeof block.get_slot_list !== 'function')
|
|
60
|
-
{
|
|
61
|
-
return
|
|
62
|
-
}
|
|
63
|
-
const slot_list = block.get_slot_list()
|
|
64
|
-
if (slot_list.length !== 1 || typeof slot_list[0].get_width !== 'function')
|
|
65
|
-
{
|
|
66
|
-
return
|
|
67
|
-
}
|
|
68
|
-
hashes.add(cube_map_function(slot_list[0]))
|
|
69
|
-
hashes.add(swapped_length_width_hash(slot_list[0]))
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function swapped_length_width_hash(slot)
|
|
73
|
-
{
|
|
74
|
-
return round(slot.get_length()) + ';' + round(slot.get_height()) + ';' + round(slot.get_width())
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function to_hash_set(remembered_sku_hashes)
|
|
71
|
+
function remembered_or_current_unitaries(pre_selected_block_list, compound_block_list, remembered_sku_hashes)
|
|
78
72
|
{
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return new Set()
|
|
82
|
-
}
|
|
83
|
-
if (remembered_sku_hashes instanceof Set)
|
|
84
|
-
{
|
|
85
|
-
return remembered_sku_hashes
|
|
86
|
-
}
|
|
87
|
-
return new Set(remembered_sku_hashes)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function compound_slot_shape_hashes(compound_block_list)
|
|
91
|
-
{
|
|
92
|
-
const hashes = new Set()
|
|
93
|
-
for (const block of compound_block_list)
|
|
73
|
+
const remembered = to_hash_set(remembered_sku_hashes)
|
|
74
|
+
if (remembered.size > 0)
|
|
94
75
|
{
|
|
95
|
-
|
|
96
|
-
{
|
|
97
|
-
continue
|
|
98
|
-
}
|
|
99
|
-
for (const slot of block.get_slot_list())
|
|
100
|
-
{
|
|
101
|
-
if (typeof slot.get_width !== 'function')
|
|
102
|
-
{
|
|
103
|
-
continue
|
|
104
|
-
}
|
|
105
|
-
hashes.add(cube_map_function(slot))
|
|
106
|
-
hashes.add(swapped_length_width_hash(slot))
|
|
107
|
-
}
|
|
76
|
+
return pre_selected_block_list.filter(block => is_unitary_matching_hashes(block, remembered))
|
|
108
77
|
}
|
|
109
|
-
return
|
|
78
|
+
return pre_selected_block_list.filter(
|
|
79
|
+
block => is_leftover_unitary_block(block, compound_slot_shape_hashes(compound_block_list))
|
|
80
|
+
)
|
|
110
81
|
}
|
|
111
82
|
|
|
83
|
+
/**
|
|
84
|
+
* @param {object} block
|
|
85
|
+
* @param {Set<string>} compound_slot_hashes
|
|
86
|
+
* @returns {boolean}
|
|
87
|
+
*/
|
|
112
88
|
function is_leftover_unitary_block(block, compound_slot_hashes)
|
|
113
89
|
{
|
|
114
90
|
if (typeof block.get_slot_list !== 'function')
|
|
@@ -128,26 +104,25 @@ function is_leftover_unitary_block(block, compound_slot_hashes)
|
|
|
128
104
|
{
|
|
129
105
|
return true
|
|
130
106
|
}
|
|
131
|
-
return
|
|
132
|
-
&& !compound_slot_hashes.has(swapped_length_width_hash(slot_list[0]))
|
|
107
|
+
return slot_shape_is_absent(slot_list[0], compound_slot_hashes)
|
|
133
108
|
}
|
|
134
109
|
|
|
135
|
-
|
|
110
|
+
/**
|
|
111
|
+
* @param {object} slot
|
|
112
|
+
* @param {Set<string>} compound_slot_hashes
|
|
113
|
+
* @returns {boolean}
|
|
114
|
+
*/
|
|
115
|
+
function slot_shape_is_absent(slot, compound_slot_hashes)
|
|
136
116
|
{
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
const slot_list = block.get_slot_list()
|
|
142
|
-
if (slot_list.length !== 1 || typeof slot_list[0].get_width !== 'function')
|
|
143
|
-
{
|
|
144
|
-
return false
|
|
145
|
-
}
|
|
146
|
-
return remembered.has(cube_map_function(slot_list[0]))
|
|
147
|
-
|| remembered.has(swapped_length_width_hash(slot_list[0]))
|
|
117
|
+
const matches_cube = compound_slot_hashes.has(cube_map_function(slot))
|
|
118
|
+
const matches_swap = compound_slot_hashes.has(swapped_length_width_hash(slot))
|
|
119
|
+
return !matches_cube && !matches_swap
|
|
148
120
|
}
|
|
149
121
|
|
|
150
122
|
leftover_unitary_blocks.remember_leftover_sku_hashes = remember_leftover_sku_hashes
|
|
151
123
|
leftover_unitary_blocks.leftover_sku_shape_hashes = leftover_sku_shape_hashes
|
|
124
|
+
leftover_unitary_blocks.from_session = leftover_unitary_blocks_from_session
|
|
125
|
+
leftover_unitary_blocks.unitaries_outside_remembered_hashes = unitaries_outside_remembered_hashes
|
|
126
|
+
leftover_unitary_blocks.blocks_are_remembered_unitaries_only = blocks_are_remembered_unitaries_only
|
|
152
127
|
|
|
153
128
|
module.exports = leftover_unitary_blocks
|
|
@@ -119,10 +119,10 @@ function resolve_compound_first_or_leftover(
|
|
|
119
119
|
empty_space_list,
|
|
120
120
|
pre_selected_block_list,
|
|
121
121
|
leftover_empty_spaces,
|
|
122
|
-
leftover_unitary_blocks(
|
|
122
|
+
leftover_unitary_blocks.from_session(
|
|
123
123
|
pre_selected_block_list,
|
|
124
124
|
compound_block_list,
|
|
125
|
-
filter_data.obligate_compound_session
|
|
125
|
+
filter_data.obligate_compound_session
|
|
126
126
|
)
|
|
127
127
|
)
|
|
128
128
|
}
|