Skip to content

Commit

Permalink
rafactor
Browse files Browse the repository at this point in the history
  • Loading branch information
JieningYu committed Dec 27, 2022
1 parent 648fe50 commit 6739567
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 120 deletions.
5 changes: 4 additions & 1 deletion src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ impl Debug for SimpleComponent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Number(_arg0) => f.debug_tuple("Number").field(&self.to_string()).finish(),
_ => f.debug_struct("SimpleExp").field("exp", &self.to_string()).finish(),
_ => f
.debug_struct("SimpleExp")
.field("exp", &self.to_string())
.finish(),
}
}
}
Expand Down
121 changes: 2 additions & 119 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,11 @@

pub mod base;
pub mod math;
pub mod solver;

use std::process;
use std::time::Instant;

use base::Component;
use base::Expression;

use base::SimpleComponent;
use math::permute;

fn main() {
println!("Enter 4 numbers and split them using spaces.");

Expand Down Expand Up @@ -63,7 +58,7 @@ fn main() {

numbers.sort();
let start = Instant::now();
let solutions = solve(&numbers, &super_mode, &max);
let solutions = solver::solve(&numbers, &super_mode, &max);
if solutions.len() == 0 {
println!("No solutions found");
} else {
Expand All @@ -79,118 +74,6 @@ fn main() {
}
}

fn solve(numbers_raw: &Vec<i32>, super_mode: &bool, limit: &usize) -> Vec<Expression> {
let nums = {
let mut temp = Vec::new();
for i in numbers_raw {
temp.push(SimpleComponent::Number(*i));
}
temp
};
let mut solutions: Vec<Expression> = Vec::new();
let mut operators = ['+', '-', '*', '/'].to_vec();
if *super_mode {
operators.append(&mut ['^', '>', '<', '|', '&'].to_vec());
}
for item1 in permute(nums) {
let items = if *super_mode {
math::roll_vec(item1.clone())
} else {
[item1.clone()].to_vec()
};
for operator in operators.iter() {
for operator1 in operators.iter() {
for operator2 in operators.iter() {
for item in items.iter() {
let mut exps = Vec::new();

exps.push(Expression::create(
Component::create(item[0], *operator1, item[1]),
*operator,
Component::create(item[2], *operator2, item[3]),
));
exps.push(Expression::create(
Component::of_simple(item[0]),
*operator,
Component::create(
item[1],
*operator1,
SimpleComponent::create(
item[2].get_num(),
*operator2,
item[3].get_num(),
),
),
));

exps.push(Expression::create(
Component::create(
SimpleComponent::create(
item[0].get_num(),
*operator,
item[1].get_num(),
),
*operator1,
item[2],
),
*operator2,
Component::of_simple(item[3]),
));

exps.push(Expression::create(
Component::of_simple(item[0]),
*operator,
Component::create(
item[1],
*operator1,
SimpleComponent::create(
item[2].get_num(),
*operator2,
item[3].get_num(),
),
),
));

for exp in exps {
if limit <= &1 {
if is_24(&exp) {
return vec![exp];
}
} else {
if is_24(&exp) {
push_if_absent(&mut solutions, exp);
}
}
}

if solutions.len() >= *limit {
return solutions;
}
}
}
}
}
}

solutions
}

fn push_if_absent<T>(vec: &mut Vec<T>, item: T)
where
T: PartialEq,
{
if !vec.contains(&item) {
vec.push(item);
}
}

fn is_24(expression: &Expression) -> bool {
match expression.calculate() {
Ok(n) => (n as f64 - 24.0).abs() < 0.000001,
Err(_) => false,
}
}

fn input_string() -> String {
let mut input = String::new();
std::io::stdin()
Expand Down
120 changes: 120 additions & 0 deletions src/solver.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
use base::Component;
use base::Expression;

use base::SimpleComponent;
use math::permute;

use crate::base;
use crate::math;

pub fn solve(numbers_raw: &Vec<i32>, super_mode: &bool, limit: &usize) -> Vec<Expression> {
let nums = {
let mut temp = Vec::new();
for i in numbers_raw {
temp.push(SimpleComponent::Number(*i));
}
temp
};
let mut solutions: Vec<Expression> = Vec::new();
let mut operators = ['+', '-', '*', '/'].to_vec();
if *super_mode {
operators.append(&mut ['^', '>', '<', '|', '&'].to_vec());
}
for item1 in permute(nums) {
let items = if *super_mode {
math::roll_vec(item1.clone())
} else {
[item1.clone()].to_vec()
};
for operator in operators.iter() {
for operator1 in operators.iter() {
for operator2 in operators.iter() {
for item in items.iter() {
let mut exps = Vec::new();

exps.push(Expression::create(
Component::create(item[0], *operator1, item[1]),
*operator,
Component::create(item[2], *operator2, item[3]),
));
exps.push(Expression::create(
Component::of_simple(item[0]),
*operator,
Component::create(
item[1],
*operator1,
SimpleComponent::create(
item[2].get_num(),
*operator2,
item[3].get_num(),
),
),
));

exps.push(Expression::create(
Component::create(
SimpleComponent::create(
item[0].get_num(),
*operator,
item[1].get_num(),
),
*operator1,
item[2],
),
*operator2,
Component::of_simple(item[3]),
));

exps.push(Expression::create(
Component::of_simple(item[0]),
*operator,
Component::create(
item[1],
*operator1,
SimpleComponent::create(
item[2].get_num(),
*operator2,
item[3].get_num(),
),
),
));

for exp in exps {
if limit <= &1 {
if is_24(&exp) {
return vec![exp];
}
} else {
if is_24(&exp) {
push_if_absent(&mut solutions, exp);
}
}
}

if solutions.len() >= *limit {
return solutions;
}
}
}
}
}
}

solutions
}

fn push_if_absent<T>(vec: &mut Vec<T>, item: T)
where
T: PartialEq,
{
if !vec.contains(&item) {
vec.push(item);
}
}

fn is_24(expression: &Expression) -> bool {
match expression.calculate() {
Ok(n) => (n as f64 - 24.0).abs() < 0.000001,
Err(_) => false,
}
}

0 comments on commit 6739567

Please sign in to comment.