110 lines
3.1 KiB
Rust
110 lines
3.1 KiB
Rust
#![feature(pattern, iter_array_chunks, round_char_boundary, iter_collect_into)]
|
|
|
|
use std::{
|
|
io::{Read, Write},
|
|
str::pattern::Pattern,
|
|
};
|
|
|
|
const BOOL_COUNT: usize = BOOLS.len();
|
|
const BOOLS: &[[&str; 2]] = &[
|
|
["false", "true"],
|
|
["False", "True"],
|
|
["FALSE", "TRUE"],
|
|
["0", "1"],
|
|
["no", "yes"],
|
|
];
|
|
|
|
fn main() -> std::io::Result<()> {
|
|
let mut input = String::new();
|
|
let mut stdin = std::io::stdin();
|
|
let mut stdout = std::io::stdout();
|
|
|
|
stdin.read_to_string(&mut input)?;
|
|
|
|
let bool_locs = find_bools(&input);
|
|
|
|
stdout.write_all(replace_bools(&mut input, bool_locs).as_bytes())
|
|
}
|
|
|
|
type BoolLocs = [[Vec<usize>; 2]; BOOL_COUNT];
|
|
|
|
// you thought [`find_bools`] was stupid? this is *so* much worse!!!
|
|
fn replace_bools(input: &str, mut bool_locs: BoolLocs) -> String {
|
|
let mut result = String::with_capacity(input.len());
|
|
let mut intermediate = input;
|
|
let mut flattened = bool_locs
|
|
.iter_mut()
|
|
.flatten()
|
|
.map(|vec| {
|
|
vec.reverse();
|
|
vec
|
|
})
|
|
.enumerate()
|
|
.collect::<Vec<_>>();
|
|
|
|
let mut smallest = || {
|
|
let min_idx = flattened
|
|
.iter()
|
|
.min_by(|va, vb| {
|
|
va.1.last()
|
|
.unwrap_or(&usize::MAX)
|
|
.cmp(vb.1.last().unwrap_or(&usize::MAX))
|
|
})?
|
|
.0;
|
|
|
|
Some((min_idx, flattened[min_idx].1.pop()?))
|
|
};
|
|
|
|
let mut input_idx = 0;
|
|
while let Some(item) = smallest() {
|
|
let (a, b) = intermediate.split_at(item.1 - input_idx);
|
|
input_idx += a.len();
|
|
result += a;
|
|
let bool_ = &BOOLS[item.0 / 2];
|
|
input_idx += bool_[item.0 % 2].len();
|
|
result += bool_[if item.0 % 2 == 0 { 1 } else { 0 }];
|
|
let (_, b) = b.split_at(bool_[item.0 % 2].len());
|
|
intermediate = b;
|
|
}
|
|
|
|
result + intermediate
|
|
}
|
|
|
|
// this is so fucking stupid
|
|
// it also would've been way easier using a regex crate lmao
|
|
fn find_bools(input: &str) -> [[Vec<usize>; 2]; BOOL_COUNT] {
|
|
let mut res = Vec::with_capacity(BOOL_COUNT);
|
|
BOOLS
|
|
.iter()
|
|
.flatten()
|
|
.map(|it| {
|
|
input
|
|
.match_indices(it)
|
|
.filter_map(|it| {
|
|
fn char_guard(c: char) -> bool {
|
|
!(c.is_alphanumeric() || c.is_contained_in("-_"))
|
|
}
|
|
|
|
let last_idx = it.0 + it.1.len();
|
|
|
|
(it.0 > 0
|
|
&& last_idx < input.len()
|
|
&& char_guard(
|
|
input[it.1.floor_char_boundary(it.0 - 1)..it.0]
|
|
.chars()
|
|
.last()?,
|
|
)
|
|
&& char_guard(
|
|
input[(last_idx)..(input.ceil_char_boundary(last_idx + 1))]
|
|
.chars()
|
|
.last()?,
|
|
))
|
|
.then_some(it.0)
|
|
})
|
|
.collect()
|
|
})
|
|
.array_chunks::<2>()
|
|
.collect_into(&mut res);
|
|
|
|
res.try_into().unwrap()
|
|
}
|