Gate XOR logic in java - java

folks... the XOR Gate is still giving me a hard time. I'm really close to finishing it but some of the test cases are failing. My specs say that if I have more than two of 1 (High Signals) such as:
111100 or 111 or 11 or 00 or 0000 so the output should be 0 (Low Signal).
Else if any input signal is 'X' the output is also X such as
XX00111 or XX10 or 0X01 then the output should also be X
Else if all the input signals are known (no X signals) and there is EXACTLY one 1 signal then the output is 1 such as
000001 or 10000 or 01 or 10 then the output should be 1
Note: All of the getters and setter methods are correct (tested) and Signal.HI ==1, Signal.LO = 0 and Signal.X = X.
Could smb help me with this method? When the inputs signals are 011 the output should be 0 when Im getting 1. Secondly, when the inputs are XX Im getting 0 when it should be X. Could smb please hint me or help me? Thanks in advance!
#Override
public boolean propagate()
{
Signal inputSignal;
int countHI = 0;
List<Wire> inputs = getInputs();
Signal temp = getOutput().getSignal();
for(int i = 0; i < inputs.size(); i++)
{
inputSignal = inputs.get(i).getSignal();
if(inputSignal == Signal.X)
{
getOutput().setSignal(Signal.X);
break;
}
else if(inputSignal == Signal.HI)
countHI++;
else if(inputSignal == Signal.LO)
getOutput().setSignal(Signal.HI);
}
if(countHI > 2 || countHI == 0)
getOutput().setSignal(Signal.LO);
....................................further unnecessary code for this problem

Here is what is happening:
When you are detecting an input signal of X, you are setting the output as X, and breaking out of the loop... but the last IF statement is still being executed, and so because your input is 'XX', countHI is zero, and so the last if condition is satisfied and you end up overriding the output signal by setting it to 0 at the end of your code. The break only breaks out of the loop it is currently in.
Your code only checks if hiCount is greater than 2 in the last if statement, but you expect it to be false when there are two or more 1's, so when you have exactly two 1's, you do not enter that if condition.
You need to think about your solution logically and run through it yourself and then you will realize why it is not working as you expect.

Here's how I would code it. Note that I only set the signal when I'm sure that it's the correct value: after the loop.
Also note that I make all the cases mutually exclusive.
boolean hasX = false;
boolean hiCount = 0;
for (Wire wire : inputs) {
Signal inputSignal = wire.getSignal();
if (inputSignal == Signal.X) {
hasX = true;
// optimization: break out of the loop early since we know
// that, whatever the number of HI and LO, if there is one
// X, the result is X
break;
}
else if (inputSignal == Signal.HI)
hiCount++;
}
}
if (hasX) {
getOutput().setSignal(Signal.X);
}
else if (hiCount == 1) {
getOutput().setSignal(Signal.HI);
}
else {
getOutput().setSignal(Signal.LO);
}

Related

Weird thing happens in a for loop, java

I'm fairly new to programming and I started to write some basic codes. I tried to create an algorithm that found every position of the character you wanted in a string. If I were to enter "helllo" as a string and wanted to search for the character l, it would output 2, 3 and 4. The code worked fine until I tried to trick the code a bit to change something. To do so, I first removed the termination condition in the "for loop" and instead added an if statement during the loop to break it. I spent about 2h on the error that occurred after and I still can't find out what's happening.
Here's the code and the output it gives me. (I know my code is a mess and not properly optimized, but right now I would just like to know what is happening. I'll rearrange it later if I get it to work. thank you^-^.)
When I run the code, instead of displaying as it should, "7, 8, 9, 10"(it searches for the character ^ in the string Oioriew^^^^) it outputs "7-1,8,9,10". To fix it, I can simply insert the termination condition in the loop again, which was, "pow != -1" but at this point, I really want to know why it happens.
public class Tests {
static void zeMethod(String mainString,char charToFind) {
int a = 0;
String b, c;
char chartToConvert;
c = "";
b = "";
for (int pow = mainString.indexOf(charToFind);
; // *the condition was here.*
pow = mainString.indexOf(charToFind, pow + 1)) {
a++;
if (a == 1){
System.out.println("String: "+mainString);
System.out.println("il y a un "+charToFind+" à la/aux position(s)");
}
if (a == 1){
System.out.print(pow);
}
if (a%2 == 0 && pow != -1) {
c = b+", "+pow;
}
if (a%2 != 0 && a != 1 && pow != -1) {
b = c+", "+pow;
}
if (pow == -1){
System.out.print(pow);
break;
}
//*end of loop*
}
if (a%2 != 0){
System.out.println(c);
}
else {
System.out.println(b);
}
}
public static void main(String[] args){
String string = "Oioriew^^^^";
char chara = '^';
zeMethod(string, chara);
}
}
I'm sorry if my question is a bit incoherent or not properly asked. This is my first time on the site and English isn't my mother language. Thank you for your time!
Edit:
I know the question wasn't clear at first, but what I meant is, why does pow become -1 after the second iteration of the loop. Also, why does the break after the System.out.print(pow); doesn't make it leave the loop. (I'm looking how to make a debugger work atm too.)
[...] instead of displaying as it should, "7, 8, 9, 10" [...] it outputs "7-1,8,9,10 [...] I really want to know why it happens
Sounds like you're asking why it prints -1, which happens because you explicitly asked it to:
if (pow == -1){
System.out.print(pow);
break;
}
If pow is -1 then print pow (aka -1) and exit the loop.
UPDATE
As for why the order of the output, use a debugger and step through the code one statement at a time, and you'll see.
But, lets see: We can agree that loop will iterate with pow having these numbers in this order: 7, 8, 9, 10, -1
Why does it print 7 first?
Because you have this code inside the loop:
a++;
if (a == 1){
System.out.print(pow);
}
Why does it print -1 next?
Because there are no other print statements inside the loop, which would be a lot more apparent if you indented the code correctly, i.e. indented the content of the loop.
Why does it print 8,9,10 last?
Because you print the content of b or c after the loop, and that is the content of whichever one of them is being printed.
Note that first value (-7) is not added to b, because you explicitly exclude it in the if statement.
I'm all good, thank you all for your time and Andreas, for the debugger option. It's a must-have for anyone programming. I don't know how I didn't see this earlier, but to break, it had to become -1 and since I had to break before I could print my answer, -1 was first.

1-bit and 2-bit Characters

We have two special characters. The first character can be represented by one bit 0. The second character can be represented by two bits (10 or 11).
Now given a string represented by several bits. Return whether the last character must be a one-bit character or not. The given string will always end with a zero.
Example 1:
Input:
bits = [1, 0, 0]
Output: True
Input:
bits = [1, 1, 1, 0]
Output: False
class Solution {
public boolean isOneBitCharacter(int[] bits) {
int n = bits.length-1;
int count = 0;
for(int i=n;i<=n;i--){
if(bits[i]==1){
count++;
}else break;
}return count%2==0;
}
}
this code is not working for some test cases
my 2nd example test case is not working
Try this:
public boolean isOneBitCharacter(int[] bits) {
int n = bits.length - 1;
int count = 0;
while (count < n) {
count += bits[count] + 1;
}
return count == n;
}
Explanation:
You start reading from left to right, if you encounter bits[i] == 0, it means that the next character will have 1 bit. And if bits[i] == 1 it means that the next character will have 2 bits. You keep incrementing the count to the start of each next character. In the end, if count is equals to n, it would mean that the last character is 1 bit.
For long bitstreams would be much faster to investigate the bit-stream from the end... However its a bit more harder to detect the cases. When we look at the ending bits:
.....00 // 1 bit
.....01 // error
.....10 // 1/2 bit
.....11 // 2 bit
we can determine answer right away unless the .....10 case is present in which case we need to investigate one more bit:
....110 // 1/2 bit
....010 // 2 bit
and again:
....1110 // 1/2 bit
....0110 // 1 bit
and again:
...11110 // 1/2 bit
...01110 // 2 bit
As you can see the consequent ones count determine if the last word is 1 or 2 bit (it is alternating) for odd count its 1 and for even its 2 bit word.
So simply detect which case it is and throw answe right away or count consequent ones before last zero and determine answer from that.
This way you do not need to process whole stream just the end until zero is encountered.
So:
.....11 // 2 bit or error
.....01 // error
.....00 // 1 bit
....010 // 2 bit
...0110 // 1 bit
..01110 // 2 bit
.011110 // 1 bit
0111110 // 2 bit
only in case you hit the start of stream (no zero at start) its needed to process whole array but that is improbable ... as its just a single case where the stream look like this:
111.....111X
so no or just single zero at the end but the count of ones before last bit will still tell you if the ending is 1 or 2 bits long... for that you can do:
last_word_bit_length= 1 + (consequent_ones_count&1)
I do not code in JAVA so here a C++ example instead (should not be hard to port it):
int last_word_bits(int *bits,int n)
{
int i=0;
if (n<1) return 0; // empty
if (n>=1) i|=bits[n-1];
if (n>=2) i|=bits[n-2]<<1;
if (i==1) return 0; // ...00 or ...0 -> error
if (i==0) return 1; // ...01 -> 1
if (i==3) return 2; // ...11 -> 2 or error
// count consequent ones
for (i=0,n-=2;n>=0;n--,i++)
if (bits[n]==0) break;
return 1+(i&1);
}
giving answers:
{1,0,0} -> 1
{1,1,1,0} -> 2
I am expecting bitstream does not contain errors otherwise the special case i==3 need to count the ones too... to determine if it is error or not
Given all the issues with your loop (before and after your edit), it's hard to say which code you actually tried.
Either way, your logic is wrong. You have to iterate over the "bits" the String from left to right, and keep some state variables that tell you if the last character encountered was a 1-bit or 2-bit character.
For example:
boolean started2bit = false;
boolean last1bit = false;
for(int i=0;i<bits.length;i++) {
if (started2bit) { // previous bit was the start of a 2-bit character and current
// bit (either 1 or 0) ends that character
started2bit = false;
last1bit = false;
} else if (bits[i]==1) { // 1 starts a 2-bit character
started2bit = true;
last1bit = false;
} else { // current bit is 0, and it represents a 1-bit character
last1bit = true;
}
}
return last1bit; // the last character we read was a 1-bit character
Or, even simpler, as Hans suggested:
boolean last1bit = false;
for(int i=0;i<bits.length;i++) {
if (bits[i]==1) { // 1 starts a 2-bit character
i++; // the next bit finishes a 2-bit character, so we can skip it
last1bit = false;
} else { // current bit is 0, and it represents a 1-bit character
last1bit = true;
}
}
return last1bit; // the last character we read was a 1-bit character
Python3 code based on #Spektre 's solution above. Any suggestions to improve the code are welcome.
class Solution:
def isOneBitCharacter(self, bits: List[int]) -> bool:
# if it's only 1 bit
if len(bits) == 1:
if bits[0] == 0:
return True
else:
# throwInvalidInputException
return False
# if it ends in 1 then error
if bits[-1] == 1:
# throwInvalidInputException
return False
# if it ends in 00 then True
if bits[-2:] == [0, 0]:
return True
# if it ends in 10 then ??
if bits[-2:] == [1, 0]:
i = len(bits)
while i > 0:
i -= 1
if bits[i-1:i+1] == [0, 1]: break
# in case the loop completes - need to check the first character
if bits[i-1] == 1: i -= 1
# i is now pointing to the first 1 in ....11110
if len(bits[i:]) % 2 == 1:
return True
else:
return False
This will help understand the 'ending in 10' case:
"""
Assuming no invalid input is received.
F 10
F 010
T 110
F 0010
T 0110
F 1010
F 1110
111111110 - len odd True
11111110 - len even false
"""

How to add a variable to another variable that's already set

My homework is to create a program that takes a list of numbers and prints out the highest number divisible by four.
List would look like this:
12
16
87
58
25
73
86
36
79
40
12
89
32
Input should be:
40 because it is the highest number there divisible by four.
Here is my code:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int saved = 0;
int saved2 = 0;
for (int i = scanner.nextInt(); i % 4 == 0; i = scanner.nextInt()) {
for (boolean bull = true; bull == true; bull ^= true) {
if (i > saved) {
saved -= saved2;
saved += i;
saved2 += i;
}
}
System.out.println(saved);
}
}
}
The input of my code is
12
16
I don't really understand why this is doing it, but it seems to me that I'm adding the variables wrong. The homework page on adding variables does not specify how to add variables to each other.
Does anyone have a tip to improve the code in anyway, or find a way to make a fix my code? Thank you.
welcome to Java.
First you are saying you got input, but that is output. Input is what you enter, and output is what you get printed.
Then there is a mistake in your for loops. You have too much going on in one place. By the logic which is implemented, your program will exit first level for loop whenever your entered value is not divisable by 4.
Read on for loops if you want to learn more https://www.learnjavaonline.org/en/Loops.
I recommend to start from while loops instead. The logic whould be this:
1. create variable to hold the correct answer saved
2. create another one to hold the value read from console i
3. start the while loop with condition i = scanner.nextInt()
3.1 check if the value just entered i is divisable by 4
3.2 if it is, then compare if it's larger than the one was saved before (initially saved value will be 0)
3.3 if it is larger, then assign the read value i to the saved
4. At the end of the loop, you will have the highest number divisable by four in your saved variable. Print it.
I will provide some help, according to
How do I ask and answer homework questions?
for (int i = scanner.nextInt(); i % 4 == 0;i = scanner.nextInt())
This only reads as long as ALL inputs are divisible by 4, that is why it ends at 16, because 87 is not divisible by 4.
for (boolean bull = true; bull == true ;bull ^= true)
This needs explanation by you, but I am pretty sure that it unconditionally executes the body of the inner loop exactly once. (Not 100% sure, because the representation of true and false could be weird in your machine. Should 0 be the representation of true, i.e. really weird, then it is an endless loop, which does not match the output you describe...)
System.out.println(saved);
This executes exactly once per input, except the last one, which is not a multiple of 4.
The value of saved is identical to input, as long as it is increasing.
These hints explain the unexpected output.
If you inspect the details of what the problem is, you should be able to improve your coding attempt.
This is how I super-quickly fixed in your code.
Note that there are no statements about the possible minimum value and about how do you stop the input. Therefore the solution is pretty-straightforward, it just reads the input until integers are present there.
This article may be useful about handling the input from the Scanner.
I hope the comments in the code will help. Add comments if there are any questions. Good luck!
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int currentMax = Integer.MIN_VALUE; // you may set negative or 0 if you know that all the input is positive
// int saved2 = 0; // no need for this variable
while (scanner.hasNextInt()) { // you can make a better input handling, especially if you know when it should end the input. Now it will end on any non-integer input line
int i = scanner.nextInt();
// for (int i = scanner.nextInt(); i % 4 == 0; i = scanner.nextInt()) {
// for (boolean bull = true; bull == true; bull ^= true) {
if (((i % 4) == 0) && (i > currentMax)) {
currentMax = i;
// saved -= saved2;
// saved += i;
// saved2 += i;
// }
}
}
System.out.println(currentMax); // moved out of "for" or "while" cycles. Print the value after the input has ended.
}
}

I don't really understand the do { } while structure

I'm trying to learn Java, I studied Pascal in high school and it has the repeat until..; instruction.
I want to solve an exercise where I'm supposed to keep entering numbers until the penultimate + antepenultimate numbers equal the last number I entered.(a[i-2]+a[i-1] = a[i]); I'm doing it without arrays but that doesn't really matter.
In Pascal it would be easy because repeat until is more easier to use
For ex it would be
repeat
...
until ((a[i-2]+a[i-1] = a[i]) and (n=3));
n is the number of values I entered
I can't figure out how to introduce it in Java, so far I did this but it doesn't work if I enter 2 2 4. It should stop but it keeps asking for numbers
int pen = 0, ant = 0, s = 0, n = 1;
int ult = input.nextInt();
s = s + ult;
do {
do {
ant = pen;
pen = ult;
ult = input.nextInt();
n++;
s = s + ult;
} while (ant + pen != ult);
System.out.println(n);
} while ((n == 3) || (n < 4));
ult is the last number I enter, s is the sum of the numbers entered.
Could anyone tell me how to set the conditions so it will stop if I enter the values 2 2 4?
A Do-While loop runs the code in the loop first. It evaluates the logic last, and then if it's true it repeats the code inside the loop, and so on until the logic is false.
The way to solve tricky problems like this is to get out a sheet of paper and record what each variable does. Step through each line like a debugger and record what's being stored in each variable as the program progresses.
It's the best way to do it. You'll find that you'll gain a deeper understanding of how your programs are working.
Java isn't any more magic than Pascal, the issue might be you've had a long break from programming :). Anyway, its been a while since I wrote anything in Java, but the issue I could spot in your code is just that n equals three after you've entered three ints, and so the outer loop continues.
int pen = 0, ant = 0, ult = 0, n = 0;
do {
ant = pen;
pen = ult;
ult = input.nextInt();
} while (++n < 3 || ant + pen != ult );
assert n >= 3;
assert ant + pen == ult;
Note that ever since Pascal everything has been zero indexed instead of one indexed.
Pascal uses the form:
repeat
doStuff();
until (boleanValue);
Java is basically the same, except for one important point:
do
doStuff();
while (~boleanValue);
The important difference is that "~" before booleanValue. The Pascal repeat ... until keeps running until the boolean evaluates to true. In Java the do ... while keeps running until the boolean evaluates to false. When converting from Pascal to Java you need to switch the boolean to work the other way.
The primary difference between while loop and a do-while loop is that while loop does eager condition check where as do-while loop does lazy condition check
while: Expression is evaluated at the top of the loop
syntax:
while (expression) {
statement(s)
}
(taken from http://www.w3resource.com/c-programming/c-while-loop.php)
Example:
public class WhileDemo{
public static void main(String args[]) {
boolean isSunday = false;
while(isSunday) {
System.out.println("Yayy.. Its Sunday!!");
}
}
}
Output: (nothing is printed on console)
Reason: Since isSunday is false, the body of loop is not executed
do-while: Expression is evaluated at the bottom of the loop. Therefore, the statements within the do block are always executed at least once.
syntax:
do {
statement(s)
} while (expression);
(taken from http://www.w3resource.com/c-programming/c-do-while-loop.php)
Example:
public class DoWhileDemo{
public static void main(String args[]) {
boolean isSunday = false;
do {
System.out.println("Yayy.. Its Sunday!!");
} while(isSunday);
}
}
Output: Yayy.. Its Sunday!!
Reason: The body of do is executed first, there by printing Yayy.. Its Sunday!! and then the condition while(isSunday); evaluates to false since isSunday is false and the loop terminates
You're only missing one thing from your problem. Your explanation of the Pascal code is almost correct, but wouldn't work without some modification.
In Java, use short-circuit logical operators to do the check.
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html
Not tested:
int n = 0;
int a[] = new a[3];
do {
n++;
a[0] = a[1];
a[1] = a[2];
a[2] = input.nextInt();
} while ((n < 3) || (a[0]+a[1] != a[2]));
System.out.println(a[2]);

Can someone trace me through this using the values (1,1)

I have been given this on a mock programming exam and I am not too good with this type of thing, can someone explain to me how I would go through something like the following? change the values to the one in the question if you feel like it explains it better. It is the final else which is really throwing me off. Thank you for the help.
public int function( int a, int b)
{
if (a<=0){
return b;
}
else if (b<=0)
{
return function( a-2, 0);
}
else
{
return function (function (a-1, b-1), b-1);
}
I interpret your (1,1) as a = 1 and b = 1. That said:
a = 1 > 0, the enter condition is false, so the first branch is not taken:
if (a<=0)
We go on until the second branch. b = 1 > 0 the enter condition is false again, so we won't take this branch neither:
else if (b<=0)
eventually, we reach the else branch and we take it:
else
So we land in this line:
return function (function (a-1, b-1), b-1);
There is a recursion, here! First call is function (a-1, b-1), so we are calling function with a = 1 - 1 = 0 and b = 1 - 1 = 0. Let's start again as above:
a = 0, so we take the first branch:
if (a <= 0)
and we return b = 0.
Now, it's time for the second recursion. We have a = function(a - 1, b - 1) = 0 and b = 1 - 1 = 0. It's still a = 0 and b = 0, so the result will be 0 as above.
Finally, we return 0.
Alright, I will step through other values so you can learn how to do it yourself.
lets take the values 2,2 for example.
check the first if statement(if (a<=0)) to see if its valid
a=2 so replace a with the value 2
is 2 <= 0? Nope. Lets go to the next statement
else if (b<=0)
NOTE: else if is essentially a statement that it used if the previous if statement for fails.
b = 2 is 2<=0? Nope. ONTO THE NEXT ONE!
else handles everything that fails under the first if and all the proceeding else ifs
So just plug in the values.
a = 2 b = 2
return function (function (a-1, b-1), b-1);
-->
return function (function (2-1, 2-1), 2-1);
-> return function (function (1, 1), 1);
You can go two ways with this keep recurring down or logically think about it.
Now... lets start noticing a pattern here and look for a base case (usually used for recursive functions like these) so you notice return b on the first if statement will ALWAYS be the actual returning result in the end and all the other recurring will stem off that result, because that's the only real value you will return. Now we got that established
How can we get to that value? if statement a<=0 is the only way to get there. You start noticing the relationships.
input a <= b or a <= 0 output b
input a > 0 a > b output 0

Categories

Resources