///|
/// Small result helpers shared by CLI integrations.
pub struct ResultCounter {
mut accepted : Int
mut rejected : Int
}
///|
pub fn result_counter() -> ResultCounter {
{ accepted: 0, rejected: 0 }
}
///|
pub fn ResultCounter::accept(self : ResultCounter, value : Bool) -> Bool {
if value {
self.accepted += 1
} else {
self.rejected += 1
}
value
}
///|
pub fn ResultCounter::total(self : ResultCounter) -> Int {
self.accepted + self.rejected
}
///|
pub fn ResultCounter::success_rate(self : ResultCounter) -> Int {
if self.total() == 0 {
0
} else {
self.accepted * 100 / self.total()
}
}
///|
pub fn ResultCounter::passed(self : ResultCounter) -> Bool {
self.rejected == 0
}
///|
pub fn ResultCounter::describe(self : ResultCounter) -> String {
"accepted=\{self.accepted}, rejected=\{self.rejected}, rate=\{self.success_rate()}%"
}
///|
/// Count booleans.
pub fn count_true(values : Array[Bool]) -> Int {
let mut result = 0
for value in values {
if value {
result += 1
}
}
result
}
///|
pub fn count_false(values : Array[Bool]) -> Int {
values.length() - count_true(values)
}
///|
pub fn all_true(values : Array[Bool]) -> Bool {
for value in values {
if !value {
return false
}
}
true
}
///|
pub fn any_true(values : Array[Bool]) -> Bool {
for value in values {
if value {
return true
}
}
false
}
///|
pub fn boolean_signature(values : Array[Bool]) -> Int {
let mut result = 17
for value in values {
let indicator = if value { 1 } else { 0 }
result = result * 31 + indicator
}
result
}
///|
/// Convert booleans to integer indicators.
pub fn boolean_indicators(values : Array[Bool]) -> Array[Int] {
values.map(value => if value { 1 } else { 0 })
}
///|
pub fn integer_indicators(values : Array[Int], target : Int) -> Array[Int] {
values.map(value => if value == target { 1 } else { 0 })
}
///|
pub fn indicator_sum(values : Array[Int], target : Int) -> Int {
integer_sum(integer_indicators(values, target))
}
///|
pub fn indicator_rate(values : Array[Int], target : Int) -> Int {
if values.length() == 0 {
0
} else {
indicator_sum(values, target) * 100 / values.length()
}
}
///|
/// Return whether values stay inside a range.
pub fn all_in_range(values : Array[Int], lower : Int, upper : Int) -> Bool {
for value in values {
if value < lower || value > upper {
return false
}
}
true
}
///|
pub fn any_outside_range(values : Array[Int], lower : Int, upper : Int) -> Bool {
!all_in_range(values, lower, upper)
}
///|
pub fn count_in_range(values : Array[Int], lower : Int, upper : Int) -> Int {
let mut result = 0
for value in values {
if value >= lower && value <= upper {
result += 1
}
}
result
}
///|
pub fn range_completion(values : Array[Int], lower : Int, upper : Int) -> Int {
if values.length() == 0 {
0
} else {
count_in_range(values, lower, upper) * 100 / values.length()
}
}
///|
/// Return a stable pairwise equality matrix.
pub fn equality_matrix(values : Array[Int]) -> IntMatrix {
let result = int_matrix(values.length(), values.length())
for row in 0.. IntMatrix {
let result = int_matrix(values.length(), values.length())
for row in 0.. Int {
let mut result = 0
for left in 0.. Int {
let safe_penalty = if penalty < 0 { 0 } else { penalty }
completion_percent * 1000 - violations * safe_penalty
}
///|
pub fn quality_score(review : QualityReview) -> Int {
if review.passed() {
1000 - review.warning_count() * 10
} else {
-review.failure_count() * 1000
}
}
///|
pub fn bounded_quality_score(score : Int) -> Int {
fm_clamp(score, -1000, 1000)
}