Identifying two random sequences in Java - java

I'm writing a program that flips a coin and then outputs whether the result is heads (H) or tails (T):
import java.util.Random;
public class coin {
public static void main (String [] arg) {
Random r = new Random();
int flip = r.nextInt(2);
if (flip == 1) {
System.out.print("H");
} else {
System.out.print("T");
}
}
}
Next, I would like the program to continue flipping the coin until it flips 3 heads in a row.
So for instances, I want it to output the following which stops after it identifies 3 heads:
H T T H T H T H H H
I'm having issues figuring out how to get Java to continue flipping the coins. I've tried implementing a for-loop which let me flip the coin a fixed amount of times, but I would rather that the program figures out how many times the coin is flip by itself. I suspect it should be with a while-loop but I can't seem to figure out how that would be implemented. Any help would be appreciated.

Use a counter to keep track of how many heads have been flipped and loop until 3 heads have been flipped:
Random r = new Random();
int counter = 0;
while(counter <3)
{
int flip = r.nextInt(2);
if (flip == 1) {
System.out.print("H");
counter++;
} else {
System.out.print("T");
counter = 0;
}
}

Somehing like this:
int headsInRow=0;
while(headsInRow<3){
int flip=doFlip();
if(heads)headsInRow++;
else headsInRow=0;
}
ofc it is a pseudocode but you should get the idea.

Related

Simulated Annealing for Sudoku Solving

I'm trying to solve a 9x9 sudoku puzzle using Simulated Annealing, but my implementation doesn't seem to be working correctly. It does not even get closer to a lower-cost solution but instead keeps circling around results that cost between 60 and 80.
My cost function returns the sum of three things: Number of repeating digits in each row, column and block (3x3).
And the successor (neighbour) function i implemented changes two randomly selected digits from the 9x9 grid with random values.
And here is my SA function that doesn't work as expected:
public static void simulatedAnnealing() {
Sudoku neighbour; // candidate successor object
final Double temperature = 2.0; // initial temperature
final Double coolingFactor = 0.999; // cooling constant
final int maxIterations = 1000; // number of iterations
for(Double t = temperature; t>1; t*=coolingFactor) {
for(int i = 0; i < maxIterations; i++) {
neighbour = sudoku.generateSuccessor(); // set random neighbour
int delta = neighbour.cost() - sudoku.cost(); // calculate delta
if (delta <= 0) {
sudoku = neighbour; // always accept good step.
} else {
if (Math.exp(-delta / temperature) > Math.random()) { // Simulated annealing
sudoku = neighbour;
}
}
}
System.out.println(sudoku.cost());
if(sudoku.cost() == 0) { break; } // if puzzle is solved
} }
Function for generating successors:
public Sudoku generateSuccessor() {
int[][] newGrid = new int[9][9];
for(int o = 0; o < 9; o ++) { // cloning current grid array
for(int g = 0; g < 9; g ++) {
newGrid[o][g] = grid[o][g];
}
}
Sudoku rndm = new Sudoku(newGrid); // random Sudoku object.
for (int i = 0; i < 2; i++) { // will randomize 2 cells in 9x9 grid.
int rndmCell = rndmValue(); // random digit for randomizing.
int randomRow = rndm(); // random row that will be randomized
int randomCol = rndm(); // random column that will be randomized
// prevent randomizing given cells in sudoku (in problem definition)
boolean shouldContinue = false;
for (Coordinate c : SudokuSolver.concreteCoordinates) {
if (c.row == randomRow && c.col == randomCol) {
shouldContinue = true;
break;
}
}
if (shouldContinue) {
i--;
continue;
}
// prevention end.
rndm.grid[randomRow][randomCol] = rndmCell;
}
return rndm;
}
Cost function:
public int cost() {
if(hasZeros()) { // if grid is not totally filled with numbers don't calculate its cost.
return -1;
}
int cost = 0;
for(int i = 0; i< 9; i++) { // find total collusions in rows&columns.
cost += findNumberOfCollusions(grid[i]); // find collustions at row 'i'.
cost += findNumberOfCollusions(getColumn(grid,i)); // find collustions at column 'i'.
}
for(int r = 0; r < 9; r += 3) { //find total colusions in blocks (3x3).
for(int c = 0; c < 9; c += 3) {
int[] block = new int[9];
int ctr = 0;
for (int i = r; i < r + 3; i++) {
for (int y = c; y < c+ 3; y++) {
block[ctr] = grid[i][y];
ctr++;
}
}
cost += findNumberOfCollusions(block);
}
}
return cost;
}
When i run the program the output is costs between 60 and 80. After that the temperature goes below the limit and the program outputs a solution that costs around that interval. Can anyone tell me what am i doing wrong? Thanks in advance.
I also had a similar problem to the one you describe, my fitness remained stuck (actually though, my problem was with not copying lists in Python). I can't really assure why your code gets stuck, but if I had to guess: the neighbor generation (int rndmCell = rndmValue(); int randomRow = rndm(); int randomCol = rndm();) may be actually doing more harm than good. Imagine that you have a nearly complete sudoku, but out of the blue two of the correct cells that you had now change their value to a complete opposite one, which is not only wrong on the cell itself but also on the row, column and/or 3x3 square. I'm no mathematician, but logic tells me that the more fitting the sudoku is (i.e. the closer its fitness is to 0), the more chances there are to mess up the sudoku by randomly changing cells. This approach may get you stuck on a local minimum easily.
A more "informed" solution for this problem would be to keep one of the three basic restrictions of the sudoku puzzle fixed by, for instance, generating rows that are permutations of the values [1..9], swapping two cells of a random row (thus still fulfilling the restriction), and calculating the fitness only on the columns and on the 3x3 squares. This choice of neighbor generation is usually more effective. If you are interested, this idea comes from the paper Metaheuristics can solve Sudoku puzzles. I can say that this idea helped me a lot and now the algorithm completes sudokus that I provide :)

Randomly generated number of X's

I need a program to randomly generate a number, and then out put that number of x's, on there own line, until it outputs a line of 16 x's, and then it will stop. So far my program generates a number but never stops outputting. I'm sure this is my error but not sure what needs to change. Here is my code at this moment.
import java.util.Random;
public static void main(String[] args)
{
toBinary();
randomX();
}
public static void randomX()
{
Random num = new Random();
int ran = num.nextInt(16+1);
int xs = ran;
while(xs <= 16)
{
System.out.print("x");
}
}
Your version has a number of small issues. Here's a suggested set of revisions.
// create your random object outside the method, otherwise
// you're instantiating a new one each time. In the long run
// this can cause awkward behaviors due to initialization.
public static Random num = new Random();
public static void randomX(){
int ran;
do {
ran = 1 + num.nextInt(16); // move the +1 outside unless you actually want 0's
int counter = 0;
while(counter++ < ran) {
System.out.print("x");
}
System.out.println(); // add a newline after printing the x's in a row
} while(ran < 16);
}
The biggest issue is that you need two loops, an outer one for generating new numbers and an inner one for printing the current number of x's.
A secondary problem was that your loop was checking for numbers <= 16. All of your values are <= 16, so it was an infinite loop.
Additional suggestions found in the comments.
To approach this, think of the loops you might need.
You need to print x a certain number of times, that's a loop. I also introduce a variable to keep track of this printing.
You need to keep printing until you hit 16. That's another loop.
public static void randomX(){
Random num = new Random();
int xs = 0;
//This loop keeps going until you reach 16
while(xs <= 16){
xs = num.nextInt(16+1);
int x = 0;
//This loop keeps going until you've printed enough x's
while (x < xs)
{
System.out.print("x");
x++;
}
System.out.println("")
}
}
You can use a auxiliary counter to manage the loop and increase it to exit the loop.
int i = 0;
while (i<xs){
System.out.print("x");
i++;
}
You can check more about java loops here:
Tutorial about java while

Counter for calculate number of runs in java

Here is my code which take an input value and compare it with a random value
I have 15 times to run the code to estimate and get the input value equals to the random value which the code decide ...
I want to make a counter to calculate how many times I did run the code ...
I tried to put count++; in different places in the code but I did not get right answer ... Where do you think that count++; should be put to get number of runs in the out put ...
thanks
Here is my code
package person;
import java.util.Random;
import java.util.Scanner;
public class Cat {
public static void main(String[] args) {
int max = 100;
int min = 0;
int diff = max-min;
Random rn = new Random();
int i = rn.nextInt(diff+1);
i+=min;
for (int k=0; k<15; k++){
int count=0;
Scanner sb = new Scanner(System.in);
System.out.println("Enter your number");
int x = sb.nextInt();
if(x>i){
System.out.println(x+"is bigger than i");
} else if(x<i){
System.out.println(x+"is smaller than i");
} else if (x==i){
System.out.println(x+"is equals to i "+" "+" no. of try"+count);
break;
}
}
}
}
The problem with your approach was that you count was in the loop so it would always be reseted. you can move it outside the loop or just print the counter loop variable.
package person;
import java.util.Random;
import java.util.Scanner;
public class Cat {
public static void main(String[] args) {
int max = 100;
int min = 0;
int diff = max-min;
Random rn = new Random();
int i = rn.nextInt(diff+1);
i+=min;
int k;
for (k=0; k<15; k++) {
Scanner sb = new Scanner(System.in);
System.out.println("Enter your number");
int x = sb.nextInt();
if(x>i) {
System.out.println(x+"is bigger than i");
} else if(x<i) {
System.out.println(x+"is smaller than i");
} else if (x==i) {
System.out.println(x+"is equals to i "+" "+" no. of try"+k+1);
break;
}
}
if(sb !=null) {
sb.close();
}
}
}
That's because you're setting count = 0 in your for loop. move
int count = 0;
above the for loop and add
count++;
at the beginning of the for-loop. If you had it at the end, you wouldn't count the last run when the loop might break out. Having it at the beginning of the loop means you definitely count each time you even start the process of looking for the randomly generated number.
But it would actually be better to just use the look counter k to keep track of the number of time. No need to waste the extra space on another variable when you already have k to keep track of everything. Just be careful because k starts at 0, so make sure you add 1 to your number of runs if using k.

How to recall a function, Sieve of Eratosthenes

I'm trying to write code that will work out prime numbers using the sieve of Eratosthenes. I have to include a function that will take in a number and cross of all of the multiples of that number. For testing I set the first number to be 2 and the second as 3. It works for the first number but never for the second(no matter the order of the numbers i.e if I put 3 into the function first). I know there are other completed sieve of Eratosthenes out there but I wanted to try and do it in the way that I thought of first.
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
System.out.println("Which number would you like to calculate up to?");
int n = input.nextInt();
input.close();
int x = 0;
int newNumber = 2;
int numbers[] = new int[n];
while(newNumber <= n){
numbers[x] = newNumber;
x++;
newNumber++;
}
int currentNumber = 2;
int finalNumber[] = markOfMultiples(n, numbers, currentNumber);
for(int y = 0;y < n-1;y++){
System.out.print(finalNumber[y] + ", ");
}
currentNumber = 3;
int secondNumber[] = markOfMultiples(n, numbers, currentNumber);
for(int y = 0;y < n-1;y++){
System.out.println(secondNumber[y]);
}
}
public static int[] markOfMultiples(int n, int numbers[], int currentNumber){
int originalNumber = currentNumber;
while(currentNumber<n){
currentNumber = currentNumber + originalNumber;
int count2 = 0;
while(currentNumber != numbers[count2] && currentNumber<=n && count2<n){
count2++;
}
numbers[count2] = 0;
}
return numbers;
}
The error I'm getting is: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 20
at sieveOfEratosthenes.sieveOfEratosthenes.markOfMultiples(sieveOfEratosthenes.java:46)
at sieveOfEratosthenes.sieveOfEratosthenes.main(sieveOfEratosthenes.java:28)
Line 28 is when I recall the function:int secondNumber[] = markOfMultiples(n, numbers, currentNumber);
And line 46 is while(currentNumber != numbers[count2] && currentNumber<=n && count2<20){
Any help would be much appreciated. How do I keep on calling the function?
p.s. Please excuse the variable names as I'll be changing them when I get the program working.
If you want to get this approach working, you can do the fix advised by #Thierry to check count2 < n first in your while loop and then also surround the line
numbers[count2] = 0
with an if clause to check count2 is not beyond the end of the index. e.g.
if (count2 < n) {
numbers[count2] = 0;
}
Your final challenge is how you call your markOfMultiples() function enough times when n gets a bit larger. It's not a problem with your fundamental approach - you can definitely do it and your approach will work well and have acceptable performance for low-ish numbers (say up to 10000).
However
I realise this is an assignment and you want to do it your way, but there are a few features of your approach which you might want to consider - maybe after you've got it working.
Readability - is it going to be easy for someone looking at (marking) your code to understand what it's doing and verify that it will do the right thing for all values of n?
Try not to repeat yourself - for instance consider where you fill your numbers array:
while(newNumber <= n){
numbers[x] = newNumber;
x++;
newNumber++;
}
Will x ever be different to newNumber? Did you need both variables? This sort or repetition occurs elsewhere in your code - the principle to stick to is known as DRY (Don't Repeat Yourself)
Is there an easier way to move the index on originalNumber places in your markOfMultiples() method? (HINT: yes, there is)
Do you really need the actual numbers in the numbers[] array? You're going to end up with a lot of zeros and the primes left as integer values if you work out how to call your markOfMultiples repeatedly for high values of n. Would an array of 1s and 0s (or trues and falses) be enough if you used the array index to give you the prime number?
You need to test if count2 < n BEFORE access to numbers[count2]:
while(count2 < n && currentNumber != numbers[count2] && currentNumber<= n){
count2++;
}

Rolling-dice class and driver

alright so i have to write a class and driver that has the user input the number of dice and the number of rolls. and then i have to make an array based off the number of dice * 6. but i get errors. like arrayindexoutofboundsexception.
after i make the array i have to fill it with random numbers and use a histogram to display the program. so the program should look like this
Please give any positive help here, im new to this programing this and i would love to learn more. also i cant seem to figure out if statements for the Y/N area to start the program
Welcome to the dice-rolling simulator!
Do you wish to run a simulaton? Y/N: x
that was an invalid option. Please try again.
Do you wish to run a simulation? Y/N: y
How many dise di you wish to roll? 2
How many rolls to you wish to make? 100000
2:######
3:####
4:###########
5:#####
6:##
7:#
8:
9:##########
10:###
11:##############
12:######
//I had to you # signs because * would not work here
here is my program updated! how do i create the histogram?
package dice;
import java.util.Scanner;
import java.util.Random;
public class Dice
{
public static Scanner in = new Scanner (System.in);
private int dice = 0;
private int roll = 0;
private int start;
private int[] diceAr;
private int[] rollAr;
private int simDice;
private String star = "*";
//****************************************************************
public Dice()
{
System.out.println("Welcome to the dice-rolling simulator!\n");
System.out.println("Do you wish to run a simulation? Y/N; ");
//start = in.nextInt();
while (true) {
System.out.print ("How Many Dice Do You Want To Roll? ");
dice = in.nextInt();
simDice = (dice * 6)-1;
diceAr = new int[simDice];
if (dice > 0)
break;
}
while (true) {
System.out.print ("How Many Times Do You Want To Roll? ");
roll = in.nextInt();
rollAr = new int[roll];
if (roll > 0)
break;
}
}
//**********************************************
// public void display()
// {
//
for ( int i = 0; i < simDice; i++)
// {
// diceAr[i] = (int)(Math.random()* simDice);
//
// }
// for(int i = 0; i<simDice; i++)
// {
// System.out.println((i + dice) + ". " + diceAr[i]);
// }
//
// }
//*********************************************************
public void display(int diceAr[], int simDice, int roll)
{
for(int i=0; i < simDice; i++)
{
diceAr[i] = (int) (Math.random()* simDice);
}
for(int i=0; i < roll; i++)
{
}
}
}
Judging from the wording of the questions the program asks and the sample histogram you give, it appears the assignment is to write a program to simulate rolling N dice M times and then make a histogram of the results (i.e. the sum of the numbers on the dice on each roll) of the rolls. So if you enter 3 dice and 100 rolls, it should be as if you rolled 3 dice by hand 100 times.
Even aside from the ArrayIndexOutOfBoundsException issue, that is not what your code is doing. Since this is admitted homework I'm not going to give any code, at least not at this point. But I do have some suggestions/questions that might help you think about the problem better and perhaps you can show us how you've changed your code after thinking about it.
First, consider actually doing the task manually. Find two or three dice and roll them, say, 20 times, and make a histogram of the result on paper. You may find just doing that by itself will give you lots of insight into what your program will have to do and keep track of.
Next, here are some questions that might help focus your thinking:
If you are rolling 2 dice, what's the lowest possible result of a roll? What's the highest?
If you are rolling 3 dice, what's the highest and lowest possible result of a roll?
If you are rolling N dice, what's the highest and lowest possible result of a roll?
When you simulate a roll, how do you determine what the result of the roll is?
What array should you track those results in and how big should it be?
How do you track the results in such a way that you can make a histogram later?
What, if anything, besides the results do you need to store?
Think this all over, do the "experiment" manually, and then get back to us with what changes you've made to your program and what new questions you may have.
You're declaring diceAr to be size 'dice', but then indexing it with a variable which goes up to 'simDice', which = dice * 6.

Categories