///|
pub suberror SolveError {
Invalid(String)
BudgetExhausted
} derive(Debug)
///|
/// allowed[tile][direction], directions east, south, west, north.
pub(all) struct Model {
labels : Array[String]
allowed : Array[Array[Int]]
} derive(Debug)
///|
pub struct Solution {
width : Int
height : Int
tiles : Array[Int]
decisions : Int
backtracks : Int
} derive(Debug, Eq, ToJson)
///|
/// Legacy integer-mask model adapter; use RuleModel for more than 30 tiles.
pub fn solve(
model : Model,
width : Int,
height : Int,
seed? : UInt = 1U,
pins? : Array[(Int, Int)] = [],
budget? : Int = 1000000,
weights? : Array[Int] = [],
periodic? : Bool = false,
) -> Solution? raise SolveError {
solve_rules(
model.to_rules(weights~),
width,
height,
seed~,
pins~,
budget~,
periodic~,
)
}
///|
pub fn Solution::render(
self : Solution,
model : Model,
) -> String raise SolveError {
if self.width < 1 ||
self.height < 1 ||
self.width > 65536 ||
self.height > 65536 ||
self.width.to_int64() * self.height.to_int64() > 65536L ||
self.tiles.length() != self.width * self.height {
raise Invalid("invalid solution dimensions")
}
let rows = []
for y in 0..= model.labels.length() {
raise Invalid("invalid solution tile")
}
row += model.labels[tile]
}
rows.push(row)
}
rows.join("\n")
}