I am working on a class assignment that has us create a system to simulate vehicles at an intersection. We are to assume that there is one lane going in each of four directions, with stoplights facing each direction. We have to vary the arrival average of vehicles in each direction and the frequency of the light changes to view the "behavior" of the intersection.
I gave my best attempt at the assignment, but still being new to Java I seem to have made a mistake that I am taking a very long time trying to figure out. Basically, my outputs at the bottom of the program do not output anything.
I am also currently stuck assuming that the outputs will output what I am desiring them to, which obviously would require the rest of my code to be sound.
That being said, if anyone can spot my error that is preventing my code from outputting everything, or anything in addition that catches your eye, then I would be very appreciative.
import java.util.*;
public class Intersection
{
private final static int PROCESS = 3;
private final static int SIM_LENGTH = 1000;
#SuppressWarnings("resource")
public static void main(String[] args)
{
Car car = new Car();
Deque<Car> carQueue = new LinkedList<Car>();
int delayTotal = 0, carArrival, lightChange = 0, switchCount = 0, changeCount = 0;
double carCount;
boolean even = false;
String lightColor, green = null, red = null;
Scanner scan = new Scanner(System.in);
System.out.println("Enter in a car arrival interval between 1 and 5 seconds." + "\n");
carArrival = scan.nextInt();
if (!(carArrival < 6 && carArrival > 0))
System.out.println("Enter a valid time." + "\n");
Scanner sc = new Scanner(System.in);
System.out.println("Enter in a traffic light duration between 5 and 10 seconds." + "\n");
lightChange = sc.nextInt();
if (!(lightChange < 11 && lightChange > 4))
System.out.println("Enter a valid time." + "\n");
//add a car to the queue every [carArrival] seconds
for (int i = 0; i < SIM_LENGTH; i+= carArrival)
{
carQueue.add(car);
}
//Develop a way for the program to know that SIM_LENGTH has
//counted 'lightChange' seconds.
//Count each time lightChange occurs
for (int i = 0; i < SIM_LENGTH; i++)
{
if (i % lightChange == 0)
{
changeCount++;
}
}
//Assuming light starts as red, every time the preceding count increases by 1,
//switch lightColor.
//if count % 2 == 0, return green light; else red light
if (changeCount % 2 == 0)
{
even = true;
}
if (even)
{
lightColor = green;
}
else
{
lightColor = red;
}
while (lightColor == green)
{
//remove a car from the queue every [PROCESS] seconds
//(PROCESS is time to pass intersection)
for (int i = 0; i < SIM_LENGTH; i+= PROCESS)
{
carQueue.remove(car);
}
//I increment 'switchCount so I can use it as a divisor
//for delayTotal to find the delayAverage
switchCount++;
}
//Trying to increment delay time (cars are immobilized by red light)
delayTotal += lightChange;
//carCount Example:
//lightChange = 6; PROCESS = 3; switchCount =166.7 times
//carCount = 333.4 cars; obviously I need it to a whole number
carCount = (lightChange / PROCESS) * switchCount;
int delayAverage = delayTotal/switchCount;
int stranded = carQueue.size();
System.out.println("Cars across: " + carCount);
System.out.println("Delay (tot): " + delayTotal);
System.out.println("Delay (avg): " + delayAverage);
System.out.println("Number stranded: " + stranded);
}
}
Related
I am constructing a simulation of beehive and I make use of a 2D array called workerBee.
It has the following 6 fields: beeId, Age, Type(egg = 1, larva = 2, pupa = 3, worker = 4, drone = 5), PollenCollection, Eaten, Alive
Brief about the model: The Queen Bee lays eggs daily(10 to 50 eggs) and they are added to the hive.Each day, data about the bees are updated(their age and type).
For every day that passes, I print the beehive status which prints information about the number of bees, births, deaths etc..
For some days during the simulation(at the beginning, say day 6 to 10), the number of larva reported is around 800 to 900 for 1 day.
Here are the codes that deal with the printing and counting:
public static int layDailyEggs() {
Random randomEggs = new Random();
final int MAX_EGGS = 50;
final int MIN_EGGS = 10;
int x = randomEggs.nextInt((MAX_EGGS - MIN_EGGS) + 1) + MIN_EGGS;
eggsLaid = x;//eggsLaid as a global variable to be used in printBeehiveStatus
return x;//To pass as argument to addEggToHive
}
public static void addEggToHive(int eggsLaid) {
//Update the workerBee array with available slots
//Traverse the 2D array and while beeId != 0, add eggs and update
for (int i = 0; i < workerBee.length; i++) {
if (workerBee[i][0] == 0 && eggsLaid > 0) {
//Available space
workerBee[i][0] = i;//Update beeID
workerBee[i][1] = 1;//Update age
workerBee[i][2] = 1;//Update Type
eggsLaid--;
}
}
}
public static void countTypesOfBees() {
//Initialize for each day
totalEggsLaid = 0;
numberOfBirths = 0;
numberOfLarva = 0;
numberOfPupa = 0;
numberOfWorkerBees = 0;
numberOfDrones = 0;
//To call upon updating type of each bee
for (int i = 0; i < workerBee.length; i++) {
if(workerBee[i][2] == 1) {
totalEggsLaid++;
}else if(workerBee[i][2] == 2) {
numberOfLarva++;
numberOfBirths++;
}else if(workerBee[i][2] == 3) {
numberOfPupa++;
numberOfBirths++;
}else if(workerBee[i][2] == 4) {
numberOfWorkerBees++;
numberOfBirths++;
}else if(workerBee[i][2] == 5) {
numberOfDrones++;
numberOfBirths++;
}
}
}
//Method called once daily
public static void metamorphose() {
numberOfDeaths = 0;
Random random = new Random();
for (int i = 0; i < workerBee.length; i++) {
//Updating the type of bee based on age of Bee
if(workerBee[i][1] == 4) {
workerBee[i][2] = 2;
}else if (workerBee[i][1] == 10) {
workerBee[i][2] = 3;
}else if(workerBee[i][1] == 20){
//Probability for a drone to emerge is 10%(As per area under curve, should be less than or equal to 10%)
double probability = random.nextDouble();
if (probability <= 0.1) {
workerBee[i][2] = 5;//Drone Bee
}else{
workerBee[i][2] = 4;//Worker Bee
}
}
if (workerBee[i][1] == 35 || workerBee[i][1] == 56) {
//Call a funeral
funeral(i);
numberOfDeaths++;
}
}
countTypesOfBees();
}
//To be called at the end of the day
public static void printBeehiveStatus() {
System.out.print("Queen laid " + eggsLaid + " eggs!" +
"\nBeehive status\nEgg Count: "+ totalEggsLaid + "\nLarva Count: " + numberOfLarva + "\nPupa Count: " + numberOfPupa +
"\nWorker Count: "+ numberOfWorkerBees + "\nDrone Count: " + numberOfDrones +
"\nDeath Count: " + numberOfDeaths + "\nBirth Count: "+ numberOfBirths +
"\nHoney Stock: " + honeyStock +"\n");
printFlowerGarden();
}
The index of the fields of the workerBee array are in the order specified above.
The order which which they are executed each day are as follows(Note that they are not the complete set)
addEggToHive(layDailyEggs());
incrementAge();
metamorphose();
printBeehiveStatus();
Screenshot [1]: https://i.stack.imgur.com/qTeuo.png
Screenshot [2]: https://i.stack.imgur.com/eMsHq.png
Note
The eggs hatches into larva when it is 4 days old
If there is anything else that you think might be causing the problem, tell me I'll upload that part of the code.
Found the solution.
Actually, the method incrementAge() was supposed to increase the ages of all bees in the hive by 1 each day. However, I was simply incrementing all ages in the array without checking whether that particular row is an actual bee or not as I had initialized unused rows to 0
I simply don't know where I'm getting it wrong. I've included the whole code. I'm trying to get the percentage part to display 30 distinct values, but it keeps displaying 29. Is there a simple fix to this and am I making this too complicated?
private static final Scanner
stdIn = new Scanner(System.in);
private static Random
rng;
public static void main (String[] args){
long
rngSeed;
int
numberOfFlips,
totalNumberOfRuns = 1,
run = 0;
boolean
theCoin,
tempVal = false;
System.out.println("Welcome to the coin flip analyzer.\n" +
"How many flips?");
numberOfFlips = stdIn.nextInt();
System.out.println("What do you want to seed the random number generator with?");
rngSeed = stdIn.nextLong();
int[]runLength = new int[50];
rng = new Random(rngSeed);
for (int i = 0; i < numberOfFlips; i++) {
theCoin = rng.nextBoolean();
if (i > 0 && theCoin != tempVal) {
if (i < 50) {
System.out.print(run + " ");
}
runLength[run - 1]++;
totalNumberOfRuns++;
run = 1;
}
else
run++;
if (theCoin) {
if (i < 50) {
System.out.print("H");
}
tempVal = true;
}
else {
if (i < 50) {
System.out.print("T");
}
tempVal = false;
}
}
System.out.print("...");
System.out.println();
System.out.println("There were a total of " + totalNumberOfRuns +
" distinct runs in the simulation.\nTheir breakdown follows.");
// run length table header line
System.out.println("[run length] = # (as percentage of all runs)");
// your code to display the count and frequency percentage of each run length
// should follow
for (int i = 0; i < runLength.length; i++) {
double percentageFreq = ((double) + (runLength[i]) / (totalNumberOfRuns) * 100);
if (runLength[i] > 0)
System.out.println("[" + (i+1) + "] = " + runLength[i] + " (" + String.format("%1.1f", percentageFreq) + " %)");
}
}
}
...............
Most Important Part of Outcome Using: 50 flips and a random seed value of 1200.
H1 T1 H1 T1 HHH3 TTTTT5 H1 T1 HHHH4 T1 HH2 T1 H1 T1 H1 T1 H1 T1 H1 TTT3 H1 TTT3 H1 TTTT4 H1 T1 HHH3 TT2 H1 T...
There were a total of 30 distinct runs in the simulation.
Their breakdown follows.
[run length] = # (as percentage of all runs)
[1] = 20 (66.7 %) (I need this to be 21 since the last value is "T").
[2] = 2 (6.7 %)
[3] = 4 (13.3 %)
[4] = 2 (6.7 %)
[5] = 1 (3.3 %)
...............
There are a few problems with your code. The ultimate reason why it's not working is that the final coin flip is not being counted.
The reason why your code is outputing There were a total of 30 distinct runs in the simulation. is because you start totalNumberOfRuns at the wrong value.
totalNumberOfRuns should start at 0 rather than 1.
Also notice how the end of the output for coin flips is T..., there should be a 1 following the T. You need to place that print statement at the end of the loop, otherwise it will only print the number from the previous iteration and simply not run at all for the final iteration.
Also, throughout your code you use magic numbers. E.g. if (i < 50), int[]runLength = new int[50]. Magic numbers are evil and you should never use them. An example of why magic numbers are evil: what if the user enters 100 when asked how many times the coin should be flipped? The code will not run properly in this case. Regardless even if you were not using a magic number here, these conditional statements are pointless because i will never be greater than 50 if you enter 50 for numberOfFlips.
I also am a bit bothered by the styling in your code. Please please please use curly braces even for blocks that are one line long. At the very least, at least be consistent with it. At some points you use curly braces for single-line if statements, but in one spot you don't use curly braces for a single-line else statement.
Also, your print statement where you output the frequencies is very messy. This is a perfect place to use System.out.printf, especially since you are already using String.format inside of the print method. The printf method is a beautiful thing and you should get comfortable with it. Here is what you should use:
System.out.printf("[%d] = %d (%1.1f%%)%n", i + 1, runLength[i], percentageFreq);
I got your code working, and I also cleaned it up a bit. Before you copy and paste this solution, I implore you to think about why my explanation above will fix your code, as well as what I did to clean up your code (e.g. rng should not be static)
Here you go :)
public class Main {
private static final Scanner stdIn = new Scanner(System.in);
public static void main(String[] args) {
int totalNumberOfRuns = 0;
int run = 1;
boolean theCoin, tempVal = false;
System.out.println("Welcome to the coin flip analyzer.\n"
+ "How many flips?");
int numberOfFlips = stdIn.nextInt();
System.out
.println("What do you want to seed the random number generator with?");
long rngSeed = stdIn.nextLong();
Random rng = new Random(rngSeed);
int[] runLength = new int[numberOfFlips];
for (int i = 0; i < numberOfFlips; i++) {
theCoin = rng.nextBoolean();
if (theCoin != tempVal) {
runLength[run - 1]++;
totalNumberOfRuns++;
run = 1;
} else {
run++;
}
if (theCoin) {
System.out.print("H");
tempVal = true;
} else {
System.out.print("T");
tempVal = false;
}
System.out.print(run + " ");
}
System.out.print("...");
System.out.println();
System.out
.println("There were a total of "
+ totalNumberOfRuns
+ " distinct runs in the simulation.\nTheir breakdown follows.");
// run length table header line
System.out.println("[run length] = # (as percentage of all runs)");
// your code to display the count and frequency percentage of each run
// length
// should follow
for (int i = 0; i < runLength.length; i++) {
double percentageFreq = ((double) +(runLength[i])
/ (totalNumberOfRuns) * 100);
if (runLength[i] > 0) {
System.out.printf("[%d] = %d (%1.1f%%)%n", i + 1, runLength[i],
percentageFreq);
}
}
}
}
i wanted to do the guess the number game. For one round my programm works and I can guess a number. I want that the user can enter the amout of rounds (1-20) what he wants to play, but there is my problem this isn't working as thought. I tried to use a boolean but after I guessed the number for 1 round it doesn't begin the next round.
The In function is similar to scanner, but I have a java class for that therefore I use that.
public class GuessNumber {
public static void main(String[] args) {
System.out.println("round 1-20");
int roundTyped = In.readInt();
int rndN = (int) (Math.random()*100)+1;
int typedN = 0;
int trys = 0;
boolean active = true;
int round = 0;
while (active) {
while (typedN != rndN) {
trys++;
System.out.println(trys + ". Versuch:");
typedN = In.readInt();
if(typedN < 1 || typedN > 100) {
System.out.println("ungueltig");
}else if(typedN < rndN) {
System.out.println("groesser");
}else if(typedN > rndN) {
System.out.println("kleiner");
}else if(typedN == rndN) {
System.out.println("korrrekt");
}
}
round++;
if (round == roundTyped) {
active = false;
}
}
}
You set the number to be guessed only once at the start of the program. Therefore, after the user has guessed the correct number once, the remaining rounds will all be completed instantly (the condition of the inner while will always be true).
I would suggest you use a debugger to find problems like these. When you step through your program, it will immediately become obvious what is happening.
Having two while loops is unnecessary, you can put several conditions for the while, and you use 2 variables that will be the same round and trys.
But your biggest problem is that you actually set your active to false right before checking if it is true.
Try something like that :)
System.out.println("round 1-20");
int roundTyped = In.readInt();
int rndN = (int) (Math.random()*100)+1;
int typedN = 0;
int nTrysAllowed = 10; // The max number of tries
int trys = 0;
int round = 0;
while (round < roundTyped) {
while (typedN != rndN && trys < nTrysAllowed) {
trys++;
System.out.println(trys + ". Versuch:");
typedN = In.readInt();
if(typedN<1 || typedN >100) {
System.out.println("ungueltig");
} else if(typedN < rndN) {
System.out.println("groesser");
} else if(typedN > rndN) {
System.out.println("kleiner");
} else {
System.out.println("korrrekt");
}
}
// Here you can reduce the max number of tries for example or do whatever you want. For example:
round++;
if (typedN == rndN) {
// New number to guess
rndN = (int) (Math.random()*100)+1;
// Difficulty
nTrysAllowed--;
trys = 0;
} else {
System.out.println("Game done you can't go to next round, you lose this one.");
round = roundTyped;
}
}
I have created a program which compares different search methods which search for a random int value 0-999 from a sorted array which is 0-999. I have created a binary search which works perfectly and after doing this I decided to try to create a search which, instead of splitting the values into half, splits them into 1/3 and 2/3 depending.
So basically if I have
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
and I was looking for 10 I would go from above to
{6,7,8,9,10,11,12,13,14,15}
to
{10,11,12,13,14,15}
to
{10,11}
then
simple {10} and return the index of this value.
I currently have:
int loopTotal3 = 0;
for(int y = 0; y < 1000; y++){
System.out.println("Reference1");
int first = 0;
int last = array0Through999.length - 1;
int third = (array0Through999[0] + array0Through999[999]) / 3;
int findThis3 = rand.nextInt(1000);
int loop3 = 0;
while(first <= last){
System.out.println("Reference2");
loop3++;
if (array0Through999[third] < findThis3){
System.out.println("Reference3");
first = third + 1;
}
else if(array0Through999[third] == findThis3){
System.out.println("Reference4");
break;
}
else{
System.out.println("Reference5");
last = third-1;
}
third = (first + last) / 3;
}
loopTotal3 = loopTotal3 + loop3;
}
int loopAverage3 = loopTotal3 / 1000;
System.out.println("The average number of times for a Binary Search is: " + loopAverage3 + "\n");
The code is currently getting stuck running through the first if statement and I am not positive of why.
Any ideas about my issue or if this logic is close to correct?
Using the same algorithm on a smaller data set, I can see an issue. Use an array with only 3 members: 0 1 2. Try to find 2. Third will get stuck on 1, and never get up high enough to find 2.
This will infinitely loop never getting third up to 2. You may be hitting a similar window somewhere else in the code. Because it enters the first if, it does first = third + 1 which yields first = 2. third=(first+last)/3=4/3=1.
import java.util.Random;
public class weqfgtqertg {
public static void main(String args[]) {
int array0Through999[] = {0,1,...,999};
int loopTotal3 = 0;
Random rand = new Random();
for(int y = 0; y < 1000; y++){
//System.out.println("Reference1");
System.out.println(y);
int first = 0;
int last = array0Through999.length - 1;
int third = (first + last) / 3;
int findThis3 = rand.nextInt(1000);
int loop3 = 0;
while(first <= last) {
//System.out.println("Reference1");
loop3++;
if (array0Through999[third] < findThis3){
//System.out.println("Reference3");
first = third+1;
}
else if(array0Through999[third] == findThis3){
//System.out.println("Reference4");
break;
}
else{
//System.out.println("Reference5");
last = third-1;
}
int calc = last - first;
third = first + (calc/3);
}//end while
loopTotal3 = loopTotal3 + loop3;
}//end for
int loopAverage3 = loopTotal3 / 1000;
System.out.println("The average number of times for a Tertiary Search is: " + loopAverage3);
}
}
It has been a while since I posted this question but I finally got around to solving my issue. Here is the correct code for anyone who may stumble upon this.
edit: The array includes the "..." to make this not obnoxious to read or put out onto the screen. I had all 0-999 within my array hard coded.
I am very beginner on Java, still getting passion about.
I have been given this exercise: "Write a simulator program that flips a coin: One thousand times then prints out how many time you get tails and how many times you get heads"
That is what i have tried to do so far.
import java.util.Random;
import java.util.regex.Pattern;
public class coin {
public static void main( String [] args ) {
Random r = new Random();
Pattern tail = Pattern.compile("Tail+");
Pattern head = Pattern.compile("Head+");
String flips = "";
for (int i = 0; i < 1000; i++) {
flips += r.nextInt(100) % 2 == 0 ? "Head" : "Tail";
}
String[] heads = head.split( flips );
String[] tails = tail.split( flips );
//Display
System.out.println("Times head was flipped:" + heads.length);
System.out.println("Times tail was flipped:" + tails.length);
}
}
The program seems to be working, but it is giving me always an almost pair amount of heads and tails, which the total exceed 1000, at least by 1 or more.
Please, someone has any solution of this? Where am I wrong?
Thanks
Rather than appending the result in a String and then splitting the string and counting the occurence of "Head"/"Tail" you can just keep track of the count in separate variables :
int headCount = 0;
int tailCount = 0;
for (int i = 0; i < 1000; i++) {
if(r.nextInt(100) %2 == 0)
{
headCount++;
}
else
{
tailCount ++;
}
System.out.println("Times head was flipped:" + headsCount);
System.out.println("Times tail was flipped:" + tailCount);
}
A coin has two sides, so I really don't see why you would ask the random generator to generate a number between 0 and 100 (exclusive). Between 0 and 2 (exclusive) would be much more logical.
Also, you're being asked to count. Appending strings and then splitting to get the final value is quite a complex and inefficient way to count. You should use an integer instead. Each time you get a 1 from your random, increment a counter. In the end, you have the number of times 1 was returned, and the number of 0 is thus 1000 - this number.
Random r = new Random();
int heads = 0;
for (int i = 0; i < 1000; i++) {
int side = random.nextInt(2);
if (side == 1) {
heads++;
}
}
System.out.println("Times head was flipped:" + heads);
System.out.println("Times tail was flipped:" + (1000 - heads));
It could even be simplified to the follwoing (although this simplification makes the code a bit harder to understand):
Random r = new Random();
int heads = 0;
for (int i = 0; i < 1000; i++) {
heads += random.nextInt(2);
}
System.out.println("Times head was flipped:" + heads);
System.out.println("Times tail was flipped:" + (1000 - heads));
I had similar question for my assessment and I tried below code and it worked. May be its not appropriate way of doing.
I am happy to receive feedback! thanks.
for (int i = 1; i < 1000; i++) {
flips += r.nextInt(100) % 2 == 1 ? "Head" : "Tail";
}