How to generate random numbers in my situation - java

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 '*'.

Related

Validating an expression

Given an expression with operators, functions, and operands, such as:
2 + sin ( max ( 2, 3 ) / 3 * 3.1415 )
How can I programmatically validate the expression, such that any functions must have the correct number of parameters? For example abs,sin,cos must have exactly 1 parameter, whereas sum,avg,max,min have 2 or more.
Given that each parameter can itself be a very complicated expression, it seems non-trivial to programmatically determine this. I have already written a lexical tokenizer (lexer), and I've managed to convert the expression to postfix/RPN. (Which is: 2 3 max 3 / 3.1415 * sin 2 +). I am still no closer to a solution.
I would appreciate some code or pseudocode that will guide me in writing something from scratch. Java would be great.
Below is my lexer code:
public static List<Token> shunt(List<Token> tokens) throws Exception {
List<Token> rpn = new ArrayList<Token>();
Iterator<Token> it = tokens.iterator();
Stack<Token> stack = new Stack<Token>();
while (it.hasNext()) {
Token token = it.next();
if (Type.NUMBER.equals(token.type))
rpn.add(token);
if (Type.FUNCTION.equals(token.type) || Type.LPAREN.equals(token.type))
stack.push(token);
if (Type.COMMA.equals(token.type)) {
while (!stack.isEmpty() && !Type.LPAREN.equals(stack.peek().type))
rpn.add(stack.pop());
if (stack.isEmpty())
throw new Exception("Missing left parenthesis!");
}
if (Type.OPERATOR.equals(token.type)) {
while (!stack.isEmpty() && Type.OPERATOR.equals(stack.peek().type))
rpn.add(stack.pop());
stack.add(token);
}
if (Type.RPAREN.equals(token.type)) {
while (!stack.isEmpty() && !Type.LPAREN.equals(stack.peek().type))
rpn.add(stack.pop());
if (stack.isEmpty())
throw new Exception("Missing left parenthesis!");
stack.pop();
if (!stack.isEmpty() && Type.FUNCTION.equals(stack.peek().type))
rpn.add(stack.pop());
}
}
while (!stack.isEmpty()) {
if (Type.LPAREN.equals(stack.peek().type) || Type.RPAREN.equals(stack.peek().type))
throw new Exception("Mismatched parenthesis!");
rpn.add(stack.pop());
}
return rpn;
}
What you want to do is implement a precise parser, that knows the exact syntax of your language (that includes "how many operators does a function have").
It is easy to write such a parser for expressions. See https://stackoverflow.com/a/2336769/120163
You either need to detect it during the Shunting Yard. A quick idea would be on the operator stack, keep a counter against each element. Count the number of commas detected. Then either on a close parenthesis or just at the end, check the number of arguments against each function entry.
An alternative might be to keep some more of the information as additional values for your RPN. e.g. keep the commas, you then get:
2 , 3 max 3 / 3.1415 * sin 2 +
When processing a function, it not only must eat values from the stack it must also eat the correct number of ,s. And too many will show itself later on.
I fear that way has some edge cases though like this; so probably better a precise parser.
sin(1,2) * max (3)
1 , 2 sin 3 max *

new password consecutive characters is greater than 3 with old password then it should throw an error. But it giving error even if it is 3 also

In This we are checking if new password consecutive characters is greater than 3 with old password then it should throw an error . For this logic is below :
if (oldPassword != null) {
for (int i = 0; i < oldPassword.length() - PASSWORD_MAX_CONS_LENGTH +1; i++) {
if (passwordString.indexOf(oldPassword.substring(i, i
+ PASSWORD_MAX_CONS_LENGTH)) >= 0) {
errors.add(ERROR_PASS_CONS_PREV_PASS);
break;
}
}
}
PASSWORD_MAX_CONS_LENGTH = 3;
But problem is it is even throwing error if it is equal to 3.
Can we have any better solution for this. As this logic is little complicated :
if (passwordString.indexOf(oldPassword.substring(i, i
+ PASSWORD_MAX_CONS_LENGTH)) >= 0)
Can we use any regular expression to check 3 consecutive character compared with old password. Is there any way to do this ?
The parameters of indexOf() are the start index and the index where you want to stop + 1. So just add one to i + PASSWORD_MAX_CONS_LENGTH.
Using regular expressions would make it much more complex. You should just increment by 1 the end index of your substring .

How to move up lines in a .txt file with BufferedReader?

Making an "assembler" program for a CS course I am enrolled in. It has functions like ADD, SET, INC (increment), and JIG. Now, we are inputing a .txt file with the following layout (as example):
Keep note: A and B are just integer's that store the value throughout the program, and print out the value once it reaches the end of the text file.
INC A (increments A by 1)
SET B 5 (set's B's value to 5)
INC B
ADD A 3 (add's 3 to A's current value)
JIG B -4 (move's backward 4 lines, so back to INC A)
So what I am confused how to do is move my BufferedReader back 4 lines? Is there a method in BufferedReader that lets you move it to a certain index/position? Otherwise, how else can I accomplish this?
The simplest thing to do is store the lines in an array or List.
List<String> lines = Files.readAllLines(Paths.get("myfile.txt"));
This will allow you to progress to any line at random.
To get any line you can use lines.get(n) For example you can do
int pointer = 0;
for(boolean running = true; running && pointer < lines.size(); ) {
String line = lines.get(pointer);
String[] parts = line.split(" +");
switch(part[0]) {
case "JMP":
pointer += Integer.parseInt(parts[1]); // jump back or forth.
continue;
case "HALT":
running = false;
break;
// other instructions
}
pointer++;
}

Print out Yijing Hexagram Symbols

I encountered a problem while coding and I can't seem to find where I messed up or even why I get a wrong result.
First, let me explain the task.
It's about "Yijing Hexagram Symbols".
The left one is the original and the right one is the result that my code should give me.
Basically every "hexagram" contains 6 lines that can be either diveded or not.
So there are a total of
2^6 = 64 possible "hexagrams"
The task is to calculate and code a methode to print all possible combinations.
Thats what I have so far :
public class test {
public String toBin (int zahl) {
if(zahl ==0) return "0";
if (zahl ==1 ) return "1";
return ""+(toBin( zahl/2)+(zahl%2));
}
public void show (String s) {
for (char c : s.toCharArray()){
if (c == '1'){
System.out.println("--- ---");
}
if(c=='0'){
System.out.println("-------");
}
}
}
public void ausgeben (){
for(int i = 0 ; i < 64; i++) {
show (toBin(i));
}
}
}
The problem is, when I test the 'show'-methode with "10" I get 3 lines and not 2 as intended.
public class runner {
public static void main(String[] args){
test a = new test();
a.ausgeben();
a.show("10");
}
}
Another problem I've encoutered is, that since I'm converting to binary i sometimes have not enough lines because for example 10 in binary is 0001010 but the first "0" are missing. How can I implement them in an easy way without changing much ?
I am fairly new to all this so if I didn't explain anything enough or made any mistakes feel free to tell me.
You may find it easier if you use the Integer.toBinaryString method combined with the String.format and String.replace methods.
String binary = String.format("%6s", Integer.toBinaryString(zahl)).replace(' ', '0');
This converts the number to binary, formats it in a field six spaces wide (with leading spaces as necessary), and then replaces the spaces with '0'.
Well, there are many ways to pad a string with zeros, or create a binary string that is already padded with zeros.
For example, you could do something like:
public String padToSix( String binStr ) {
return "000000".substring( 0, 5 - binStr.length() ) + binStr;
}
This would check how long your string is, and take as many zeros are needed to fill it up to six from the "000000" string.
Or you could simply replace your conversion method (which is recursive, and that's not really necessary) with one that specializes in six-digit numbers:
public static String toBin (int zahl) {
char[] digits = { '0','0','0','0','0','0' };
int currDigitIndex = 5;
while ( currDigitIndex >= 0 && zahl > 0 ) {
digits[currDigitIndex] += (zahl % 2);
currDigitIndex--;
zahl /= 2;
}
return new String(digits);
}
This one modifies the character array ( which initially has only zeros ) from the right to the left. It adds the value of the current bit to the character at the given place. '0' + 0 is '0', and '0' + 1 is '1'. Because you know in advance that you have six digits, you can start from the right and go to the left. If your number has only four digits, well, the two digits we haven't touched will be '0' because that's how the character array was initialized.
There are really a lot of methods to achieve the same thing.
Your problem reduces to printing all binary strings of length 6. I would go with this code snippet:
String format = "%06d";
for(int i = 0; i < 64; i++)
{
show(String.format(format, Integer.valueOf(Integer.toBinaryString(i))));
System.out.println();
}
If you don't wish to print leading zeros, replace String.format(..) with Integer.toBinaryString(i).

What's wrong with my brainfuck parser code?

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++;
}

Categories

Resources