im making a simple add and subtract binary calculator. i got it to take in a number and convert it into binary number, and i even got it to add the numbers. When i try and get it to subtract it doesnt work. i get a weird output. heres the piece of the code.
int [ ] subtarctBin = new int [16];
int carryX = 0;
for (int i = 0; i < 16; i++)
{
subtarctBin[i] = 0;
}
for (int i = 15; i >= 0; i--)
{
int subtract = resultBinA[i] - resultBinB[i] - carryX;
subtarctBin[i] = subtract % 2;
carryX = subtract / 2;
}
System.out.println("");
System.out.print("DIF:");
for(int i=0; i<16; i++)
{
System.out.print(subtarctBin[i]);
}
}
In addition to #Ken Y-N's answer, I find that in this statement, you are subtracting the first digit from the second along with the carryX.
int subtract = resultBinA[i] - resultBinB[i] - carryX;
I think you should ensure that the first number is the bigger of the two( i.e. resultBinB > resultBinA) and then the subtraction should go like this instead:
int subtract = (resultBinB[i] + carryX) - resultBinA[i];
Assuming that resultBinA and resultBinB contain the binary numbers, the problem is here:
subtarctBin[i] = subtract % 2;
According to the Java documentation, the result of the remainder operation can be negative only if the dividend is negative, and can be positive only if the dividend is positive. So, when subtract equals -1, subtract % 2 also equals -1, so subtarctBin[i] will be -1 too, which is not what you want.
Furthermore, subtract / 2 will yield 0 when subtract equals -1, as Integer division rounds toward 0, as noted here.
Now, to solve your problem, build up this table:
resultBinA resultBinB carryX subtract required subtarctBin required new carryX
0 0 0 0 0 0
0 0 1 -1 1 1
0 1 0 -1 1 1
0 1 1 -2 0 1
1 0 0 1 1 0
1 0 1 0 0 0
1 1 0 0 0 0
1 1 1 -1 1 1
So, we can see, I hope, that:
subtarctBin[i] = (subtract + 2) % 2;
carryX = (subtract < 0 ? 1 : 0);
Gives you the results you require.
Try
if ((resultBinA[i] - resultBinB[i]) < 0 ){
int k = i-1;
while (resultBinA[k] != 1){
resultBinA[k] = 1;
k--;
}
resultBinA[k] = 0;
subract = 1;
}
else{
subract = (resultBinA[i] - resultBinB[i]);
}
I can give you a small hack.
Try to write a function to subtract a binary number by 1.
Then, make another function to check if a binary number is equal to 0 (basically, if we have a String like "010100" we need to check if each character is 0).
In your main function, keep subtracting until one of your numbers is 0. Return whichever is not 0. (Or return 0 if both numbers are 0.)
public String sub(String bin2){
while(!iszero(bin1) && !iszero(bin2)){
bin1 = subby1(bin1);
bin2 = subby1(bin2);
}
if(!iszero(bin1))
return bin1;
else
return bin2;
}
private String subby1(String bin){
int index = bin.length()-1;
while(bin.charAt(index) != '1'){
index--;
}
char[] c = bin.toCharArray();
c[index] = '0';
for(int x = bin.length()-1; x >= index + 1; x--){
c[x] = '1';
}
return String.valueOf(c);
}
private boolean iszero(String bin){
for(int x = 0; x < bin.length(); x++)
if(bin.charAt(x) == '1')
return false;
return true;
}
}
Related
I am trying to work out a solution to the CodeWars challenge Catching Car Mileage Numbers:
Write the function that parses the mileage number input, and returns a 2 if the number is "interesting" (see below), a 1 if an interesting number occurs within the next two miles, or a 0 if the number is not interesting.
Interesting numbers are 3-or-more digit numbers that meet one or more of the following criteria:
Any digit followed by all zeros: 100, 90000
Every digit is the same number: 1111
The digits are sequential, incementing†: 1234
The digits are sequential, decrementing‡: 4321
The digits are a palindrome: 1221 or 73837
The digits match one of the values in the awesomePhrases array
† For incrementing sequences, 0 should come after 9, and not before 1, as in 7890.
‡ For decrementing sequences, 0 should come after 1, and not before 9, as in 3210.
I can pass all tests in the first batch, but fail to pass the second batch.
Any feedback would be very much appreciated, not only on a possible solution but also to the way I'm thinking about the exercise.
public static int isInteresting(int number, int[] awesomePhrases) {
for (int offSet = 0; offSet <= 2; offSet++) {
int testNumber = number;
testNumber += offSet;
boolean isYellow = testNumber != number;
int yellowOffset = 0;
if (isYellow) {
yellowOffset = 1;
}
//check three or more digit number
boolean greaterThan99 = testNumber > 99;
int[] numbers = Integer.toString(testNumber).chars().map(c -> c - '0').toArray();
int zeroCounter = 0;
int identicalCounter = 0;
int incrementingCounter = 0;
int decrementingCounter = 0;
int palindromeCounter = 0;
boolean endsInZero = numbers[numbers.length - 1] == 0;
for (int i = 0; i < numbers.length; i++) {
//check digit followed by zeros
if (numbers[i] == 0) {
zeroCounter++;
}
if (i + 1 < numbers.length) {
//check every digit is the same
if (numbers[i] == numbers[i + 1]) identicalCounter++;
//check ascending order
if (numbers[i + 1] - numbers[i] == 1) incrementingCounter++;
//check descending order
if (numbers[i] - numbers[i + 1] == 1) decrementingCounter++;
}
}
if (greaterThan99) {
//check awesomePhrases
for (int phrase : awesomePhrases) {
if (phrase == testNumber) return 2 - yellowOffset;
}
//check palindrome
int reversedIndex = numbers.length - 1;
for (int i = 0; i < numbers.length; i++) {
if (numbers[reversedIndex] == numbers[i]) {
palindromeCounter++;
}
reversedIndex--;
}
if (zeroCounter == numbers.length - 1) return 2 - yellowOffset;
if (identicalCounter == numbers.length - 1) return 2 - yellowOffset;
if (incrementingCounter == numbers.length - 1) return 2 - yellowOffset;
if (incrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;
if (decrementingCounter == numbers.length - 1) return 2 - yellowOffset;
if (decrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;
if (palindromeCounter == numbers.length) return 2 - yellowOffset;
}
}
return 0;
}
I've tried pretty much all I know but to no result, all the tests I try pass, would love to know what I'm doing wrong.
The problem is in how your code tests for increasing sequences that end in a zero. It is not enough to test that the sequence has n-2 increments and the last digit is a zero, because that will give a false positive on numbers like 6780. It is required that the one-but-last digit is a 9.
A similar issue exist for the decreasing sequence logic, however, there you would not need a special test for an ending zero at all. This condition is covered by counting n-1 decrements, where the ending could be a 1 followed by a zero. There is no special case to be handled here.
To fix the first problem, I would suggest you not only check whether the last digit is a zero, but whether the last two digits are 9 and 0, or in other words, that the number modulo 100 is equal to 90.
You could replace this:
boolean endsInZero = numbers[numbers.length - 1] == 0;
by this:
boolean endsInNinety = testNumber % 100 == 90;
and then replace:
if (incrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;
by:
if (incrementingCounter == numbers.length - 2 && endsInNinety) return 2 - yellowOffset;
and finally remove this test:
if (decrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;
This will fix it.
Note that it can be helpful to have your function print the input it gets, so that when a test fails, at least you can know for which input there was a problem:
System.out.println("input " + number);
This is the code I know:
bool checkPrime(int n) {
bool prime = true;
for (int i = 2; i < n; i++) {
if ((n%i) == 0) {
prime = false;
}
}
return prime;
}
But is this ok if you’re looking for prime numbers:
List<int> arr = [2, 3, 5, 7]; // Already known
int n = 30; // Between 1 to 30. It could be any number
for (int i = 2; i < n; i++) {
if (i % 2 != 0 && i % 3 != 0 && i % 5 != 0 && i % 7 != 0) {
arr.add(i);
}
// Then maybe some code for numbers less than 8
}
print(arr);
Output:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
And also is there much difference in time complexity?
Your code is incorrect.
This code only works because you are taking the value of n as 30, for a greater number like 1000 this will produce an incorrect result.
List arr = [2,3,5,7]; // already known
int n = 1000; // between 1 to 1000 it could be any number
List<int> arr = [2,3,5,7];
for (int i = 2; i < n; i++) {
if (i % 2 != 0 && i % 3 != 0 && i % 5 != 0 && i % 7 != 0){
arr.add(i);
}
//Then maybe some code for numbers less than 8
}
print(arr);
Your code will return 231 prime numbers when there are actually only 168 prime numbers.
This is because you are not considering the future prime numbers that can only be divided by a prime number between 7 to that number.
eg: 121 will be returned by you as prime but it is a multiple of 11
Extending your pattern.
Though this will be faster since it has reduced a number of division operations but due to two loops, it will still be N square.
Here I am simply only dividing numbers from the existing prime numbers collection and adding them in the collection if prime is found tobe used in next iteration for division.
List < int > arr = [2]; // taking 2 since this is the lowerst value we want to start with
int n = 30; // n can between 2 to any number
if (n < 3) {
print(arr); // can return from here.
}
// since we already have added 2 in the list we start with next number to check that is 3
for (int i = 3; i < n; i++) {
bool isPrime = true;
for (int j = 0; j < arr.length; j++) { // we iterate over the current prime number collection only [2] then [2,3]...
if (i % arr[j] == 0) { // check if number can be divided by exisiting numbers
isPrime = false;
}
}
if (isPrime) { // eg: 2 cant divide 3 so we 3 is also added
arr.add(i)
}
}
print(arr);
You can look a faster pattern here.
Which is the fastest algorithm to find prime numbers?
This is the question we were assigned :
Nine coins are placed in a 3x3 matrix with some face up and some face down. You can represent the state of the coins using a 3x3 matrix with values 0 (heads) and 1 (tails). Here are some examples:
0 0 0 1 0 1 1 1 0
0 1 0 0 0 1 1 0 0
0 0 0 1 0 0 0 0 1
Each state can also be represented using a binary number. For example, the preceding matrices correspond to the numbers:
000010000 101001100 110100001
There are a total of 512 possibilities, so you can use decimal numbers 0, 1, 2, 3,...,511 to represent all the states of the matrix.
Write a program that prompts the user to enter a number between 0 and 511 and displays the corresponding matrix with the characters H and T.
I want the method toBinary() to fill the array binaryNumbers. I realized that this does not fill in 0s to the left. I have to think that through but is that the only thing that is the problem?
//https://www.geeksforgeeks.org/java-program-for-decimal-to-binary-conversion/
import java.util.Scanner;
public class HeadsAndTails {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int num = input.nextInt();
int[] binaryNumbers = toBinary(num);
for (int i = 0; i < 9; i++) {
printArr(binaryNumbers);
System.out.print(binaryNumbers[1]);
}
}
public static int[] toBinary(int inputtedNumber) {
int[] binaryNum = new int[9];
int i = 0;
while (inputtedNumber > 0) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
inputtedNumber++;
} return binaryNum;
}
public static void printArr(int[] arr) {
for (int i = 0; i < 9; i++) {
if (arr[i] == 0) {
System.out.print("H ");
} else {
System.out.print("T ");
}
if (arr[i+1] % 3 == 0) {
System.out.println();
} System.out.print(arr[i]);
}
}
}
Looks like you are incrementing the wrong variable in your while loop:
while (inputtedNumber > 0) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
i++; // NOT inputtedNumber
} return binaryNum;
Also note, a new int[9] is probably already initialized to 0, but if not, you could just loop 9 times, rather than until the inputtedNumber is 0:
for (int i = 0; i < 9; i++) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
}
return binaryNum;
Finally, I think your array might be backwards when you're done, so you may need to reverse it or output it in reverse order
I realize this is a homework assignment so you should stick with your current approach. However, sometimes it can be fun to see what can be achieved using the built in features of Java.
The Integer class has a method toBinaryString that's a good starting point:
int n = 23;
String s1 = Integer.toBinaryString(n);
System.out.println(s1);
Output: 10111
But as we can see, this omits leading 0s. We can get these back by making sure our number has a significant digit in the 10th place, using a little bit-twiddling:
String s2 = Integer.toBinaryString(1<<9 | n);
System.out.println(s2);
Output: 1000010111
But now we have a leading 1 that we don't want. We'll strip this off using String.substring, and while we're at it we'll use String.replace to replace 0 with H and 1 with T:
String s3 = Integer.toBinaryString(1<<9 | n).substring(1).replace('0','H').replace('1','T');
System.out.println(s3);
Output: HHHHTHTTT
Now we can print this string in matrix form, again using substring to extract each line and replaceAll to insert the desired spaces:
for(int i=0; i<9; i+=3)
System.out.println(s3.substring(i, i+3).replaceAll("", " ").trim());
Output:
H H H
H T H
T T T
If we're up for a bit of regex wizardry (found here and here) we can do even better:
for(String sl : s3.split("(?<=\\G.{3})"))
System.out.println(sl.replaceAll(".(?=.)", "$0 "));
Putting it all together we get:
int n = 23;
String s3 = Integer.toBinaryString(1<<9 | n).substring(1).replace('0','H').replace('1','T');
for(String s : s3.split("(?<=\\G.{3})"))
System.out.println(s.replaceAll(".(?=.)", "$0 "));
In my code, the user enters how many numbers they want to test, and then enters the numbers. If a number can be divided by 3 distinct numbers, it prints a "1". Otherwise, it prints a "0". When I run my code, it only prints "0". I tried fixing some of the brackets to see if messed up somewhere in the syntax.
int distinct = 0;
int T = input.nextInt();
int [] nums = new int [T];
for (int n : nums) {
distinct = 0;
n = input.nextInt();
for (int m = nums.length; m == 0; m--) {
if (n % m == 0) {
distinct++;
}
}
if (distinct < 3) {
System.out.println("0");
}
else
System.out.println("1");
}
}
}
By "three distinct numbers", I mean a number like "4" which can be divided by "4, 2, and 1".
When I enter this:
3
2 3 4
It returns:
0
0
0
When it should return:
0
0
1
In the for loop, you initiate the variable with int m = nums.length.
As the length of nums is defined at the beginning by the user as 3, the first factor you check is 3 before checking all positive integers less than this. So, for n = 4 you check 3, 2 and 1; only 2 and 1 are factors so distinct will be 2. I suspect this should be int m = n;
for (int m = n; m == 0; m--) {
if (n % m == 0) {
distinct++;
}
}
Assuming you are ignoring negative integers (as this would mean negative integers could be considered), the only time this will fail is when n is 1 or n is prime; 1 and n itself will always be a factor. As such, you could ignore the check for these values.
I have two questions about this of code.
Can someone explain me, what the if statement is doing exactly. I know that count has to increment every time the test is true, but I'm not sure what the this n % i == 0 is doing.
My second question is, how can I print the return statement's answer on the console?
int n = 10;
countFactors(n);
}
public static int countFactors(int n){
int count = 0;
for (int i = 1; i <= n; i++){
if (n % i == 0) //this line
count++;
}
return count;
}
}
It count the number of divisor in your range 1-n so for example :
if n = 10 the result will be 4 because there are 4 divisor:
1
2
5
10
and about how you print in console :
for (int i = 1; i <= n; i++) {
if (n % i == 0) {
count++;
System.out.println(i);
}
}
System.out.println("Number or disivor = " + count);
You can learn here : Table of divisors
Well, as the name of the method suggests, the count represents the number of divisors that n has.
The if statement tests the following: Is n divisible by i?. in other words: Is n/i a whole number?
if you were to use:
if(n%i == 1)
instead, then it would count the numbers for which: n/i has a remainder of 1.
in order to print the return statement, you can add this line just before the return:
public static int countFactors(int n){
int count = 0;
for (int i = 1; i <= n; i++){
if (n % i == 0)
count++;
}
System.out.println(count);//adding this
return count;
}
The % operator (known as the remainder or Modulus operator) basically divides a number by another and gives you the remainder and nothing else. For instance, if you do 4 % 2, it would give you 0 because 2 goes into 4 evenly. If you would do 4 % 3 it would give you 1 because that's the remainder of 4 / 3. Also look at this website: http://www.cafeaulait.org/course/week2/15.html
The countFactors method loops 1 to n and includes n. If you do 10 % 1, you would get 0 because one goes into 10 evenly so the count would be incremented.