COMMENTS BELOW ARE ANSWERING ANOTHER QUESTION, THIS IS THE ONLY WAY FOR ME TO ASK NEW QUESTION...
Okay. My program is like writing info on a .txt file. Currently it is writing info to end of the text file like so:
t/1/15/12
o/1/12/3
o/2/15/8
... (lots of lines like this.. all with different numbers)
o/1/16/4
Then.. when I add line using:
BufferedWriter fw = new BufferedWriter(new FileWriter(new File("C://Users/Mini/Desktop/Eclipse/Japda/map/" +Numbers.map +".txt"), true));
fw.newLine();
fw.write(RightPanel.mode.charAt(0) +"/" +ID +"/" +Numbers.middlex +"/" +Numbers.middley);
fw.close();
It adds the line I want to but currently to the end of the text file.. However I would like it to write that line to a specific part of the text files.. I already do know the number of the line I want to write it.. (It is calculated depending on other lines..) :D Is there any way to do it? Or what would be the best way to edit one specific line in the middle of that text file?
To achieve what you require, you would need to use a RandomAccessFile. Steps:
First create a RandomAccessFile then:
Create a variable called lineStart which is initially set to 0
(beginning of the file)
Read in the file line by line using readline
Check whether it is the required line that you wish to insert before
If it is the correct place, then lineStart will hold the position
just before the line you wish to insert before. Use seek to
position you at the correct place by initially using seek(0) to
position you at the start of the file, then seek(lineStart) to get
the required position. You then use writeChars to write to the file.
Remember that you have to explicitly write the newline.
If it is not where you wish to insert then call getFilePointer, and
store value in lineStart
REPEAT STEPS 2-5 UNTIL YOU ARRIVE AT THE DESIRED PLACE FOR INSERTION
You want a do-while loop:
do {
//code
} while (expression);
Source:
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html
You probably want something like this:
int[] done = new int[100];
int randomquestion;
do{
randomquestion = (int)(Math.random() * 83 + 1);
if(done[randomquestion] != 1)
{
//ask random question
//if answer is correct, set done[randomquestion] = 1
//else just let do-while loop run
}
//check if all questions are answered
} while (!areAllQuestionsComplete(done));
Here is the method areAllQuestionsComplete(int[]):
private boolean areAllQuestionsComplete(int[] list)
{
for(int i = 0; i<list.length; i++)
{
if(list[i] != 1)
{
return false;//found one false, then all false
}
}
return true;//if it makes it here, then you know its all done
}
Looking at your latest code:
for(int i = 0; i<done.length; i++)
{
done[i] = 0;//need default values else wise itll just be NULL!!!
}
do{
ran = (int)(Math.random() * 83 + 1);
//before entering the do-while loop, you must set default values in the entire done[] array
if(done[ran] != 1)
{
//ask random question
//if answer is correct, set done[ran] = 1
//else just let do-while loop run
if (ran == 1) { //1
question = "kala";
rightanswer = "fish";}
if (ran == 2) { //2
question = "peruna";
rightanswer = "potato";}
if (ran == 3) { //3
question = "salaatti";
rightanswer = "cabbage";}
if (ran == 4) { //4
question = "kalkkuna";
rightanswer = "turkey";}
if (ran == 5) { //5
question = "kia";
rightanswer = "tikku";}
//YOU MUST HAVE EVERY CONDITION COVERED
//say your random number makes the number 10
//you dont set question to anything at all (hence getting null!)
System.out.println(question);
System.out.print("Vastaus?: ");
answer = in.readLine();
//if (answer == rightanswer){
//must use .equals with Strings...not ==
if (answer.equals(rightanswer)){
right++;
done[ran] = 1;}
else{wrong++;}
}
//check if all questions are answered
} while (!areAllQuestionsComplete(done));//use the method I wrote!
EDIT:
You must put default values in the array. When you create an array, the default value is null.
int[] done = new int[100];//create array but everything is null
for(int i = 0; i<done.length; i++)
{
done[i] = 0;//need default values else wise it'll just be NULL!!!
}
//must be done before the do-while loop starts
Finally, make sure your random number generator picks the correct range in numbers. If you have an array that is size 100, then it's indexes will be 0-99. This means there is no done[100]. It goes from done[0] to done[99].
If you have done[] be a size of 5, then it will range from done[0] to done[4]. That means you should randomly generate like this:
randomquestion = (int)(Math.random() * 5 );
Related
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.
}
}
When creating the following function, in order to get a correct answer I have to add "count-=1" line, otherwise the answer gets skewed by 1.
public int countCTG(String dna) {
int count = 0;
int firstOccurrence = dna.indexOf("CTG");
if (firstOccurrence != -1) {
count +=1;
while (dna.indexOf("CTG", firstOccurrence) != -1 && firstOccurrence != -1) {
count +=1;
firstOccurrence = dna.indexOf("CTG", firstOccurrence+3);
}
count -=1;
}
else {
count = 0;
}
return count;
}
I managed to get this function working, however could you please help me understand the logic behind it? The count variable was initialized originally to 0 and if a string,for example, contains one instance of "CTG" it will be already counted in by "count +=1" line. Wouldn't count -=1 reset this variable back to 0?
You need the -1 because of the +1 before the loop: the first iteration of the while loop counts the already-found occurrence again.
An easier solution is like so:
int count = 0;
int skip = "CTG".length();
int current = -skip;
while ((current = dna.indexOf("CTG", current + skip)) >= 0) {
++count;
}
return count;
Because you're not updating firstOccurrence after your first search -- i.e. you're searching twice from the start (.indexOf("CTG")) before starting to search from the previous result (.indexOf("CTG", prevResultIndex + 3)).
Also note that:
you don't have to search once before the while loop
the else clause is redundant
you're calling .indexOf twice as many times as you actually need
the firstOccurrence+3 is a liability, you'll forget to update the offset when the string changes and it will be hard to track down. Store the searched-for string in one place, and compute its length instead of hardcoding it.
EDIT: Well #AndyTurner rewrote it for you, but try to see how each one of the listed points come into reaching that result
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++;
}
QUESTION:
How can I read the string "d6+2-d4" so that each d# will randomly generate a number within the parameter of the dice roll?
CLARIFIER:
I want to read a string and have it so when a d# appears, it will randomly generate a number such as to simulate a dice roll. Then, add up all the rolls and numbers to get a total. Much like how Roll20 does with their /roll command for an example. If !clarifying {lstThen.add("look at the Roll20 and play with the /roll command to understand it")} else if !understandStill {lstThen.add("I do not know what to say, someone else could try explaining it better...")}
Info:
I was making a Java program for Dungeons and Dragons, only to find that I have come across a problem in figuring out how to calculate the user input: I do not know how to evaluate a string such as this.
I theorize that I may need Java's eval at the end. I do know what I want to happen/have a theory on how to execute (this is more so PseudoCode than Java):
Random rand = new Random();
int i = 0;
String toEval;
String char;
String roll = txtField.getText();
while (i<roll.length) {
check if character at i position is a d, then highlight the numbers
after d until it comes to a special character/!aNumber
// so if d was found before 100, it will then highlight 100 and stop
// if the character is a symbol or the end of the string
if d appears {
char = rand.nextInt(#);
i + #'s of places;
// so when i++ occurs, it will move past whatever d# was in case
// d# was something like d100, d12, or d5291
} else {
char = roll.length[i];
}
toEval = toEval + char;
i++;
}
perform evaluation method on toEval to get a resulting number
list.add(roll + " = " + evaluated toEval);
EDIT:
With weston's help, I have honed in on what is likely needed, using a splitter with an array, it can detect certain symbols and add it into a list. However, it is my fault for not clarifying on what else was needed. The pseudocode above doesn't helpfully so this is what else I need to figure out.
roll.split("(+-/*^)");
As this part is what is also tripping me up. Should I make splits where there are numbers too? So an equation like:
String[] numbers = roll.split("(+-/*^)");
String[] symbols = roll.split("1234567890d")
// Rough idea for long way
loop statement {
loop to check for parentheses {
set operation to be done first
}
if symbol {
loop for symbol check {
perform operations
}}} // ending this since it looks like a bad way to do it...
// Better idea, originally thought up today (5/11/15)
int val[];
int re = 1;
loop {
if (list[i].containsIgnoreCase(d)) {
val[]=list[i].splitIgnoreCase("d");
list[i] = 0;
while (re <= val[0]) {
list[i] = list[i] + (rand.nextInt(val[1]) + 1);
re++;
}
}
}
// then create a string out of list[]/numbers[] and put together with
// symbols[] and use Java's evaluator for the String
wenton had it, it just seemed like it wasn't doing it for me (until I realised I wasn't specific on what I wanted) so basically to update, the string I want evaluated is (I know it's a little unorthodox, but it's to make a point; I also hope this clarifies even further of what is needed to make it work):
(3d12^d2-2)+d4(2*d4/d2)
From reading this, you may see the spots that I do not know how to perform very well... But that is why I am asking all you lovely, smart programmers out there! I hope I asked this clearly enough and thank you for your time :3
The trick with any programming problem is to break it up and write a method for each part, so below I have a method for rolling one dice, which is called by the one for rolling many.
private Random rand = new Random();
/**
* #param roll can be a multipart roll which is run and added up. e.g. d6+2-d4
*/
public int multiPartRoll(String roll) {
String[] parts = roll.split("(?=[+-])"); //split by +-, keeping them
int total = 0;
for (String partOfRoll : parts) { //roll each dice specified
total += singleRoll(partOfRoll);
}
return total;
}
/**
* #param roll can be fixed value, examples -1, +2, 15 or a dice to roll
* d6, +d20 -d100
*/
public int singleRoll(String roll) {
int di = roll.indexOf('d');
if (di == -1) //case where has no 'd'
return Integer.parseInt(roll);
int diceSize = Integer.parseInt(roll.substring(di + 1)); //value of string after 'd'
int result = rand.nextInt(diceSize) + 1; //roll the dice
if (roll.startsWith("-")) //negate if nessasary
result = -result;
return result;
}
I've been trying to get this to work for a while. I'm putting in three parallel empty arrays and it errors out saying that there is no line found. It ONLY works when I change the while statement to the number of elements. I am trying to make arrays that are the size of 15, but only fill the first ten array portions.
Sorry if it sounds complicated, but basically I'm trying to say that the size of the array is 15, I only have 10 things to enter in the array, and the rest of them should be blank.
while (text.hasNext() && c < nameArray.length) {
nameArray[count] = text.nextLine();
intArray[count] = text.nextDouble();
doubleArray[count] = text.nextInt();
text.nextLine();
c++;
}
This does not work.
while (text.hasNext() && c < 9) {
nameArray[count] = text.nextLine();
intArray[count] = text.nextDouble();
doubleArray[count] = text.nextInt();
text.nextLine();
c++;
}
This does.
Your read the file TWICE within a single loop. Remove the 2nd read:
fileText.nextLine();
Of course it doesn't work. If you need to cycle to the max between fileText length and gameArray length, you should use or instead of and and use an if in the loop.
Try something like this:
while (fileText.hasNext() || count < gameArray.length) {
if (!fileText.hasNext()) {
gameArray[count] = "";
priceArray[count] = 0;
stockArray[count] = 0;
} else {
gameArray[count] = fileText.nextLine();
priceArray[count] = fileText.nextDouble();
stockArray[count] = fileText.nextInt();
fileText.nextLine();
}
count++;
}
Your issue is not with the length of the array but with fileTest.nextLine(). After a certain point there is no nextLine() available. It works for the 1st 9 times but I guess all the lines are exhausted before you reach array.length. I would suggest just one condition in your while loop:
while(fileText.hasNext()) {
}
This way you would fill in only the amount actually present.
Add another check with the second fileText.nextLine() to ensure that there is a line to read.
while (fileText.hasNext() && count < gameArray.length) {
gameArray[count] = fileText.nextLine();
priceArray[count] = fileText.nextDouble();
stockArray[count] = fileText.nextInt();
if ( fileText.hasNext() )
fileText.nextLine();
count++;
}
In the first version of your code, your try to read input 15 times, but it is entered only 10 times. So the scanner tries to read a new line but it doesn't exist.