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
"""
Related
Can someone explain to me how I am able to turn this into a loop? (allDigitsOdd Method)
There should only be one true value returned or one false value returned by the end of the loop.
Check each digit of a number to see if it is odd or even. If the digit is odd then keep going on to the next digit. If the digit being checked is even then stop the loop and return one false value for the entire number. If all of the digits are odd then return true. How can I make this work for any number and not just the one in the example of what I am trying to convey below?
```java
public class oddOrEvenDigits {
public static void main(String[] args) {
boolean b1 = allDigitsOdd(73925);
System.out.println(b1);
// correct output is false value
// create Method
public static boolean allDigitsOdd(int n) {
// The integer is n but I am putting 73925 in place of n for the example of what I am trying to do
// get the last digit of the number (n)
(73925 example) % 10); // gives 5 as answer
// check to see if the last digit of n (5 in example) is even or odd
// if it is odd then keep going
// if it is even then return false and stop loop
(73925 / 10); // becomes 7392
(7392 % 10); // gives 2 as answer
// check to see if 2 is even or odd
// if it is odd then keep going
// if it is even then return false and stop the loop
// check to see if the 2 is even or odd
(7392 / 10); // becomes 739
(739 % 10); // Output 9
// check to see if 9 is even or odd
// if it is odd then keep going
// if it is even then return false and stop the loop
(739 / 10); // becomes 73
(73 % 10); // Output 3
// check if 3 is odd or even
// if it is odd then keep going
// if it is even then return false and stop the loop
(73 / 10); // becomes 7
(7 % 10);// Output 7
// check if 7 is odd or even
// if 7 is odd then if all the previous numbers checked are also odd then return
// true and stop the loop
// if 7 is even then stop the loop
}
```
Here is one way.
int[] data = {23122, 20202,31753, 20209,99999};
for (int i : data) {
System.out.println(i + " " +allDigitsOdd(i));
}
prints
23122 false
20202 false
31753 true
20209 false
99999 true
iterate until the number == 0
get the last digit by using remainder (%) via 10.
Then test for evenness doing the same with 2.
As soon as even is detected, return false
else return true if loop finishes.
public static boolean allDigitsOdd(int n) {
while (n != 0) {
if ((n%10)%2 == 0) {
return false;
}
// expose next digit
n/=10;
}
return true;
}
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);
}
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
I generate randomly this expression [0-9*]. The symbol '*' is end line symbol. When it is generated, I jump to next line and fill it until '*' is generated again and so on. But in some cases, my first generated symbol is '*' and then jump to next line. for example:
116165464*
56465*
*
654*
64*
*
14*
and so on
...
..
.
As you can see, end line symbol like in 3 line is not suitable and useful. So I want to avoid this. How can I generate numbers and prevent to generate like 3 line and 6 line in my example? In other words, I want to generate lines which must to contain numbers ( there cannot be like 3 and 6 lines showed in my example)
(Assume that I will delete all '*' symbols in the future, and if there will be lines like 3 and 6 in my example, there will be only empty space.)
My code looks like this: (it will generate symbols, c - char type)
for(int i = 1;i<max;i++){
if(i == max-1)
c = '*';
c = numbers.charAt(rnd.nextInt(numbers.length()));
listChar.add(c);
Thanks
I think I solved my problem by doing this:
I add additional char temp;
I stored my previous symbol in my temp;
And check this condition:
temp = c;
c = generate symbol;
...
if(temp == c)
continue;
if not equal
add(c)
(It is kind of pseudo to get an idea)
One from my results:
123355666778999
98631
112339
7
8
88877431
169
99988765544443211
112444456788999
981
1345
98876655543211
334667899
85431
34569
876521
1112334556678
88764333211
With small change to your code what you wanted may be achieved.
I'm assuming that number = "0123456789*" based on your logic. If you want to achieve a non zero
// Next line will generate one number from 0 to 9 as we are ignoring last character.
listChar.add(numbers.charAt(rnd.nextInt(numbers.length()-1)));
for(int i = 2;i<max;i++){
c = numbers.charAt(rnd.nextInt(numbers.length()));
listChar.add(c);
if(c == '*')
break;
}
System.out.println(listChar);
Below code will ensure you can avoid adding an asterisk.
// Next line will generate one number from 0 to 9 as we are ignoring last character.
listChar.add(numbers.charAt(rnd.nextInt(numbers.length()-1)));
for(int i = 2;i<max;i++){
c = numbers.charAt(rnd.nextInt(numbers.length()));
if(c == '*')
{
break;
}
else
{
listChar.add(c);
}
}
System.out.println(listChar);
However there can always be a better algorithm to generate what you wanted. But this will work.
public void genLine(){
int random = Math.random()*10;
System.out.print(random);
while (random!=10)
random = Math.random()*11;
if (random == 10) System.out.print('*');
else System.out.print(random);
}
}
This will generate one line for you. The first character is a special case because it cannot be a '*' so I just hard coded it. In every other case generate a random number with one more possibility. If that extra possibility is chosen, print '*'.
I'm trying to make a program in Java that can read, compile, and run brainfuck source files (.bf). I've gotten it to work just fine with Wikipedia's Hello World example, but it breaks on the ROT13 example (claims it reached an unmatched ] when it was actually matched).
The actual parser code is all written in one .JAVA file, but the heart of it (the actual brainfuck parser and running code) is in the below method, doNow(char). Here are what the variables are: cells is the array of characters to be run (char[]); pointer is the Java workaround to point to an address in the array (short); PC is the program counter (int), and loopStack is a stack of addresses which correspond to [s (basically a short[]). These are not the problem, as they work just fine in the Hello World test. The method that takes input automatically filters out excess characters, and I confirmed it to work perfectly from debug inspection.
Why doesn't this parser run the ROT 13 code?
Code
My parser, written in Java
/** The array of data */
private byte[] cells = new byte[Short.MAX_VALUE];
/** The pointer that is manipulated by the user or program */
private short pointer = 0;
/** The program counter, to run compiled programs */
private int PC = 0;
/** The compiled commands */
private ArrayPP<Character> commandBuffer = new ArrayPP<>();
/** The stack of locations of loop brackets ({#code [}) in the command buffer */
private ArrayPP<Short> loopStack = new ArrayPP<>();//ArrayPP is my proprietary augmented array object, which also functions as a perfectly working stack.
public int doNow(char command) throws IOException
{
PC++;
switch (command)
{
case '>':
return ++pointer;
case '<':
return --pointer;
case '+':
return ++cells[pointer];
case '-':
return --cells[pointer];
case '.':
System.out.print((char)cells[pointer]);
return 0;
case ',':
return cells[pointer] = (byte)System.in.read();
case '[':
if (cells[pointer] == 0)//If we're ready to skip this conditional
{
int oldPC = PC;
try
{
while (getCompiledCommand(PC) != ']')//Find the matching ]
PC++;
PC++;//Now that we're at the ], skip over it to the next command
}
catch (ArrayIndexOutOfBoundsException e)
{
throw new NullPointerException("Unmatched '[' at " + oldPC);//If we try to reference a command outside the buffer
}
}
else//if we want to enter this conditional
loopStack.push(PC - 1);//Add the location of this conditional to the list of conditionals which we are in
return PC;
case ']':
try
{
return PC = loopStack.pop();//Move us to the matching [ and remove it from the list of conditionals we're in
}
catch (ArrayIndexOutOfBoundsException e)
{
throw new NullPointerException("Unmatched ] at " + PC);//If the loop stack is empty
}
default:
throw new AssertionError(command + " is not a valid command.");
}
}
public char getCompiledCommand(int commandIndex)
{
return commandBuffer.get(commandIndex);//Look into the buffer of precompiled commands and fetch the one at the given index
}
The Hello World example (works perfectly)
+++++ +++++ initialize counter (cell #0) to 10
[ use loop to set the next four cells to 70/100/30/10
> +++++ ++ add 7 to cell #1
> +++++ +++++ add 10 to cell #2
> +++ add 3 to cell #3
> + add 1 to cell #4
<<<< - decrement counter (cell #0)
]
> ++ . print 'H'
> + . print 'e'
+++++ ++ . print 'l'
. print 'l'
+++ . print 'o'
> ++ . print ' '
<< +++++ +++++ +++++ . print 'W'
> . print 'o'
+++ . print 'r'
----- - . print 'l'
----- --- . print 'd'
> + . print '!'
> . print '\n'
ROT 13 example (My test console input is M. Breaks on command 54 after several loop iterations)
-,+[ Read first character and start outer character reading loop
-[ Skip forward if character is 0
>>++++[>++++++++<-] Set up divisor (32) for division loop
(MEMORY LAYOUT: dividend copy remainder divisor quotient zero zero)
<+<-[ Set up dividend (x minus 1) and enter division loop
>+>+>-[>>>] Increase copy and remainder / reduce divisor / Normal case: skip forward
<[[>+<-]>>+>] Special case: move remainder back to divisor and increase quotient
<<<<<- Decrement dividend
] End division loop
]>>>[-]+ End skip loop; zero former divisor and reuse space for a flag
>--[-[<->+++[-]]]<[ Zero that flag unless quotient was 2 or 3; zero quotient; check flag
++++++++++++<[ If flag then set up divisor (13) for second division loop
(MEMORY LAYOUT: zero copy dividend divisor remainder quotient zero zero)
>-[>+>>] Reduce divisor; Normal case: increase remainder
>[+[<+>-]>+>>] Special case: increase remainder / move it back to divisor / increase quotient
<<<<<- Decrease dividend
] End division loop
>>[<+>-] Add remainder back to divisor to get a useful 13
>[ Skip forward if quotient was 0
-[ Decrement quotient and skip forward if quotient was 1
-<<[-]>> Zero quotient and divisor if quotient was 2
]<<[<<->>-]>> Zero divisor and subtract 13 from copy if quotient was 1
]<<[<<+>>-] Zero divisor and add 13 to copy if quotient was 0
] End outer skip loop (jump to here if ((character minus 1)/32) was not 2 or 3)
<[-] Clear remainder from first division if second division was skipped
<.[-] Output ROT13ed character from copy and clear it
<-,+ Read next character
] End character reading loop
to make it clear, here's where it breaks:
>[+[<+>-]>+>>] Special case: increase remainder / move it back to divisor / increase quotient
^
You should keep track of '[]' nestedness in the '[' case branch: now, the match for the first '[' in [+++[----]+] is the first ']', which is not good.
Problem
It seems the problem lies in this line:
while (getCompiledCommand(PC) != ']')//Find the matching ]
This works fine in the Hello World program because it has no nested loops. However, with nested loops, we run into the problem that it hits the first encountered ], which is not always the matching ].
Fix
One possible fix is to introduce a variable before the while loop, say loopCount, and increment it every time a [ is encountered, then decrement it when a ] is encountered and loopCount is greater than 0. For instance:
int loopCount = 0;
while ((command = getCompiledCommand(PC)) != ']' && loopCount == 0)//Find the matching ]. We can save the return in command because we're done using it.
{
if (command == '[')//If we run into a nested loop
loopCount++;
else if (command == ']')//If we run into the end of a nested loop
loopCount--;
PC++;
}