I am not understanding how recursive backtracking works. We did this example in class, but I don't understand why it backtracks when it is always adding 1 to level or i. Why don't we have to subtract at some point to actually go back through the array? Also, why do 2 recursive calls work, and not produce some kind of error?
public class Subsets {
public static void main(String[] args) {
int[] arr = {3,7,12};
printSubsets(arr);
}
public static void printSubsets(int[] a) {
boolean[] inSet = new boolean[a.length];
printSubsets(a, inSet, 0);
}
public static void printSubsets(int[] a, boolean[] inSet, int level) {
if(level == a.length) {
System.out.print("{");
int i = 0;
while(i < inSet.length && !inSet[i]) {
i++;
}
if(i < inSet.length) {
System.out.print(a[i]);
i++;
for(; i < inSet.length; i++) {
if(inSet[i])
System.out.print(", " + a[i]);
}
}
System.out.print("}");
System.out.println();
}
else {
//System.out.println(level + " " + inSet[level] + " ");
inSet[level] = false;
printSubsets(a, inSet, level+1);
inSet[level] = true;
printSubsets(a, inSet, level+1);
}
}
}
Related
This program is a Domino memory game where you flip dominos until you make a correct guess where the correct dominos are supposed to stay revealed. However the problem is that while the game does work correctly the dominos do not stay revealed nor does the game end.
This is the code for my Domino Class
`
public class Domino {
private int top, bottom;
private boolean revealed;
public Domino(int x, int y) {
if (x > y) {
top = y;
bottom = x;
} else {
top = x;
bottom = y;
}
}
public int getTop() {
return top;
}
public int getBottom() {
return bottom;
}
public boolean isRevealed() {
if (revealed)
return true;
return false;
}
public void setRevealed(boolean revealed) {
this.revealed = revealed;
}
public boolean equals(Domino other) {
if (top == bottom)
return true;
return false;
}
}
`
Then here is the memory game class (called MemoryLane)
`
import java.util.Arrays;
import java.util.Random;
public class MemoryLane
{
private Domino[] board;
public MemoryLane(int max)
{
board = new Domino[(max * max) + max];
int i = 0;
for(int top = 1; top <= max; top++)
for(int bot = 1; bot <= max; bot++)
{
// make new Domino(2x) +
// save into array
if(top <= bot)
{
board[i] = new Domino(top, bot);
i++;
board[i] = new Domino(top, bot);
i++;
}
}
shuffle();
}
private void shuffle()
{
int index;
Random random = new Random();
for (int i = board.length - 1; i > 0; i--)
{
index = random.nextInt(i + 1);
if (index != i)
{
Domino temp = board[index];
board[index] = board[i];
board[i] = temp;
}
}
}
public boolean guess(int i, int k)
{
if(board[i] == board[k])
{
return true;
}
return false;
}
public String peek(int a, int b)
{
String text = new String();
text += ("[" + board[a].getTop()+ "] [" + board[b].getTop()+ "]\n");
text += ("[" + board[a].getBottom()+ "] [" + board[b].getBottom()+ "]\n");
return text;
}
public boolean gameOver() {
int count = 0;
for(int i=0; i< board.length; i++)
{
if(board[i].isRevealed())
count ++;
}
return (count == board.length);
}
public String toString() {
String text = new String();
for(int i=0; i< board.length; i++)
{
if(board[i].isRevealed())
text += ("[" + board[i].getTop()+ "] ");
else
text += ("[ ] ");
}
text += ('\n');
for(int i=0; i< board.length; i++)
{
if(board[i].isRevealed())
text += ("[" + board[i].getBottom()+ "] ");
else
text += ("[ ] ");
}
return text;
}
}
`
Then here is the driver (the driver was provided to me by a third party so it must work as it is presented and cannot be changed)
`
import java.util.Scanner;
public class MemoryLaneDriver
{
public static void main(String[] args)
{
String message = "Welcome to Memory Lane!" + "\n" +
"Choose two indexes to reveal the corresponding dominoes." + "\n" +
"If the dominoes match, they stay revealed." + "\n" +
"Reveal all the dominoes to win the game!" + "\n";
System.out.println(message);
Scanner input = new Scanner(System.in);
MemoryLane game = new MemoryLane(2);
long start = System.currentTimeMillis();
while(!game.gameOver())
{
System.out.println(game);
System.out.print("First: ");
int first = input.nextInt();
System.out.print("Second: ");
int second = input.nextInt();
game.guess(first, second);
System.out.println(game.peek(first, second) + "\n");
}
long stop = System.currentTimeMillis();
long elapsed = (stop - start) / 1000;
System.out.println(game);
System.out.println("\nYou win!");
System.out.println("Total time: " + elapsed + "s");
}
}
`
I have tried using the methods in Domino like setRevealed and isRevealed in the guess method (for example when i try board.setRevealed = true or board.isRevealed = true), but it wont work and turns up red in IntelliJ. I can also not use any Stringbuilder uses (such as append) because it is outside of what has been covered in class.
When I say the game is working correctly, I mean that it outputs my choices like:
`
Welcome to Memory Lane!
Choose two indexes to reveal the corresponding dominoes.
If the dominoes match, they stay revealed.
Reveal all the dominoes to win the game!
[ ] [ ] [ ] [ ] [ ] [ ]
[ ] [ ] [ ] [ ] [ ] [ ]
First: 1
Second: 3
[2] [2]
[2] [2]
[ ] [ ] [ ] [ ] [ ] [ ]
[ ] [ ] [ ] [ ] [ ] [ ]
First:
`
However as you can see it is not revealing the correct guess, and even if I guess all of the Dominos correctly the game does not end.
So, in your original code, you were using board[i] == board[k] which is comparing memory address locations and not the object properties, instead, you should be using board[i].equals(board[k]).
In this case you need to override equals method of the Domino class in order to change how the comparison works, for example...
#Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + this.getTop();
hash = 59 * hash + this.getBottom();
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Domino)) {
return false;
}
final Domino other = (Domino) obj;
if (this.getTop() != other.getTop()) {
return false;
}
if (this.getBottom() != other.getBottom()) {
return false;
}
return true;
}
It's important to remember, if you override equals you should also override hashCode as they have an important relationship to each other.
You also never call setRevealed, which I guess should be done in guess
public boolean guess(int i, int k) {
if (board[i].equals(board[k])) {
board[i].setRevealed(true);
board[k].setRevealed(true);
return true;
}
return false;
}
Runnable example...
import java.util.Random;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
new Main();
}
Main() {
String message = "Welcome to Memory Lane!" + "\n"
+ "Choose two indexes to reveal the corresponding dominoes." + "\n"
+ "If the dominoes match, they stay revealed." + "\n"
+ "Reveal all the dominoes to win the game!" + "\n";
System.out.println(message);
Scanner input = new Scanner(System.in);
MemoryLane game = new MemoryLane(2);
long start = System.currentTimeMillis();
while (!game.gameOver()) {
// This is just making it easier to cheat.
System.out.println(game.debug());
System.out.println(game);
System.out.print("First: ");
int first = input.nextInt();
System.out.print("Second: ");
int second = input.nextInt();
game.guess(first, second);
System.out.println(game.peek(first, second) + "\n");
}
long stop = System.currentTimeMillis();
long elapsed = (stop - start) / 1000;
System.out.println(game);
System.out.println("\nYou win!");
System.out.println("Total time: " + elapsed + "s");
}
public class Domino {
private int top, bottom;
private boolean revealed;
public Domino(int x, int y) {
if (x > y) {
top = y;
bottom = x;
} else {
top = x;
bottom = y;
}
}
public int getTop() {
return top;
}
public int getBottom() {
return bottom;
}
public boolean isRevealed() {
return revealed;
}
public void setRevealed(boolean revealed) {
this.revealed = revealed;
}
#Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + this.getTop();
hash = 59 * hash + this.getBottom();
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Domino)) {
return false;
}
final Domino other = (Domino) obj;
if (this.getTop() != other.getTop()) {
return false;
}
if (this.getBottom() != other.getBottom()) {
return false;
}
return true;
}
}
public class MemoryLane {
private Domino[] board;
public MemoryLane(int max) {
board = new Domino[(max * max) + max];
int i = 0;
for (int top = 1; top <= max; top++) {
for (int bot = 1; bot <= max; bot++) {
// make new Domino(2x) +
// save into array
if (top <= bot) {
board[i] = new Domino(top, bot);
i++;
board[i] = new Domino(top, bot);
i++;
}
}
}
shuffle();
}
private void shuffle() {
int index;
Random random = new Random();
for (int i = board.length - 1; i > 0; i--) {
index = random.nextInt(i + 1);
if (index != i) {
Domino temp = board[index];
board[index] = board[i];
board[i] = temp;
}
}
}
public boolean guess(int i, int k) {
if (board[i].equals(board[k])) {
board[i].setRevealed(true);
board[k].setRevealed(true);
return true;
}
return false;
}
public String peek(int a, int b) {
String text = new String();
text += ("[" + board[a].getTop() + "] [" + board[b].getTop() + "]\n");
text += ("[" + board[a].getBottom() + "] [" + board[b].getBottom() + "]\n");
return text;
}
public boolean gameOver() {
int count = 0;
for (int i = 0; i < board.length; i++) {
if (board[i].isRevealed()) {
count++;
}
}
return (count == board.length);
}
public String debug() {
String text = new String();
for (int i = 0; i < board.length; i++) {
text += ("[" + board[i].getTop() + "] ");
}
text += ('\n');
for (int i = 0; i < board.length; i++) {
text += ("[" + board[i].getBottom() + "] ");
}
return text;
}
public String toString() {
String text = new String();
for (int i = 0; i < board.length; i++) {
if (board[i].isRevealed()) {
text += ("[" + board[i].getTop() + "] ");
} else {
text += ("[ ] ");
}
}
text += ('\n');
for (int i = 0; i < board.length; i++) {
if (board[i].isRevealed()) {
text += ("[" + board[i].getBottom() + "] ");
} else {
text += ("[ ] ");
}
}
return text;
}
}
}
I figured it out
The problem was my equals method was comparing top to bottom which is why i was getting such weird results. I changed it to
public boolean equals(Domino other){
return this.top == other.top && this.bottom == other.bottom
}
and now it works perfectly fine thanks for all of the help guys!
This is the code I atempted with the guide of external video which didnt cover expected output in terms of formatting
public class Lab3Class {
public static void main(String[] args) {
// TODO Auto-generated method stub
int table = 1;
while(table<10) {
int i = 1;
while(i<=10)
{
System.out.println(table+ " * "+i+" = "+(table*i));
i++;
}
System.out.println(" ");
table++;
}
}
}
You are just missing a check for even numbers i.e. if (table % 2 == 0).
public class Main {
public static void main(String[] args) {
int table = 1;
while (table < 10) {
if (table % 2 == 0) {
int i = 1;
while (i <= 10) {
System.out.println(table + " * " + i + " = " + (table * i));
i++;
}
}
System.out.println();
table++;
}
}
}
Alternatively, you can start table with 2 and increment it by 2 in each iteration as follows:
public class Main {
public static void main(String[] args) {
int table = 2;
while (table < 10) {
int i = 1;
while (i <= 10) {
System.out.println(table + " * " + i + " = " + (table * i));
i++;
}
System.out.println();
table += 2;
}
}
}
If you need to print it in a tabular structure, you can write the loops as follows:
public class Main {
public static void main(String[] args) {
for (int line = 1; line <= 10; line++) {
for (int i = 2; i <= 10; i += 2) {
System.out.print(i + "*" + line + "=" + (i * line) + "\t");
}
System.out.println();
}
}
}
Output:
2*1=2 4*1=4 6*1=6 8*1=8 10*1=10
2*2=4 4*2=8 6*2=12 8*2=16 10*2=20
2*3=6 4*3=12 6*3=18 8*3=24 10*3=30
2*4=8 4*4=16 6*4=24 8*4=32 10*4=40
2*5=10 4*5=20 6*5=30 8*5=40 10*5=50
2*6=12 4*6=24 6*6=36 8*6=48 10*6=60
2*7=14 4*7=28 6*7=42 8*7=56 10*7=70
2*8=16 4*8=32 6*8=48 8*8=64 10*8=80
2*9=18 4*9=36 6*9=54 8*9=72 10*9=90
2*10=20 4*10=40 6*10=60 8*10=80 10*10=100
As you can see, it looks cleaner by using a for loop. However, I recommend you also practice it with a while loop. Once you gain more confidence, I also recommend you use String::format or System.out.printf for better formatting.
This is a very small data set but if the dataset is huge, you can improve the performance by reducing the I/O operation. For this, you can append the result to a StringBuilder and print it just once at the end.
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
for (int line = 1; line <= 10; line++) {
for (int i = 2; i <= 10; i += 2) {
sb.append(i).append('*').append(line).append('=').append(i * line).append('\t');
}
sb.append('\n');
}
System.out.println(sb);
}
}
Something in the main function is wrong, but I don't know what. If I go through the code with a debugger I can see that my code isn't even reaching the fibonacci function right now.
public class Fibonacci {
public static void main(String[] args) {
for (int n=1; n<50; n++) {
System.out.println("Element "+ n + " of the sequence: " + newFib(n));
}
}
public static ArrayList<BigInteger> memo = new ArrayList<BigInteger>();
static BigInteger newFib(int n){
assert n >= 1: "the fibonacci sequence starts at 1";
BigInteger result=BigInteger.valueOf(1);
if (memo.get(n) != null) {
return memo.get(n);
}
else if( n == 1 || n == 2 ) {
memo.add(n, BigInteger.valueOf(1));
return BigInteger.valueOf(1);
}
else {
result= newFib(n-1).add(newFib(n-2));
memo.add(n,result);
return result;
}
}
}
Your code was throwing some exceptions. You simply needed to debug the exceptions and implement the proper checks. Using the code with these changes should work as intended:
import java.math.*;
import java.util.ArrayList;
public class Fibonacci {
public static void main(String[] args) {
for (int n=1; n<50; n++) {
System.out.println("Element "+ n + " of the sequence: " + newFib(n));
}
}
public static ArrayList<BigInteger> memo = new ArrayList<BigInteger>();
static BigInteger newFib(int n){
assert n >= 1: "the fibonacci sequence starts at 1";
BigInteger result=BigInteger.valueOf(1);
if (memo.size() - 1 >= n && memo.get(n) != null) {
return memo.get(n);
}
else if( n == 1 || n == 2 ) {
memo.add(n-1, BigInteger.valueOf(1));
return BigInteger.valueOf(1);
}
else {
result= newFib(n-1).add(newFib(n-2));
memo.add(n,result);
return result;
}
}
}
Your current code does not handle out of bounds correctly and as I mentioned in the comments, the fibonacci sequence does not necessarily start at one and the logic can be simplified. I would use a HashMap<Integer, BigInteger> for storing the memoization and I would also prefer to populate the initial constants once (and as constants). For example,
private static Map<Integer, BigInteger> memo = new HashMap<>();
static {
memo.put(0, BigInteger.ZERO);
memo.put(1, BigInteger.ONE);
}
static BigInteger newFib(int n) {
if (!memo.containsKey(n)) {
if (n < 0) {
memo.put(n, newFib(n + 2).subtract(newFib(n + 1)));
} else {
memo.put(n, newFib(n - 2).add(newFib(n - 1)));
}
}
return memo.get(n);
}
Which can then be tested like
public static void main(String[] args) {
for (int i = -8; i < 9; i++) {
if (i != -8) {
System.out.print(" ");
}
System.out.printf("%-5s", String.format("F(%d)", i));
}
System.out.println();
for (int i = -8; i < 9; i++) {
if (i != -8) {
System.out.print(" ");
}
System.out.printf("%-5s", newFib(i));
}
}
To reproduce the example given in the Fibonacci number Wikipedia entry.
F(-8) F(-7) F(-6) F(-5) F(-4) F(-3) F(-2) F(-1) F(0) F(1) F(2) F(3) F(4) F(5) F(6) F(7) F(8)
-21 13 -8 5 -3 2 -1 1 0 1 1 2 3 5 8 13 21
I am using Comb Sort to sort out a given array of Strings. The code is :-
public static int combSort(String[] input_array) {
int gap = input_array.length;
double shrink = 1.3;
int numbOfComparisons = 0;
boolean swapped=true;
//while(!swapped && gap>1){
System.out.println();
while(!(swapped && gap==1)){
gap = (int)(gap/shrink);
if(gap<1){
gap=1;
}
int i = 0;
swapped = false;
String temp = "";
while((i+gap) < input_array.length){
numbOfComparisons++;
if(Compare(input_array[i], input_array[i+gap]) == 1){
temp = input_array[i];
input_array[i] = input_array[i+gap];
input_array[i+gap] = temp;
swapped = true;
System.out.println("gap: " + gap + " i: " + i);
ArrayUtilities.printArray(input_array);
}
i++;
}
}
ArrayUtilities.printArray(input_array);
return numbOfComparisons;
}
The problem is that while it sorts many arrays , it gets stuck in an infinite loop for some arrays, particularly small arrays. Compare(input_array[i], input_array[i+gap]) is a small method that returns 1 if s1>s2, returns -1 if s1
try this version. The string array is changed to integer array (I guess you can change it back to string version). The constant 1.3 is replaced with 1.247330950103979.
public class CombSort
{
private static final int PROBLEM_SIZE = 5;
static int[] in = new int[PROBLEM_SIZE];
public static void printArr()
{
for(int i=0;i<in.length;i++)
{
System.out.print(in[i] + "\t");
}
System.out.println();
}
public static void combSort()
{
int swap, i, gap=PROBLEM_SIZE;
boolean swapped = false;
printArr();
while ((gap > 1) || swapped)
{
if (gap > 1)
{
gap = (int)( gap / 1.247330950103979);
}
swapped = false;
for (i = 0; gap + i < PROBLEM_SIZE; ++i)
{
if (in[i] - in[i + gap] > 0)
{
swap = in[i];
in[i] = in[i + gap];
in[i + gap] = swap;
swapped = true;
}
}
}
printArr();
}
public static void main(String[] args)
{
for(int i=0;i<in.length;i++)
{
in[i] = (int) (Math.random()*PROBLEM_SIZE);
}
combSort();
}
}
Please find below implementation for comb sort in java.
public static void combSort(int[] elements) {
float shrinkFactor = 1.3f;
int postion = (int) (elements.length/shrinkFactor);
do {
int cursor = postion;
for(int i=0;cursor<elements.length;i++,cursor++) {
if(elements[i]>elements[cursor]) {
int temp = elements[cursor];
elements[cursor] = elements[i];
elements[i] = temp;
}
}
postion = (int) (postion/shrinkFactor);
}while(postion>=1);
}
Please review and let me know your's feedback.
I am trying to make a calculator that performs the quadratic formula.
Currently if my result would be a decimal it returns NaN. (EDIT: Resolved)
Preferably I would like the result to be in an simplified radical form (i.e. √(99) = 3√(11) ).
How would I go about achieving this?
This is what I have so far.
// Do the math
private double mathCalcPlus(double varA,double varB,double varC) {
return ((-varB + Math.sqrt(varB * varB - 4 * varA * varC)) / 2 * varA);
}
private double mathCalcMinus(double varA,double varB,double varC) {
return ((-varB - Math.sqrt(varB * varB - 4 * varA * varC)) / 2 * varA);
}
Any help will be greatly appreciated.
This works great! However, I decided to add the top bar of the radical sign just for fun :D
import java.util.Scanner;
public class Radical {
public static void main(String[] args) {
System.out.print("Enter the unsimplified radical: ");
Scanner scan = new Scanner(System.in);
int input = scan.nextInt();
recurse(input);
}
public static void recurse(int x) {
System.out.println(" ______");
System.out.println("Attempting to simplify -/" + x);
int a = 0;
int b = 0;
int count = 0;
for (int i = 1; i < x; i++) {
if ((i * (x/i)) == x) {
//System.out.println(i + "<i rest>" + (x/i));
a = i;
b = x/i;
if (Math.sqrt(a)%1==0) {
if (a != 1) {
System.out.println(" ______");
System.out.println(" " + (int)Math.sqrt(a) + "-/" + b);
count = 1;
}
}
}
}
if (count>0) {
recurse(b);
} else if (count==0) {
System.out.println(" ______");
System.out.println("Cannot simplify -/" + x);
}
}
}
Here's something that might help as far as simplifying radicals go. Give it the unsimplified radical (let's say 850) and it should return the correct answer (5-/34). It also tries to recursively simplify what's left in the radical in case it needs to be broken down again.
This was written quickly so I'm sure there are edge cases I missed that will throw off the calculations but I hope it helps at least a little. Best of luck!
import java.util.Scanner;
public class Radical {
public static void main(String[] args) {
System.out.print("Enter the unsimplified radical: ");
Scanner scan = new Scanner(System.in);
int input = scan.nextInt();
recurse(input);
}
public static void recurse(int x) {
System.out.println("Attempting to simplify -/" + x);
int a = 0;
int b = 0;
int count = 0;
for (int i = 1; i < x; i++) {
if ((i * (x/i)) == x) {
//System.out.println(i + "<i rest>" + (x/i));
a = i;
b = x/i;
if (Math.sqrt(a)%1==0) {
if (a != 1) {
System.out.println((int)Math.sqrt(a) + "-/" + b);
count = 1;
}
}
}
}
if (count>0) {
recurse(b);
} else if (count==0) {
System.out.println("Cannot simplify -/" + x);
}
}
}