Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
165
Task/24-game-Solve/Rust/24-game-solve.rust
Normal file
165
Task/24-game-Solve/Rust/24-game-solve.rust
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
#[derive(Clone, Copy, Debug)]
|
||||
enum Operator {
|
||||
Sub,
|
||||
Plus,
|
||||
Mul,
|
||||
Div,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Factor {
|
||||
content: String,
|
||||
value: i32,
|
||||
}
|
||||
|
||||
fn apply(op: Operator, left: &[Factor], right: &[Factor]) -> Vec<Factor> {
|
||||
let mut ret = Vec::new();
|
||||
for l in left.iter() {
|
||||
for r in right.iter() {
|
||||
use Operator::*;
|
||||
ret.push(match op {
|
||||
Sub if l.value > r.value => Factor {
|
||||
content: format!("({} - {})", l.content, r.content),
|
||||
value: l.value - r.value,
|
||||
},
|
||||
Plus => Factor {
|
||||
content: format!("({} + {})", l.content, r.content),
|
||||
value: l.value + r.value,
|
||||
},
|
||||
Mul => Factor {
|
||||
content: format!("({} x {})", l.content, r.content),
|
||||
value: l.value * r.value,
|
||||
},
|
||||
Div if l.value >= r.value && r.value > 0 && l.value % r.value == 0 => Factor {
|
||||
content: format!("({} / {})", l.content, r.content),
|
||||
value: l.value / r.value,
|
||||
},
|
||||
_ => continue,
|
||||
})
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn calc(op: [Operator; 3], numbers: [i32; 4]) -> Vec<Factor> {
|
||||
fn calc(op: &[Operator], numbers: &[i32], acc: &[Factor]) -> Vec<Factor> {
|
||||
use Operator::*;
|
||||
if op.is_empty() {
|
||||
return Vec::from(acc)
|
||||
}
|
||||
let mut ret = Vec::new();
|
||||
let mono_factor = [Factor {
|
||||
content: numbers[0].to_string(),
|
||||
value: numbers[0],
|
||||
}];
|
||||
match op[0] {
|
||||
Mul => ret.extend_from_slice(&apply(op[0], acc, &mono_factor)),
|
||||
Div => {
|
||||
ret.extend_from_slice(&apply(op[0], acc, &mono_factor));
|
||||
ret.extend_from_slice(&apply(op[0], &mono_factor, acc));
|
||||
},
|
||||
Sub => {
|
||||
ret.extend_from_slice(&apply(op[0], acc, &mono_factor));
|
||||
ret.extend_from_slice(&apply(op[0], &mono_factor, acc));
|
||||
},
|
||||
Plus => ret.extend_from_slice(&apply(op[0], acc, &mono_factor)),
|
||||
}
|
||||
calc(&op[1..], &numbers[1..], &ret)
|
||||
}
|
||||
calc(&op, &numbers[1..], &[Factor { content: numbers[0].to_string(), value: numbers[0] }])
|
||||
}
|
||||
|
||||
fn solutions(numbers: [i32; 4]) -> Vec<Factor> {
|
||||
use std::collections::hash_set::HashSet;
|
||||
let mut ret = Vec::new();
|
||||
let mut hash_set = HashSet::new();
|
||||
|
||||
for ops in OpIter(0) {
|
||||
for o in orders().iter() {
|
||||
let numbers = apply_order(numbers, o);
|
||||
let r = calc(ops, numbers);
|
||||
ret.extend(r.into_iter().filter(|&Factor { value, ref content }| value == 24 && hash_set.insert(content.to_owned())))
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut numbers = Vec::new();
|
||||
if let Some(input) = std::env::args().skip(1).next() {
|
||||
for c in input.chars() {
|
||||
if let Ok(n) = c.to_string().parse() {
|
||||
numbers.push(n)
|
||||
}
|
||||
if numbers.len() == 4 {
|
||||
let numbers = [numbers[0], numbers[1], numbers[2], numbers[3]];
|
||||
let solutions = solutions(numbers);
|
||||
let len = solutions.len();
|
||||
if len == 0 {
|
||||
println!("no solution for {}, {}, {}, {}", numbers[0], numbers[1], numbers[2], numbers[3]);
|
||||
return
|
||||
}
|
||||
println!("solutions for {}, {}, {}, {}", numbers[0], numbers[1], numbers[2], numbers[3]);
|
||||
for s in solutions {
|
||||
println!("{}", s.content)
|
||||
}
|
||||
println!("{} solutions found", len);
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("empty input")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct OpIter (usize);
|
||||
|
||||
impl Iterator for OpIter {
|
||||
type Item = [Operator; 3];
|
||||
fn next(&mut self) -> Option<[Operator; 3]> {
|
||||
use Operator::*;
|
||||
const OPTIONS: [Operator; 4] = [Mul, Sub, Plus, Div];
|
||||
if self.0 >= 1 << 6 {
|
||||
return None
|
||||
}
|
||||
let f1 = OPTIONS[(self.0 & (3 << 4)) >> 4];
|
||||
let f2 = OPTIONS[(self.0 & (3 << 2)) >> 2];
|
||||
let f3 = OPTIONS[(self.0 & (3 << 0)) >> 0];
|
||||
self.0 += 1;
|
||||
Some([f1, f2, f3])
|
||||
}
|
||||
}
|
||||
|
||||
fn orders() -> [[usize; 4]; 24] {
|
||||
[
|
||||
[0, 1, 2, 3],
|
||||
[0, 1, 3, 2],
|
||||
[0, 2, 1, 3],
|
||||
[0, 2, 3, 1],
|
||||
[0, 3, 1, 2],
|
||||
[0, 3, 2, 1],
|
||||
[1, 0, 2, 3],
|
||||
[1, 0, 3, 2],
|
||||
[1, 2, 0, 3],
|
||||
[1, 2, 3, 0],
|
||||
[1, 3, 0, 2],
|
||||
[1, 3, 2, 0],
|
||||
[2, 0, 1, 3],
|
||||
[2, 0, 3, 1],
|
||||
[2, 1, 0, 3],
|
||||
[2, 1, 3, 0],
|
||||
[2, 3, 0, 1],
|
||||
[2, 3, 1, 0],
|
||||
[3, 0, 1, 2],
|
||||
[3, 0, 2, 1],
|
||||
[3, 1, 0, 2],
|
||||
[3, 1, 2, 0],
|
||||
[3, 2, 0, 1],
|
||||
[3, 2, 1, 0]
|
||||
]
|
||||
}
|
||||
|
||||
fn apply_order(numbers: [i32; 4], order: &[usize; 4]) -> [i32; 4] {
|
||||
[numbers[order[0]], numbers[order[1]], numbers[order[2]], numbers[order[3]]]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue