Algorithm without an array - java

I have a method that determines whether an expression equal to 24 can be made up of 4 whole array elements.
At the entrance: an array of 4 integers from 1 to 9.
On output: true (if an expression equal to 24 can be constructed from a given set) or false (if it is impossible to build such an expression from a given set).
Admissible arithmetic operators: addition, subtraction, multiplication, division, parentheses.
Example:
Input: [4, 1, 8, 7]
at the exit: true
explanation: (8 - 4) * (7 - 1) = 24
How can I do this without an array of combinations?
public static boolean canBeEqualTo24(int[] nums) {
if (nums.length < 4 || nums.length > 4) return false;
for (int num : nums) {
if (num < 1 || num > 9) return false;
}
final int RESULT = 24;
if (nums[0] + nums[1] + nums[2] + nums[3] == RESULT) return true;
if (nums[0] * nums[1] * nums[2] * nums[3] == RESULT) return true;
int[][] combinations = {
{0, 1, 2, 3},
{0, 1, 3, 2},
{0, 2, 1, 3},
{0, 2, 3, 1},
{0, 3, 2, 1},
{0, 3, 1, 2},
{1, 0, 2, 3},
{1, 0, 3, 2},
{1, 2, 0, 3},
{1, 2, 3, 0},
{1, 3, 2, 0},
{1, 3, 0, 2},
{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},
};
int i = 0;
while (i < combinations.length) {
int a = nums[combinations[i][0]];
int b = nums[combinations[i][1]];
int c = nums[combinations[i][2]];
int d = nums[combinations[i][3]];
if (a + b + c - d == RESULT) return true;
if (a + b - c - d == RESULT) return true;
if (a + b + c * d == RESULT) return true;
if (a + b * c * d == RESULT) return true;
if (a - b + c * d == RESULT) return true;
if (-a + b * c - d == RESULT) return true;
if (a * b * c - d == RESULT) return true;
if (a + b * (c + d) == RESULT) return true;
if (a - b * (c + d) == RESULT) return true;
if (a + b * (c - d) == RESULT) return true;
if (a * b * (c + d) == RESULT) return true;
if (a * b * (c - d) == RESULT) return true;
if (-a + b * (c - d) == RESULT) return true;
if (a * (b + c + d) == RESULT) return true;
if (a * (b + c - d) == RESULT) return true;
if (a * (b - c - d) == RESULT) return true;
if (-a + (b * (c + d)) == RESULT) return true;
if ((a + b) * (c + d) == RESULT) return true;
if ((a - b) * (c + d) == RESULT) return true;
if ((a - b) * (c - d) == RESULT) return true;
if ((a * b) + (c * d) == RESULT) return true;
if ((a * b) - (c * d) == RESULT) return true;
if (a * (b * c - d) == RESULT) return true;
if (a * (b * c + d) == RESULT) return true;
if (d != 0) {
if (a * b - c / d == RESULT && c % d == 0) return true;
if (a + b - c / d == RESULT && c % d == 0) return true;
if ((a * b) / d + c == RESULT && (a * b) % d == 0) return true;
if (((a + b) * c) / d == RESULT && ((a + b) * c) % d == 0) return true;
if (((a - b) * c) / d == RESULT && ((a - b) * c) % d == 0) return true;
if (((a * b) - c) / d == RESULT && ((a * b) - c) % d == 0) return true;
if (((a * d + c) * b) / d == RESULT && ((a * d + c) * b) % d == 0) return true;
if (((a * d - c) * b) / d == RESULT && ((a * d - c) * b) % d == 0) return true;
}
if (d * c != 0) {
if ((a * b) / (d * c) == RESULT && (a * b) % (d * c) == 0) return true;
}
if (c - d != 0) {
if ((a * b) / (c - d) == RESULT && (a * b) % (c - d) == 0) return true;
}
if (c + d != 0) {
if ((a * b) / (c + d) == RESULT && (a * b) % (c + d) == 0) return true;
}
if ((a * c - b) != 0) {
if ((d * c) / (a * c - b) == RESULT && (d * c) % (a * c - b) == 0) return true;
}
i++;
}
return false;
}

I have done this before, my solution worked and got me good grades. But then i found this on a website and this solution is complex and lengthy but have a more elegant and systematic approach:
import java.util.*;
public class Game24Player {
final String[] patterns = {"nnonnoo", "nnonono", "nnnoono", "nnnonoo",
"nnnnooo"};
final String ops = "+-*/^";
String solution;
List<Integer> digits;
public static void main(String[] args) {
new Game24Player().play();
}
void play() {
digits = getSolvableDigits();
Scanner in = new Scanner(System.in);
while (true) {
System.out.print("Make 24 using these digits: ");
System.out.println(digits);
System.out.println("(Enter 'q' to quit, 's' for a solution)");
System.out.print("> ");
String line = in.nextLine();
if (line.equalsIgnoreCase("q")) {
System.out.println("\nThanks for playing");
return;
}
if (line.equalsIgnoreCase("s")) {
System.out.println(solution);
digits = getSolvableDigits();
continue;
}
char[] entry = line.replaceAll("[^*+-/)(\\d]", "").toCharArray();
try {
validate(entry);
if (evaluate(infixToPostfix(entry))) {
System.out.println("\nCorrect! Want to try another? ");
digits = getSolvableDigits();
} else {
System.out.println("\nNot correct.");
}
} catch (Exception e) {
System.out.printf("%n%s Try again.%n", e.getMessage());
}
}
}
void validate(char[] input) throws Exception {
int total1 = 0, parens = 0, opsCount = 0;
for (char c : input) {
if (Character.isDigit(c))
total1 += 1 << (c - '0') * 4;
else if (c == '(')
parens++;
else if (c == ')')
parens--;
else if (ops.indexOf(c) != -1)
opsCount++;
if (parens < 0)
throw new Exception("Parentheses mismatch.");
}
if (parens != 0)
throw new Exception("Parentheses mismatch.");
if (opsCount != 3)
throw new Exception("Wrong number of operators.");
int total2 = 0;
for (int d : digits)
total2 += 1 << d * 4;
if (total1 != total2)
throw new Exception("Not the same digits.");
}
boolean evaluate(char[] line) throws Exception {
Stack<Float> s = new Stack<>();
try {
for (char c : line) {
if ('0' <= c && c <= '9')
s.push((float) c - '0');
else
s.push(applyOperator(s.pop(), s.pop(), c));
}
} catch (EmptyStackException e) {
throw new Exception("Invalid entry.");
}
return (Math.abs(24 - s.peek()) < 0.001F);
}
float applyOperator(float a, float b, char c) {
switch (c) {
case '+':
return a + b;
case '-':
return b - a;
case '*':
return a * b;
case '/':
return b / a;
default:
return Float.NaN;
}
}
List<Integer> randomDigits() {
Random r = new Random();
List<Integer> result = new ArrayList<>(4);
for (int i = 0; i < 4; i++)
result.add(r.nextInt(9) + 1);
return result;
}
List<Integer> getSolvableDigits() {
List<Integer> result;
do {
result = randomDigits();
} while (!isSolvable(result));
return result;
}
boolean isSolvable(List<Integer> digits) {
Set<List<Integer>> dPerms = new HashSet<>(4 * 3 * 2);
permute(digits, dPerms, 0);
int total = 4 * 4 * 4;
List<List<Integer>> oPerms = new ArrayList<>(total);
permuteOperators(oPerms, 4, total);
StringBuilder sb = new StringBuilder(4 + 3);
for (String pattern : patterns) {
char[] patternChars = pattern.toCharArray();
for (List<Integer> dig : dPerms) {
for (List<Integer> opr : oPerms) {
int i = 0, j = 0;
for (char c : patternChars) {
if (c == 'n')
sb.append(dig.get(i++));
else
sb.append(ops.charAt(opr.get(j++)));
}
String candidate = sb.toString();
try {
if (evaluate(candidate.toCharArray())) {
solution = postfixToInfix(candidate);
return true;
}
} catch (Exception ignored) {
}
sb.setLength(0);
}
}
}
return false;
}
String postfixToInfix(String postfix) {
class Expression {
String op, ex;
int prec = 3;
Expression(String e) {
ex = e;
}
Expression(String e1, String e2, String o) {
ex = String.format("%s %s %s", e1, o, e2);
op = o;
prec = ops.indexOf(o) / 2;
}
}
Stack<Expression> expr = new Stack<>();
for (char c : postfix.toCharArray()) {
int idx = ops.indexOf(c);
if (idx != -1) {
Expression r = expr.pop();
Expression l = expr.pop();
int opPrec = idx / 2;
if (l.prec < opPrec)
l.ex = '(' + l.ex + ')';
if (r.prec <= opPrec)
r.ex = '(' + r.ex + ')';
expr.push(new Expression(l.ex, r.ex, "" + c));
} else {
expr.push(new Expression("" + c));
}
}
return expr.peek().ex;
}
char[] infixToPostfix(char[] infix) throws Exception {
StringBuilder sb = new StringBuilder();
Stack<Integer> s = new Stack<>();
try {
for (char c : infix) {
int idx = ops.indexOf(c);
if (idx != -1) {
if (s.isEmpty())
s.push(idx);
else {
while (!s.isEmpty()) {
int prec2 = s.peek() / 2;
int prec1 = idx / 2;
if (prec2 >= prec1)
sb.append(ops.charAt(s.pop()));
else
break;
}
s.push(idx);
}
} else if (c == '(') {
s.push(-2);
} else if (c == ')') {
while (s.peek() != -2)
sb.append(ops.charAt(s.pop()));
s.pop();
} else {
sb.append(c);
}
}
while (!s.isEmpty())
sb.append(ops.charAt(s.pop()));
} catch (EmptyStackException e) {
throw new Exception("Invalid entry.");
}
return sb.toString().toCharArray();
}
void permute(List<Integer> lst, Set<List<Integer>> res, int k) {
for (int i = k; i < lst.size(); i++) {
Collections.swap(lst, i, k);
permute(lst, res, k + 1);
Collections.swap(lst, k, i);
}
if (k == lst.size())
res.add(new ArrayList<>(lst));
}
void permuteOperators(List<List<Integer>> res, int n, int total) {
for (int i = 0, npow = n * n; i < total; i++)
res.add(Arrays.asList((i / npow), (i % npow) / n, i % n));
}
}
Note: Here you can find this website. Do tell me if this works for you and always give credit to owner.
EDIT: You have to change this code a bit, because it produces random numbersand check if they can be solved to give 24 as a result, if they not then it'll produce another set of random variables and keep ding so until they produces such numbers that can be solved.
Hint: Check methods like
isSolvable()
getSolvableDigits()
randomDigits()
and edit them as you wish.

Related

Checking whether an expression is a valid formula

Recursion Question: A formula is defined as a string
containing positive single digits numbers, variables, and operations
(such that: +,-,/,*,%). In addition, the string doesn't contain space
bars. Each operation between two numbers or variables is separated
with brackets - "()".
Valid formulas would be: ((6+x)*(4+2)), (((9*4)+(x+8))*(6-5)), 6,
(3+1), etc...
Invalid formulas would be: -6, (1+*(x+2)*(1-6)), ( (6+x)), 10,
2+x, (33+3), ((1+2)), etc...
Write a boolean recursion function which gets a string - "s" and
returns true if he is a valid formula, and false otherwise.
The code has to be written via java.
My attempt: I have tried the following, putting in mind that the number of "(" is less equal to the number of ")", however, it doesn't right since: "((1+2))" isn't a valid formula. So I have written the following:
public static boolean isFormula(String s) {
return calc(s, 0, 0, 0, 0);
}
public static boolean calc(String s, int oc, int l, int r, int g) {
if (s == "") {
return (oc <= 1 && (l == r));
}
char c = s.charAt(0);
char e = s.charAt(s.length() - 1);
if (g == 0) {
if (!(op(s))) return false;
else {
return calc(s, oc, l, r, g + 1);
}
}
if (c == '(') {
return calc(s.substring(1), oc, l + 1, r, g);
} else if (c == ')') {
return calc(s.substring(1), oc, l, r + 1, g);
} else if ((c >= '0' && c <= '9') || c == 'x') {
if (oc <= 1) {
return calc(s.substring(1), 0, l, r, g);
}
} else if ((c == '+' || c == '-' || c == '*' || c == '/')) {
return calc(s.substring(1), oc + 1, l, r, g);
}
return false;
}
public static boolean op(String s) {
int count = 0;
if (s.charAt(0) == '+' || s.charAt(0) == '-' || s.charAt(0) == '*' || s.charAt(0) == '/') {
count++;
}
String d = s.replace("(", "");
if (d.charAt(0) == '+' || d.charAt(0) == '-' || d.charAt(0) == '*' || d.charAt(0) == '/') {
count++;
}
d = d.replace(")", "");
d = d.replace("+", ",");
d = d.replace("-", ",");
d = d.replace("*", ",");
d = d.replace("/", ",");
String[] words = d.split(",");
int sum = words.length;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '+' || s.charAt(i) == '-' || s.charAt(i) == '/' || s.charAt(i) == '*') {
count++;
}
}
if (s.contains(" ")) return false;
return (count <= sum - 1);
}
Thoughts:
I find this question very complex, and I don't know how to arrange the code, because it doesn't seem that my way is correct and and it is so messy. I will be glad for some help. I put a lot of effort into writing this post. Thank you!
Try this.
static final Pattern DIGIT_OR_X = Pattern.compile("[\\dx]");
static final Pattern OPERATION = Pattern.compile("\\([\\dx][+*/%-][\\dx]\\)");
public static boolean isFormula(String s) {
while (true) {
if (DIGIT_OR_X.matcher(s).matches())
return true;
String rep = OPERATION.matcher(s).replaceAll("x");
if (rep.equals(s))
return false;
s = rep;
}
}
Test cases:
assertTrue(isFormula("((6+x)*(4+2))"));
assertTrue(isFormula("(((9*4)+(x+8))*(6-5))"));
assertTrue(isFormula("6"));
assertTrue(isFormula("(3+1)"));
assertFalse(isFormula("-6"));
assertFalse(isFormula("(1+*(x+2)*(1-6))"));
assertFalse(isFormula("( (6+x))"));
assertFalse(isFormula("10"));
assertFalse(isFormula("2+x"));
assertFalse(isFormula("(33+3)"));
assertFalse(isFormula("((1+2))"));
Or you can also do it without regular expression.
static boolean isFormula(String s) {
return new Object() {
int index = 0;
boolean match(String expects) {
if (index >= s.length() || expects.indexOf(s.charAt(index)) < 0)
return false;
++index;
return true;
}
boolean formula() {
if (match("0123456789x"))
return true;
return match("(")
&& formula() && match("+-*/%") && formula()
&& match(")");
}
boolean parse() {
return formula() && index >= s.length();
}
}.parse();
}

Euler Brick imlementation in Java

Hello to all who are taking the time out of their day to attempt and help solve my problem. I am truly stuck for the first time in a while and would really appriciate some help. But enough exposition; here is the what I have implemented thus far:
public class EulerBrick {
private int a, b, c;
private int d, e, f;
private Random random;
public EulerBrick(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
this.d = (int) Math.sqrt((a * a) + (b * b));
this.e = (int) Math.sqrt((a * a) + (c * c));
this.f = (int) Math.sqrt((b * b) + (c * c));
this.random = new Random();
if (verify(a, b, c, random.nextInt())) {
if (a % 3 != 0) {
if (b % 3 != 0) return;
if (c % 3 != 0) return;
}
if (a % 4 != 0) {
if (b % 4 != 0) return;
if (c % 4 != 0) return;
}
if (a % 11 != 0) {
if (b % 11 != 0) {
if (c % 11 != 0) return;
}
}
} else return;
printDimensions();
}
public boolean verify(double a, double b, double c, int k) {
a *= k;
b *= k;
c *= k;
if (a % 3 != 0) {
if (b % 3 != 0) return false;
if (c % 3 != 0) return false;
}
if (a % 4 != 0) {
if (b % 4 != 0) return false;
if (c % 4 != 0) return false;
}
if (a % 11 != 0) {
if (b % 11 != 0) {
if (c % 11 != 0) return false;
}
}
return true;
}
public void printDimensions() {
System.out.println("Side A: " + a + ", Side B: " + b + ", Side C: " + c + ", Side D: " + d + ", Side E: " + e + ", Side F: " + f);
}
}
And here is the main class I am using to test it:
public class Main {
public static void main(String[] args) throws InterruptedException {
int i = 0, j = 0, k = 0;
while (true) {
new EulerBrick(i += 3, j += 4, k += 11);
Thread.sleep(1000);
}
// EulerBrick brick = new EulerBrick(44, 117, 240);
}
}
Again any help would be greatly appreciated. Also this isn't for a course/class just an exercise that Ive stumped myself on.

How can I program to check whether a number is a zeisel number or not?

To know more about zeisel numbers
A Zeisel number is a square-free integer k with at least three prime factors which fall into the pattern
p[x] = a*p[x-1] + b
where a and b are some integer constants and x is the index number of each prime factor in the factorization, sorted from lowest to highest. For the purpose of determining Zeisel numbers, p[0] = 1.
I have written this code below in java. This function does test for positive b but not for negative b. How can I do that?
// function to caluculate zeisel number
public static boolean zeisel(int num) {
// returning false if not squarefree
if (Math.sqrt(num) == (int) Math.sqrt(num))
return false;
int fac = 2, count = 0, str = num;
// arrray to store prime factors
int[] fact;
int a = 1, b = 0, i = 0;
// counting number of factors
while (num != 1) {
if(num % fac == 0) {
count++;
num /= fac;
}
else
fac++;
}
num = str;
fac = 2;
// storing factors in array
fact = new int[count];
while (num != 1) {
if(num % fac == 0) {
fact[i] = fac;
i++;
num /= fac;
} else
fac++;
}
if(i < 3)
return false;
// checking for zeisel equation
while(a < fact[0]) {
b = fact[0] - a;
for(i = 1; i < count; i++) {
if(fact[i] != a*fact[i -1] + b) {
break;
}
}
if(i == count) {
return true;
}
a++;
}
return false;
}
There is no need for any looping to determine the a and b factors. You have two equations in two unknowns:
p1 = a * (1) + b
p2 = a * p1 + b
Subtracting the first from the second gives:
p2 - p1 = a * (p1 - 1)
Which you can use to directly solve for a = (p2 - p1) / (p1 - 1), and assuming it is an integer, then solve for b = p1 - a.
So, after you've generated your factors in fact[] (with the corrected square-free condition), your test could be something like:
if ((fact[1] - fact[0]) % (fact[0] - 1) != 0)
return false;
int a = (fact[1] - fact[0]) / (fact[0] - 1);
int b = fact[0] - a;
for(int i=2; i<count; i++) {
if (fact[i] != a*fact[i-1] + b) {
return false;
}
}
return true;

How to print the middle digit of a number if so?

I tried a program but it shows the first digit. I want a mid digit program by using while loop.
I used the following-
public class MID {
public static void Indra(int n) {
int a = 0, c = 0, m = 0, r = 0;
a = n;
while (n != 0) {
c++;
n = n / 10;
}
n = a;
if (c % 2 == 0) {
System.out.println("No mid digit exsist!!");
} else {
m = (c + 1) / 2;
c = 0;
while (n != 0) {
c++;
r = n % 10;
if (c == r) {
System.out.println(r);
}
n = n / 10;
}
}
}
}
But it keeps on giving the same output-
The mid digit of 345 is 3
Please,help me!
If you dont mind using a different logic, you can try this..
int x = 354;
String num = Integer.toString(x);
if(num.length() % 2 != 0){
System.out.println("The mid digit of " + x + " is " + num.charAt(num.length()/2));
}else {
System.out.println("No middle number.");
}
You calculate m for the position middle digit, but you don't use it.
m = (c + 1) / 2;
for (int i = 0; i < m; i++)
n /= 10;
System.out.println(n % 10);
If you want to stick to int then use this
if (c == 1 || c % 2 == 0) {
System.out.println("No mid digit exsist!!");
}
else
{
m = c/2;
int lower = (int)(n % Math.pow(10, m));
int upper = n-((int)(n % Math.pow(10, m+1)));
r = n-(upper+lower);
while (r >= 10)
{
r = r/10;
}
System.out.println(r);
}

CodingBat : LoneSum optimization

I have completed this exercise on codingbat successfully, but I want to know is there a better/faster or more elegant solution?
Given 3 int values, a b c, returns their sum. However, if one of the values is the same as another of the values, it does not count towards the sum.
loneSum(1, 2, 3) → 6
loneSum(3, 2, 3) → 2
loneSum(3, 3, 3) → 0
public int loneSum(int a, int b, int c)
{
int sum = a + b + c;
if ( a == b) { sum = sum - a - b; }
if ( a == c) { sum = sum - a - c; }
if( b == c) { sum = sum - b - c; }
if (( a == b ) && (b==c)) { sum = 0; }
return sum;
}
Maybe this code?
public static int loneSum(int a, int b, int c) {
if (a == b && b == c) {
a = 0;
b = 0;
c = 0;
}
if (a == b) {
a = 0;
b = 0;
}
if (a == c) {
a = 0;
c = 0;
}
if (b == c) {
b = 0;
c = 0;
}
return a + b + c;
}
You can measure the time ... this seems like less sub ops so might be faster
public int loneSum(int a, int b, int c) {
int sum = 0;
boolean ab = a != b;
boolean ac = a != c;
boolean bc = b != c;
if(ab && ac) sum += a;
if(ab && bc) sum += b;
if(bc && ac) sum += c;
return sum;
}
public int loneSum(int a, int b, int c) {
if ( (a==b) && (b==c) && (c==a) ) return 0;
else
{
if (a==b) return c ;
if (b==c) return a;
if (a==c) return b;
else return a+b+c;
}
}
public int loneSum(int a, int b, int c) {
int sum = a+b+c;
if (a==b) sum -= a*2;
if (b==c) sum -= b*2;
if (c==a) sum -= c*2;
if (sum<0) sum=0;
return sum;
}
This take 4 comparisons.
Initialize sum to a+b+c
Compare numbers to each other and if same, decrease sum by num*2.
If multiple IF's are hit (meaning a==b==c), the sum becomes 0. Return 0 in that case.
if (a==b && b==c) return 0;
if (a==b) return c;
if (a==c) return b;
if (b==c) return a;
return a+b+c;
def lone_sum(a, b, c):
sum=0
if a==b==c:
sum=0
elif a==b:
sum=c
elif a==c:
sum=b
elif b==c:
sum=a
else:
sum=a+b+c
return sum
This is for python
public int loneSum(int a, int b, int c)
{
int sum = a + b + c;
if ( a == b) { sum = c; }
if ( a == c) { sum = b; }
if( b == c) { sum = a; }
if (( a == b ) && (b==c)) { sum = 0; }
return sum;
}
This is for java
I sending you another approach using ternary operators. I hope it can be useful in your exercises and learning process.
public int noTeenSum(int a, int b, int c) {
a = (a >= 13 && a <= 19) ? (a == 15 || a == 16) ? a : 0 : a;
b = (b >= 13 && b <= 19) ? (b == 15 || b == 16) ? b : 0 : b;
c = (c >= 13 && c <= 19) ? (c == 15 || c == 16) ? c : 0 : c;
return a+b+c;
}
I think this is easier to read
def lone_sum(a, b, c):
if a == b == c:
return 0
if a == b:
return c
if b == c:
return a
if a == c:
return b
else:
return a + b + c
Here's my answer:
def lone_sum(a, b, c):
if a!=b and b!=c and c!=a:
return a+b+c
elif a==b==c:
return 0
elif a==b:
return c
elif b==c:
return a
elif c==a:
return b
public int loneSum(int a, int b, int c) {
int sum = a+b+c;
if(a==b)
sum -= (a+b);
if(a==c)
sum -= (a + c);
if(b==c)
sum -= (b+c);
return sum > 0? sum: 0;
}
def lone_sum(a, b, c):
tempSum, arr2 = a+b+c, list(set([a,b,c]))
if (a==b==c): return 0
return sum(arr2) - (tempSum - sum(arr2))
Please see the below function :
def su(a,b,c):
total=0
for x in (a,b,c):
if x==(x+1):
y=0
else:
y=1
total+=x*y
return total
print(su(3,2,3))

Categories

Resources