///|
fn state_key(remaining : Array[Int32], inventory : Array[Int32]) -> String {
let b = StringBuilder()
for n in remaining {
b.write_string(n.to_string())
b.write_string(",")
}
b.write_string("|")
for n in inventory {
b.write_string(n.to_string())
b.write_string(",")
}
b.to_string()
}
///|
fn objective_le(a : (Int32, Int32, Int32), b : (Int32, Int32, Int32)) -> Bool {
a.0 < b.0 ||
(a.0 == b.0 && a.1 < b.1) ||
(a.0 == b.0 && a.1 == b.1 && a.2 <= b.2)
}
///|
fn index_patterns(
p : Problem,
patterns : Array[Pattern],
) -> Array[Array[Pattern]] {
let result = Array::makei(p.demands.length(), _ => [])
for a in patterns {
for i, count in a.counts {
if count > 0 {
result[i].push(a)
}
}
}
for entries in result {
entries.sort_by((a, b) => {
let sa = p.stocks[a.stock]
let sb = p.stocks[b.stock]
let left = sa.cost.to_int64() * pattern_useful(p, b).to_int64()
let right = sb.cost.to_int64() * pattern_useful(p, a).to_int64()
if left != right {
left.compare(right)
} else if a.remaining != b.remaining {
a.remaining.compare(b.remaining)
} else {
a.stock.compare(b.stock)
}
})
}
result
}