Skip to content

Commit

Permalink
0.1.1
Browse files Browse the repository at this point in the history
super mode
  • Loading branch information
JieningYu committed Dec 26, 2022
1 parent 8105bb0 commit 5fb89e2
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 51 deletions.
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ notice like this when it starts in an interactive mode:
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
The hypothetical commands `show w' and`show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

Expand All @@ -671,4 +671,4 @@ into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
<https://www.gnu.org/licenses/why-not-lgpl.html>.
12 changes: 11 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ This is a simple 24 points solver written in rust.

`+, -, *, /`

Operators that will be supported in the future:
With super mode:

`>>, <<, ^, &`

## Usage Commands

### Toggle super mode

`super`

### Exit

`exit`, `quit`
43 changes: 37 additions & 6 deletions src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl SimpleComponent {
number1,
number2,
op,
} => format!("({} {} {})", number1, op, number2),
} => format!("({} {} {})", number1, map_op_string(op), number2),
}
}
}
Expand All @@ -75,7 +75,7 @@ impl PartialEq for SimpleComponent {
op: op2,
},
) => {
if op1 == op2 && op1 == &'/' {
if op1 == op2 && is_op_ordered(op1) {
return n11 == n21 && n12 == n22;
}
math::compare_arr(&[n11, n12], &[n21, n22]) && op1 == op2
Expand Down Expand Up @@ -171,7 +171,12 @@ impl Component {
number1,
number2,
op,
} => format!("({} {} {})", number1.to_string(), op, number2.to_string()),
} => format!(
"({} {} {})",
number1.to_string(),
map_op_string(op),
number2.to_string()
),
}
}
}
Expand All @@ -192,7 +197,7 @@ impl PartialEq for Component {
op: op2,
},
) => {
if op1 == op2 && op1 == &'/' {
if op1 == op2 && is_op_ordered(op1) {
return n11 == n21 && n12 == n22;
}
math::compare_arr(&[n11, n12], &[n21, n22]) && op1 == op2
Expand Down Expand Up @@ -257,15 +262,15 @@ impl Expression {
format!(
"{} {} {}",
self.component1.to_string(),
self.op,
map_op_string(&self.op),
self.component2.to_string()
)
}
}

impl PartialEq for Expression {
fn eq(&self, other: &Self) -> bool {
if self.op == other.op && self.op == '/' {
if self.op == other.op && is_op_ordered(&self.op) {
return self.component1.eq(&other.component1) && self.component2.eq(&other.component2);
}
math::compare_arr(
Expand Down Expand Up @@ -303,6 +308,32 @@ fn solve_simple(number1: &f64, number2: &f64, op: &char) -> Option<f64> {
Some(number1 / number2)
}
}
'^' => Some((*number1 as i32 ^ *number2 as i32).into()),
'&' => Some((*number1 as i32 & *number2 as i32).into()),
'|' => Some((*number1 as i32 | *number2 as i32).into()),
'>' => match (*number1 as u32).checked_shr(*number2 as u32) {
Some(n) => Some(n.into()),
None => None,
}
'<' => match (*number1 as u32).checked_shl(*number2 as u32) {
Some(n) => Some(n.into()),
None => None,
}
_ => None,
}
}

fn is_op_ordered(op: &char) -> bool {
match op {
'<' | '>' | '/' => true,
_ => false,
}
}

fn map_op_string(op: &char) -> String {
match op {
'>' => String::from(">>"),
'<' => String::from("<<"),
_ => op.to_string(),
}
}
98 changes: 56 additions & 42 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,48 @@
pub mod base;
pub mod math;

use std::process;

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

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

fn main() {
println!("Enter 4 numbers and split them using spaces, or use 'exit' 'quit' to quit: ");
println!("Enter 4 numbers and split them using spaces.");

let mut super_mode = false;

loop {
let input = input_string();
if input == "exit" || input == "quit" {
break;
}
if input == "super" {
super_mode = if super_mode { false } else { true };
println!("Super mode {}", if super_mode {"enabled"} else {"disabled"});
continue;
}
let mut numbers: Vec<i32> = input
.split_whitespace()
.map(|s| s.parse().unwrap())
.collect();
let mut exit = false;
let msg = "Invalid input, please enter 4 numbers between 1 and 13";
for i in numbers.iter() {
if *i < 1 || *i > 13 {
println!("{}", msg);
exit = true;
break;
process::exit(1);
}
}
if numbers.len() != 4 {
println!("{}", msg);
exit = true;
}
if exit {
continue;
process::exit(1);
}

numbers.sort();

let solutions = solve(&numbers);
let solutions = solve(&numbers, &super_mode, &16);

if solutions.len() == 0 {
println!("No solutions found");
Expand All @@ -51,7 +56,7 @@ fn main() {
}
}

fn solve(numbers_raw: &Vec<i32>) -> Vec<Expression> {
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 {
Expand All @@ -60,48 +65,57 @@ fn solve(numbers_raw: &Vec<i32>) -> Vec<Expression> {
temp
};
let mut solutions: Vec<Expression> = Vec::new();
let operators = ['+', '-', '*', '/'];
let mut operators = ['+', '-', '*', '/'].to_vec();
if *super_mode {
operators.append(&mut ['^', '>', '<', '|', '&'].to_vec());
}
for item in permute(nums) {
for operator in operators {
for operator1 in operators {
for operator2 in operators {
push_if_absent(
&mut solutions,
Expression::create(
Component::create(item[0], operator1, item[1]),
operator,
Component::create(item[2], operator2, item[3]),
),
for operator in operators.iter() {
for operator1 in operators.iter() {
for operator2 in operators.iter() {
let exp1 = Expression::create(
Component::create(item[0], *operator1, item[1]),
*operator,
Component::create(item[2], *operator2, item[3]),
);
push_if_absent(
&mut solutions,
Expression::create(
Component::of_simple(item[0]),
operator,
Component::create(
item[1],
operator1,
SimpleComponent::create(
item[2].get_num(),
operator2,
item[3].get_num(),
),
let exp2 = Expression::create(
Component::of_simple(item[0]),
*operator,
Component::create(
item[1],
*operator1,
SimpleComponent::create(
item[2].get_num(),
*operator2,
item[3].get_num(),
),
),
);
if limit <= &1 {
if is_24(&exp1) {
return vec![exp1];
}
if is_24(&exp2) {
return vec![exp2];
}
} else {
if is_24(&exp1) {
push_if_absent(&mut solutions, exp1);
}
if is_24(&exp2) {
push_if_absent(&mut solutions, exp2);
}
}

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

let mut results: Vec<Expression> = Vec::new();
for (i, _item) in solutions.iter().enumerate() {
if is_24(&solutions[i]) {
results.push(solutions[i].clone());
}
}

results
solutions
}

fn push_if_absent<T>(vec: &mut Vec<T>, item: T)
Expand Down

0 comments on commit 5fb89e2

Please sign in to comment.