use crate::cube::{Face, Move};
pub fn string_from_moves(moves: &Vec<Move>) -> String {
moves
.iter()
.map(|m| format!("{}", m))
.collect::<Vec<String>>()
.join(" ")
}
pub fn move_from_str(mv: &str) -> Option<Move> {
let chars = mv.chars().collect::<Vec<char>>();
let face = match chars.first()? {
'U' => Some(Face::U),
'D' => Some(Face::D),
'F' => Some(Face::F),
'B' => Some(Face::B),
'R' => Some(Face::R),
'L' => Some(Face::L),
_ => None,
}?;
let (turn_chars, direction) = if *chars.last()? == '\'' {
(chars.get(1..(chars.len() - 1))?, -1)
} else {
(chars.get(1..chars.len())?, 1)
};
let amount = direction
* if turn_chars.len() == 0 {
1
} else {
turn_chars.iter().collect::<String>().parse::<i32>().ok()?
};
Some(Move { face, amount })
}
pub fn moves_from_str(moves: &str) -> Vec<Move> {
moves
.split(' ')
.flat_map(|mv| move_from_str(mv))
.collect::<Vec<Move>>()
}
pub fn invert_even_primes(moves: &Vec<Move>) -> Vec<Move> {
let mut new: Vec<Move> = vec![];
for mv in moves {
new.push(if mv.amount % 2 == 0 && mv.amount < 0 {
Move {
face: mv.face,
amount: -mv.amount,
}
} else {
*mv
})
}
new
}
pub fn collect_moves_negating(moves: &Vec<Move>) -> Vec<Move> {
let mut collected: Vec<Move> = vec![];
for mv in moves {
match &mut collected[..] {
[.., a] if a.face == mv.face => {
a.amount += mv.amount;
}
[.., b, a] if a.face.opposite() == mv.face && b.face == mv.face => {
b.amount += mv.amount;
}
_ => {
collected.push(*mv);
}
}
collected.retain(|m| m.amount != 0);
}
collected
}
pub fn collect_moves(moves: &Vec<Move>) -> Vec<Move> {
let mut collected: Vec<Move> = vec![];
for mv in moves {
match &mut collected[..] {
[.., a] if a.face == mv.face && a.amount.signum() == mv.amount.signum() => {
a.amount += mv.amount;
}
[.., b, a]
if a.face.opposite() == mv.face
&& b.face == mv.face
&& b.amount.signum() == mv.amount.signum() =>
{
b.amount += mv.amount;
}
_ => {
collected.push(*mv);
}
}
}
collected
}