How can I simplify boolean Algebra Expressions without using outside Java addons? - java

I am trying to take a Boolean algebra expression generated from another part of the project and simplify it before I output it. This Boolean expression will only include or statements due to the nature of the rest of the program.
An example would be starting with an expression like aC + bC + BC + Ab + Ac + AC + AB and ending with A + C. The lower case letters indicate not e.g. a means not A.
I have struggled for hours trying to figure this out, but every time I solve one case I ruin another. I imagine there is some recursive function for this problem but I struggled to find anything elsewhere.
Edit: To be clear, I understand how to simplify the expression on paper, I just am unable to simplify it using Java.
Thanks in advance.
public static void mutate (ArrayList<String> Final, ArrayList<String> Factored, String a){
int multiples = 0;
String holder = "";
for (int i = 0; i < Final.size(); i++){
if (Final.get(i).contains(a)){
multiples++;
if (multiples == 1)
holder = Final.get(i);
if (multiples >=2)
Factored.add(Final.get(i));
}
}
if (multiples > 1)
Factored.add(holder);
}
public static void simplify (ArrayList<String> Factored, char a, ArrayList<String> Main){
String temp = "";
int size = Factored.size();
int cnt = 0;
int cnt2 = 0;
int holder = 0;
System.out.println(Factored);
int menial = 0;
if (Factored.size() == 0)
menial = 1;
else{
for (int i = 0; i < size; i++){ //Gets rid of leading letters
if(Factored.get(i).charAt(0) == a){
temp = Factored.get(i).substring(1);
Factored.add(temp);
}
}
for (int i = 0; i < size; i++){ //Gets rid of leading letters
if(Factored.get(i).charAt(1) == a){
temp = Factored.get(i).substring(1);
Factored.add(temp);
}
}
for (int j = 0; j < size; j++){
Factored.remove(j - cnt);
cnt++;
}
for (int i = 0; i < Factored.size(); i++){ //gets rid of duplicates if they exist
for (int j = i + 1; j < Factored.size();j++)
if (Factored.get(i).equals(Factored.get(j))){
cnt2++;
if (cnt2 == 1)
holder = i;
}
}
if (cnt2 >= 1)
Factored.remove(holder);
String temp1 = "";
int size1 = Factored.size();
for (int i = 0; i < size1; i++){ //Makes it uppercase
temp1 = Factored.get(i).toUpperCase();
Factored.add(temp1);
}
int cnt3 = 0;
for (int i = 0; i <size1; i++){
Factored.remove(i-cnt3);
cnt3++;
}
int sizeOver2 = Factored.size()/2;
int holder1 = 0; int holder2 = 0;
for (int q = 0; q < sizeOver2; q++){
int cnt4 = 0;
for (int i = 0; i < Factored.size(); i++){ //gets rid of duplicates if they exist now that there are caps
for (int j = i + 1; j < Factored.size();j++)
if (Factored.get(i).equals(Factored.get(j))){
cnt4++;
if (cnt4 == 1)
holder1 = i;
holder2 = j;
}
if (cnt4 >= 1){
Factored.remove(holder1);
Factored.remove(holder2 - 1);
}
}
}
if (Factored.size() == 0)
Main.add(Character.toString(a));
else if (Factored.size() > 1)
menial = 5;
else
for (int i = 0; i < Factored.size(); i++)
Main.add(Factored.get(i));
}}
}
Edit2: I have added my code above. I apologize for the slopiness in advance, it got pretty messy towards the end. The Factored arraylist has all of the elements of the boolean expression separated E.g. the first element is aC, and the second is bC, etc. My plan was to find duplicates and try to factor them out, but after coding all of this I realized the egregious logic error. It has to be more complicated than that and at this point I'm lost in my own code.

Related

Why don't we redistribute inversely in this implementation of Radix sort of strings

I found this implementation of radix sort LSD for strings :
public static void sort(String[] input, int w) {
String[] aux = new String[input.length];
//ascii chars
int R = 256;
int n = input.length;
for(int d = w-1; d >= 0; d--) {
int[] count = new int[R+1];
//update the frequency at i+1 index
for(int i=0; i<n; i++) {
count[input[i].charAt(d) + 1] ++;
}
//transform the frequency into indices
for(int r=0; r< R; r++) {
count[r+1] += count[r];
}
//redistribute
for(int i=0; i<n; i++) {
aux[count[input[i].charAt(d)]++] = input[i];
}
for(int i=0; i<n; i++) {
input[i] = aux[i];
}
}
}
But I don't understand two things :
why here we have count[input[i].charAt(d) + 1] ++; rather than count[input[i].charAt(d)] ++; ?
why we don't redistribute the characters inversely ? I think it's way simpler (my implementation) :
public static void sort(String[] arr, int lenStr) {
int R = 256;
int len = arr.length;
String[] arrSorted = new String[len];
for (int d = lenStr - 1; d >= 0; d--) {
// frequency count of each character
int[] count = new int[R + 1];
for (int i = 0; i < len; i++) {
count[arr[i].charAt(d)]++;
}
for (int i = 1; i < count.length; i++) {
count[i] += count[i - 1];
}
for (int i = len - 1; i >= 0; i--) {
count[arr[i].charAt(d)]--;
arrSorted[count[arr[i].charAt(d)]] = arr[i];
}
for (int i = 0; i < len; i++) {
arr[i] = arrSorted[i];
}
}
}
I think most of it comes down to personal preference.
why here we have count[input[i].charAt(d) + 1] ++; rather than count[input[i].charAt(d)] ++; ?
Their count[x+1] means, after the second inner loop, how many times character x and any character prior to it appear. For example, we might have the initial counts:
count[0] = 0
count[1] = 2
count[2] = 3
Then after the second for loop we will have:
count[0] = 0
count[1] = 2
count[2] = 5
This means that character 0 takes the positions between count[0] and count[1], character 1 takes the positions between count[1] and count[2] and in general, character x takes the positions between count[x] and count[x+1] This allows them to do this:
for(int i=0; i<n; i++) {
aux[count[input[i].charAt(d)]++] = input[i];
}
Which is a nice one liner that ties everything together neatly IMO, because count[x] changes to mean at what position should we next place character x in our sorted array.
Your implementation works just as well and can also be turned into a one liner:
for (int i = len - 1; i >= 0; i--) {
arrSorted[--count[arr[i].charAt(d)]] = arr[i];
}
If you think it's simpler then you can use it, I don't see any downsides (assuming you've tested it well enough). It's a pretty complex algorithm and once you understand one way of doing it, you tend to stick with it. This is just the implementation that stuck I guess. Simplicity is highly subjective here, personally I think your version is just as complex.

Making a nested for loop into a single for loop

I had an assignment to create an array of random number from 10-100.
Then I need to sout all the numbers not listed in the array.
I did the assignment with a nested for loops, to cross reference the arrays, then I changed all the found numbers in the array into -1. Finally I printed out the elements in the array that were not -1.
My professor told me that is it possible for me to do this assignment with only one for loop and there is no need to do a nested for loop. and make the computer run 10,000 times instead of just 100.
Is that possible? If so how?
Thank you.
package assignment.pkg1;
import java.util.Random;
public class Assignment1 {
static Random ran = new Random();
public static void main(String[] args) {
int[] arr = new int[100];
for (int i = 0; i < 100; i++) {
arr[i] = (ran.nextInt(90)) + 10;
}
InversingArray(arr);
}
public static void InversingArray(int[] randomArray) {
int[] fullArray = new int[100];
for (int i = 0; i < 100; i++) {
fullArray[i] = i;
}
for (int i = 0; i < 100; i++) {
for (int j = 1; j < 100; j++) {
if (randomArray[j] == fullArray[i]) {
fullArray[i] = -1;
}
}
}
System.out.println("These numbers are not in randomArray: ");
for (int i = 0; i < 100; i++) {
if (fullArray[i] != -1) {
System.out.println(fullArray[i]);
}
}
}
In your code you create an array to hold the possible values. If you think about it, the array index will always be equal to the number stored in the array.
fullArray[i] = i;
This is redundant.
What you are being asked to do is determine which numbers have been used: a boolean test. This means that you should have an array of boolean that is initially false (the default value of booleans in java) and is flipped to true when an equal integer is flipped to true.
Something like
int[] arr = new int[100];
for (int i = 0; i < 100; i++) {
arr[i] = (ran.nextInt(90)) + 10;
}
// ba starts with all false values
boolean ba[] == new boolean[90]; // note that the instructor said 10-100
for(int i=0; i<90; i++) {
ba[arr[i]] = true;
// lets assume arr[0] == 45
// ba[arr[0]] is the same as ba[45]
// ba[45] = true; will set that bucket of the boolean array to true
}
System.out.println("These numbers are not in randomArray: ");
for (int k = 0; k < 10; k++) {
System.out.println(k);
}
for (int j = 0; j < 90; j++) {
if (!ba[j]) { // shorthand for ba[j]==false
System.out.println(j+10); // The array starts at a base of 10
}
}
Be aware (probably the point of the exercise) that you are working with an array [0..90] that represents the numbers [10..100].
The nested loop currently looks like this:
for (int i = 0; i < 100; i++) {
for (int j = 1; j < 100; j++) {
if (randomArray[j] == fullArray[i]) {
fullArray[i] = -1;
}
}
}
But we know, that fullArray[i] is always the same as i.
So you can rewrite it to:
for (int j = 1; j < 100; j++) {
int i = randomArray[j];
fullArray[i] = -1;
}
Or even shorter:
for (int j = 1; j < 100; j++) {
fullArray[randomArray[j]] = -1;
}

How to get the values of an array in the following connect four test in Java? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm doing a project for my senior programming class, and I cannot seem to find a solution to the problem I'm presented with. I need to get the values of the four consecutive numbers this finds in a multidimensional array, of six rows and seven columns.
In essence, the provided code tells me if there is or isn't a consecutive four. All I need is to find the indexes of the values in the array of the four consecutive numbers.
public static boolean isConsecutiveFour(int[][] values) {
int numberOfRows = values.length;
int numberOfColumns = values[0].length;
// Check rows
for (int i = 0; i < numberOfRows; i++) {
if (isConsecutiveFour(values[i]))
return true;
}
// Check columns
for (int j = 0; j < numberOfColumns; j++) {
int[] column = new int[numberOfRows];
// Get a column into an array
for (int i = 0; i < numberOfRows; i++)
column[i] = values[i][j];
if (isConsecutiveFour(column))
return true;
}
// Check major diagonal (lower part)
for (int i = 0; i < numberOfRows - 3; i++) {
int numberOfElementsInDiagonal
= Math.min(numberOfRows - i, numberOfColumns);
int[] diagonal = new int[numberOfElementsInDiagonal];
for (int k = 0; k < numberOfElementsInDiagonal; k++)
diagonal[k] = values[k + i][k];
if (isConsecutiveFour(diagonal))
return true;
}
// Check major diagonal (upper part)
for (int j = 1; j < numberOfColumns - 3; j++) {
int numberOfElementsInDiagonal
= Math.min(numberOfColumns - j, numberOfRows);
int[] diagonal = new int[numberOfElementsInDiagonal];
for (int k = 0; k < numberOfElementsInDiagonal; k++)
diagonal[k] = values[k][k + j];
if (isConsecutiveFour(diagonal))
return true;
}
// Check sub-diagonal (left part)
for (int j = 3; j < numberOfColumns; j++) {
int numberOfElementsInDiagonal
= Math.min(j + 1, numberOfRows);
int[] diagonal = new int[numberOfElementsInDiagonal];
for (int k = 0; k < numberOfElementsInDiagonal; k++)
diagonal[k] = values[k][j - k];
if (isConsecutiveFour(diagonal))
return true;
}
// Check sub-diagonal (right part)
for (int i = 1; i < numberOfRows - 3; i++) {
int numberOfElementsInDiagonal
= Math.min(numberOfRows - i, numberOfColumns);
int[] diagonal = new int[numberOfElementsInDiagonal];
for (int k = 0; k < numberOfElementsInDiagonal; k++)
diagonal[k] = values[k + i][numberOfColumns - k - 1];
if (isConsecutiveFour(diagonal))
return true;
}
return false;
}
public static boolean isConsecutiveFour(int[] values) {
for (int i = 0; i < values.length - 3; i++) {
boolean isEqual = true;
for (int j = i; j < i + 3; j++) {
if (values[j] != values[j + 1]) {
isEqual = false;
break;
}
}
if (isEqual) return true;
}
return false;
}
}
I would like someone to at least help me by pointing me in the right direction. Any help will be greatly appreciated. Thanks :)

Can you give me idea on how to code this program using array and for loops?

I was supposed to make a program using for loop and arrays now the output program will need to show something like this
0-1-0-0-1-0-0-0-1-0-0-0-0-1
Notice that the 0 is adding every after the 1's show so far im stuck with this code can you help me please...
int[] binary = new int[150];
int b = 0;
int x = 3;
for(int a = 0; a < binary.length; a=a+2) {
box[a] =1;
}
for(int i =0; i < binary.length; i++){
for(b = 0; b < binary.length; b = b+x){
if(box[b] == 1) {
box[b] =0; // this condition changes the value of 1 to 0 if the binary is already "1".
}
else {
box[b] =1; // if the value of the binary is 0 it changes it to 1.
}
}
x++; // Putting this changes the value of the x making x=4 so that the next time the for loop runs it adds the int b to 4..(NOT SURE IF THIS IS RIGHT THOUGH)
}
for(int c =0; c < binary.length; c++) {
System.out.print(binary[c]); // "this should print the output "
}
My problem is making it show something like this
01001000100001000001
You're mixing multiple variable names, since you assign the values to box you should probably remove binary - so something like,
int[] box = new int[150];
int b = 0;
int x = 3;
for (int a = 0; a < box.length; a = a + 2) {
box[a] = 1;
}
for (int i = 0; i < box.length; i++) {
for (b = 0; b < box.length; b = b + x) {
if (box[b] == 1) {
box[b] = 0;
} else {
box[b] = 1;
}
}
x++;
}
for (int c = 0; c < box.length; c++) {
System.out.print(box[c]); // "this should print the output "
}
Output is
101101111011111101111111101111111111011111111111101111111111111101111111111111111011111111111111111101111111111111111111101111111111111111111111011111
I'm not sure to fully understand what you want. From your post I only understand that your goal is to have an output composed of 0 and 1 only and starting with a 0 immediately followed by a 1. The number of zeros following a 1 is successively increased by 1 : so you have after that 2 zeros followed by a 1 and then 3 zeros followed by a 1, 4 zeros followed by a 1 and so one : 0-1-00-1-000-1-0000-1.
Am I right ?
If that is what you want, try something like that :
int num_zero = 1;
int cptr = 0;
int[] arr = new int[20];
for(int j = 0; j < arr.length; j++){
if(cptr == num_zero){
arr[j] = 1;
num_zero = 1+ cptr;
cptr = 0;
}else{
arr[j] = 0;
++cptr;
}
}
Here is the output :
01001000100001000001
Try this:
int[] binary = new int[150];
int onesNextIndex = 1;
int onesGap = 2;
for(int i = 0; i < binary.length; i++){
if(i == onesNextIndex){
binary[i] = 1;
onesNextIndex += onesGap + 1;
onesGap++;
}else{
binary[i] = 0;
}
}
You can test it with:
for(int x : binary){
System.out.print(x);
}
it will print: 0100100010000100000100000010000000100000000..... etc
if you want it the other way around then :
int[] binary = new int[150];
int zerosNextIndex = 1;
int zerosGap = 2;
for(int i = 0; i < binary.length; i++){
if(i == zerosNextIndex){
binary[i] = 0;
zerosNextIndex += zerosGap + 1;
onesGap++;
}else{
binary[i] = 1;
}
}
this will print: 101101110111101111101111110111111101111111101111.......etc
Hope this helps

How do i complete this question with 2-dimensional array in java?

Hey guys, im working through the Introduction to Programming in Java book and one of the exercises is this:
Empirical shuffle check. Run
computational experiments to check
that our shuffling code works as
advertised. Write a program
ShuffleTest that takes command-line
arguments M and N, does N shuffles of
an array of size M that is initialized
with a[i] = i before each shuffle, and
prints an M-by-M table such that row i
gives the number of times i wound up
in position j for all j. All entries
in the array should be close to N/M.
Now, this code just outputs a block of zeros...
public class ShuffleTest2 {
public static void main(String[] args) {
int M = Integer.parseInt(args[0]);
int N = Integer.parseInt(args[1]);
int [] deck = new int [M];
for (int i = 0; i < M; ++i)
deck [i] = i;
int [][] a = new int [M][M];
for (int i = 0; i < M; i++) {
for (int j = 0; j < M; j++) {
a[i][j] = 0 ;
for(int n = 0; n < N; n++) {
int r = i + (int)(Math.random() * (M-i));
int t = deck[r];
deck[r] = deck[i];
deck[i] = t;
for (int b = 0; b < N; b++)
{
for (int c = 0; c < M; c++)
System.out.print(" " + a[b][c]);
System.out.println();
}
}
}
}
}
}
What am i doing wrong? :(
Thanks
So a is like a history? As you are now it is always filled with zeroes just like you initialized, you never assign to it! After the "shuffling" for loop you need to set
A[i][POSITION] = CARD_VALUE
Meaning that after i-th shuffle, card CARD_VALUE is in position POSITION. I don't want to give you all the specifics, but it will take another for loop, and the nested for-loop for printing needs to be independent of any other loop, occuring when everything else is done.
Looks like you have a few things concerning the for-loops that you need to look over carefully. Trace the program flow manually or with a debugger and you'll notice that some of those braces and code blocks need to be moved.
--TRY THIS--
public class ShuffleTest2 {
public static void main(String[] args) {
int M = Integer.parseInt(args[0]);
int N = Integer.parseInt(args[1]);
int [] deck = new int [M];
int [][] a = new int [M][M];
for (int i = 0; i < M; i++) { //initialize a to all zeroes
for (int j = 0; j < M; j++) {
a[i][j] = 0 ;
}
}
for(int i = 0; i < N; i++) //puts the deck in order, shuffles it, and records. N times
{
for (int j = 0; j < M; j++) //order the deck
deck[j] = j;
for(int j = 0; j < M; j++) { //shuffle the deck (same as yours except counter name)
int r = j + (int)(Math.random() * (M-j));
int t = deck[r];
deck[r] = deck[j];
deck[j] = t;
}
for(int j = 0; j < M; j++) //record status of this deck as described
{
int card_at_j = deck[j]; //value of card in position j
a[card_at_j][j]++; //tally that card_at_j occured in position j
}
} //big loop ended
for (int b = 0; b < M; b++) //print loop. a is MxM, so limit of N was wrong.
{
for (int c = 0; c < M; c++)
{
System.out.print(" " + a[b][c]);
System.out.println();
}
} //print loop ended
} //main() ended
} //class ended

Categories

Resources