Why is my Java Tortoise and Hare Race not displaying properly? - java

I have seen several questions about the Tortoise and Hare Race but they are all pertaining to applets and I am not programming an applet. The program is meant to I am having some trouble with the display output of my program. I would like to have the program display an output that looks something like this:
______T__________H________________________________
__________T_______________________H_______________
_____________T________H___________________________
etc. until either the tortoise or the hare reaches the end and wins the race. As of right now, my output looks like this:
______________________________HT__________________________________________________HT__________________________________________________HT_
over and over in what seems to be an infinite loop. Here is my code:
public class TortoiseAndHair {
public static void main ( String [] args )
{
int t = 0; // Keeps track of tortoise progress
int h = 0; // Keeps track of hare progress
System.out.println( "AND THEY'RE OFF!!" );
while (t < 50 || h < 50)
{
hareMove( h );
tortoiseMove( t );
if (t>1 && h> 1 && t == h) // Display when tortoise and hare occupy same space beyond start
{
System.out.print( "OUCH!!");
}
if ( t < 1 )
{ // Prevents tortoise from slipping behind start
t = 1;
}
if ( h < 1 )
{ // Prevents hare from slipping behind start
h = 1;
}
if ( t > 50 )
{ // Prevents tortoise from going passed finish line
t = 50;
}
if ( h > 50 )
{ // Prevents hare from going passed finish line
h = 50;
}
for ( int count = 1; count <= 50; count++)
{
System.out.print( "_" );
if ( count == h )
{
System.out.print( "H" );
}
if ( count == t )
{
System.out.print( "T" );
}
}
if (h < 50 && t == 50)
{ //Output if tortoise wins
System.out.print( "TORTOISE WINS!!" );
}
if ( t < 50 && h == 50)
{ // Output if hare wins
System.out.print( "HARE WINS!!" );
}
if ( h == 50 && t == 50)
{
System.out.print( "IT'S A TIE!!" );
}
}
}
/**
* This method will calculate the random integer that will dictate the tortoise's movements on the board,
* use that random integer to determine the tortoise's movements (tMove), and add that to the counter keeping track
* of the tortoise's position
* #param t is an int variable that is keeping track of the tortoises position on the board
* #return the tortoise's current position on the board after that turn
* Pre-Conditions: n is an int between 1 and 10, t is a positive int greater than 0 and less than 50
*/
public static int tortoiseMove (int t)
{
int n;
int tMove = 0;
n = (int) ( 10 * Math.random() ) + 1; // Generates random number between 1 and 10
if ( n > 10 )
{ // ensures n doesn't go higher than 10
n = 10;
}
// Series of if/else statements to control tMove
if ( n >= 1 && n <= 5)
{ // Fast plod if n is between 1 and 5
tMove = 3;
}
else
{
if ( n >= 6 && n <= 8)
{ // Slow Plod if n is between 6 and 8
tMove = 1;
}
else
{
if ( n == 9 || n == 10 )
{ // Slip if n is 9 or 10
tMove = -6;
}
}
}
// Add determined movement to tortoise counter and return that value
t += tMove;
return t;
}
/**
* This method will calculate the random integer that will dictate the hare's movements on the board,
* use that random integer to determine the hare's movements (hMove), and add that to the counter keeping track
* of the hare's position on the board
* #param h is an int variable keeping track of the hare's current position on the board
* #return the hare's position on the board after current turn
* Pre-Condition: n is an int between 1 and 10, h is a positive int greater than 0 and less than 50
*/
public static int hareMove (int h)
{
int n;
int hMove = 0;
n = (int) ( 10 * Math.random() ) + 1; // Generates random number between 1 and 10
if ( n > 10 )
{ // ensures n doesn't go higher than 10
n = 10;
}
//Series of if/else statements to control hMove
if ( n == 1 || n == 2 )
{ // Big hop if n is 1 or 2
hMove = 9;
}
else
{
if ( n >= 3 && n <= 5)
{ // Small hop is n is between 3 and 5
hMove = 1;
}
else
{
if ( n == 6 )
{ // Big slip is n is 6
hMove = -12;
}
else
{
if ( n == 7 || n == 8 )
{ // Small slip if n is 7 or 8
hMove = -2;
}
else
{
if ( n == 9 || n == 10 )
{ // Hare falls asleep if n is 9 or 10
hMove = 0;
}
}
}
}
}
// Add determined movement to hare counter and return value of h
h += hMove;
return h;
}
}

You never reassign h and t after moving
h = hareMove( h );
t = tortoiseMove( t );
Primitives are passed by value, so whatever change you made to h and t in the move method are not reflected in the original values.

Related

How to change value of 2D bool array?

I have this assignment for school:
Imagine a chess board and an ant. The ant is randomly put on the
board and after that it can walk up, down, left and right (not diagonally). The ant cannot walk over the edge of the chess board
(if it tries, it is not counted as a movement). The task is to create
a program called Ants.java that simulates the walking over the
chess board of an ant. To walk to another square than the one
the ant is currently on is called a “step” (even though it will take
the ant several steps to move…). Each simulation should calculate the number of “steps” the ant takes to visit all squares on
the chess board. The simulations must be done ten times and
an average should be calculated at the end of the simulation.
An example run of the simulation is shown below:
Ants
Number of steps in simulation 1: 708
Number of steps in simulation 2: 818
Number of steps in simulation 3: 953
Number of steps in simulation 4: 523
Number of steps in simulation 5: 671
Number of steps in simulation 6: 338
Number of steps in simulation 7: 535
Number of steps in simulation 8: 702
I am quite sure that I'm about 95% done. However, I need an array to store bool values, to see if the ant has visited the square on the board or not. I can't really figure out how to do it. Ignore the "isVisited", it was my first idea.
This is my code right now:
public static void main(String[] args) {
// Sums every step in the 10 iterations
double totalNumber = 0;
boolean[][] grid = new boolean[8][8];
for (int r = 0; r< grid.length; r++)
{
for (int c = 0 ; c<grid[0].length; c++)
{
grid[r][c] = false;
}
}
// Just a loop to make the ant walk 10 times
for (int k = 1; k <= 10; k++) {
// Setting board to false, not visited
boolean isVisited = false;
// Creating spawn points
int x = (int) (Math.random() * (8 + 1)) + 1;
int y = (int) (Math.random() * (8 + 1)) + 1;
// Setting spawn point to
isVisited = true;
// Variables, steps, min coord and max coords
int count = 0;
int minY = 1;
int maxY = 8;
int minX = 1;
int maxX = 8;
// All the unchecked places
int unchecked = 64;
// Places where the ant has been
int alreadyChecked = 0;
// While there's more than 0 unchecked places, random 1 - 4
while (unchecked > 0) {
int random = (int) (Math.random() * 4 + 1);
// West
if (random == 1) {
// Move to the left
x--;
// If the ant falls off
if (x < minX) {
// Bump it back
x++;
}
// If the place is visited
if (isVisited) {
// Already checked
alreadyChecked++;
// Count step anyway
count++;
}
// If it's not
if(!isVisited) {
// Set to visited
isVisited = true;
// Remove 1 from the unchecked
unchecked--;
// And take a step
count++;
}
}
// East
if (random == 2) {
x++;
if (x > maxX) {
x--;
}
if (isVisited) {
alreadyChecked++;
count++;
}
if(!isVisited) {
isVisited = true;
unchecked--;
count++;
}
}
// North
if (random == 3) {
y++;
if (y > maxY) {
y--;
}
if (isVisited) {
alreadyChecked++;
count++;
}
if(!isVisited) {
isVisited = true;
unchecked--;
count++;
}
}
// South
if (random == 4) {
y--;
if (y < minY) {
y++;
}
if (isVisited) {
alreadyChecked++;
count++;
}
isVisited = true;
unchecked--;
count++;
}
}
/**
* This simulation assumes Ant movement is discrete relative to grid cells
* i.e. its either in one of these cells at a time, overlapping two cells in not allowed!!
* **/
public class AntMovementSimulation
{
int onBoard[][] = null;
int antPosX = 0;
int antPosY = 0;
int antPrevPosX = 0;
int antPrevPosY = 0;
int directionOfMovement = 0;
int stepsCount = 0;
AntMovementSimulation()
{
onBoard = new int[8][8];
//initialize each position in onBoard to -1 ,implying Ant has not been placed yet, not even once!!
for( int i = 0 ; i < 8 ; i++ )
{
for( int j = 0 ; j < 8 ; j++ )
{
onBoard[i][j] = -1;//implying Ant has not been placed yet, not even once!!
}
}
//place Ant in random cell
antPosX = (int)Math.round(Math.random()*7);//generating random number between 0 and 7, since index is from 0 to 7 as there are 8 cell!!
antPosY = (int)Math.round(Math.random()*7);
//assigning 1 to onBoard at index antPosX,antPosY to indicate Ant has been placed there
onBoard[antPosX][antPosY] = 1;
}
/*this function returns false if any cell has -1,else true
* cause when all cells have been traversed , each cell have non negative value,either 0 or 1
* */
public boolean areAllCellsTraversed()
{
boolean result = true;
for( int i = 0 ; i < 8 ; i++ )
{
for( int j = 0 ; j < 8 ; j++ )
{
if( onBoard[i][j] == -1 )//implying this cell not traversed yet,i.e Ant not placed in this cell yet!!
{
result = false;
}
}
}
return result;
}
public void simulate()
{
//loop while all cells have been not traversed
while( !areAllCellsTraversed() )
{
directionOfMovement = (int)Math.round(Math.random()*3);//generating random number between 0 and 3
switch( directionOfMovement )
{
case 0://move left-to-right
antPosX += 1;
if( antPosX >= 7 ) antPosX = 0; //since largest array index is 1 less than its size, we compare with 7 instead of 8
break;
case 1://move right-to-left
antPosX -= 1;
if( antPosX <= 0 ) antPosX = 7;
break;
case 2://move top-to-bottom
antPosY += 1;
if( antPosY >= 7 ) antPosY = 0;
break;
case 3://move bottom-to-top
antPosY -= 1;
if( antPosY <= 0 ) antPosY = 7;
break;
}
//assign 0 to previous position, meaning Ant is no longer there
onBoard[antPrevPosX][antPrevPosY] = 0;
//assign 1 to new position , meaning Ant is here
onBoard[antPosX][antPosY] = 1;
stepsCount++;
antPrevPosX = antPosX;
antPrevPosY = antPosY;
}
//once all cells have been traversed , print result!!
printSteps();
}
/*prints the total number of step taken to traverse all cells*/
public void printSteps()
{
System.out.println("Total steps taken by Ant to traverse all cells = "+stepsCount);
}
public static void main(String[] args)
{
int sumOfTotalNumOfSteps = 0;
AntMovementSimulation[] amsArray = new AntMovementSimulation[10];
for( AntMovementSimulation ams: amsArray )
{
ams = new AntMovementSimulation();
ams.simulate();
sumOfTotalNumOfSteps += ams.stepsCount;
}
System.out.println("Average num of steps taken by Ant to traverse all cells = "+ sumOfTotalNumOfSteps/10);
}
}

Assign new value to double in a for loop after 6 iterations

I cant figure out why x=x-z gives me the values it does.
x is supposed to decrease its value by z every 6th loop, for 1000 loops, making it less probable that mrnd (math random) is greater than poa (probability of acceptance).
int i = 0;
double y = 0.9;
double x = 1.0;
double z = 0.1;
for (int o = 0; o < 1000; o++) {
for (i = 0; i < 6; i++) {
Double random = Math.random();
Double mrnd = Math.floor(random*100)/100;
double poa = (x*y);
System.out.println("randomkalk " + mrnd);
System.out.println("probability" + poa);
if (poa < mrnd ) {
System.out.println("accept change");
};
if (poa > mrnd ) {
System.out.println("deny change");
}
}
System.out.println(x-z); // This gives the right output if x=x-z is not present
System.out.println(" nr 6 \n \n ");
x = x-z; // Gives wrong output
}
As M. Prokhorov points out, you're not doing anything every 6th iteration. You're doing something 6 times every iteration. Making another loop inside your loop will only add more iterations of something; instead, try checking the counter on the outside loop.
int i = 0;
double y = 0.9;
double x = 1.0;
double z = 0.1;
for (int o = 0; o < 1000; o++) {
Double random = Math.random();
Double mrnd = Math.floor(random*100)/100;
double poa = (x*y);
System.out.println("randomkalk " + mrnd);
System.out.println("probability" + poa);
if (poa < mrnd ) {
System.out.println("accept change");
};
if (poa > mrnd ) {
System.out.println("deny change");
}
if (o % 6 == 5) {
x = x-z;
}
}
Here, I use the modulus operator to check if we are on the 6th iteration
0 % 6 == 0
1 % 6 == 1
2 % 6 == 2
3 % 6 == 3
4 % 6 == 4
5 % 6 == 5 decrement
6 % 6 == 0
7 % 6 == 1
8 % 6 == 2
9 % 6 == 3
10 % 6 == 4
11 % 6 == 5 decrement
12 % 6 == 0

Java infinite method run

I make a class to make Arithmetic operations on rational numbers the problem is when I run the program it keeps running and never stops or show results after many tries I discovered that the problem is the reduce method it is just stuck and never completed . any ideas ?
private void normalize() {
if ( (this.num > 0 && this.den < 0) || (this.num < 0 && this.den < 0)){
this.num = -this.num;
this.den = -this.den;
}
}
private void reduce(int n , int d) {
int r , L = 0;
while ( (n!=0) && (d!=0) ) {
if (this.den > this.num)
r = den % num ;
else
r = num % den ;
while (r != 0 ){
for ( int i= r ; i>0 ; i-- ){
if (den % i == 0 && num % i == 0 )
L = i ;
}
num = num / L ;
den = den / L ;
}
}
}
public Rational (int num , int den) {
this.num = num ;
this.den = den ;
normalize();
reduce (this.num , this.den) ;
}
I think I see the source of your confusion. You're passing num and den to reduce(int n, int d), but n and d get assigned the same value as num and den, not the same reference. As such, even though the values of num and den are changing in the while loop, those changes aren't reflected in the values of n and d.
Note also that you're doing division on integers and assigning the result to integers, which may be mathematically undesirable.
One other thing: Even after you fix the problem with n and d, you have an inner while loop that will never exit, because the value of r never changes. You need to update the value of r in the loop so that it eventually becomes 0.
The problem with your loop is that you're never changing the value of r, which contains the terminal value
while (r != 0 )
{
for ( int i= r ; i>0 ; i-- )
{
if (den % i == 0 && num % i == 0 )
L = i ;
}
num = num / L ;
den = den / L ;
}
Somewhere within your while loop, you need to decrement r, or create a condition to help it reach 0.

Optimizing the largest palindrome from product of two three digit numbers?

I am working on an interview question which I was asked in which I was supposed to write a program to find the largest palindrome from product of two three digit numbers.
Here is the question
I came up with this brute force approach which starts from bottom.
public class LargestPalindromeQuestion {
public static void main(String[] args) {
int value = 0;
for (int i = 100; i <= 999; i++) {
for (int j = i; j <= 999; j++) {
int value1 = i * j;
if (isPalindrome(value1) && value < value1) {
value = value1;
}
}
}
System.out.println(value);
}
private static boolean isPalindrome(final int product) {
int p = product;
int reverse = 0;
while (p != 0) {
reverse *= 10;
reverse += p % 10;
p /= 10;
}
return reverse == product;
}
}
They asked me what are the optimizations I can do in this program? I mentioned that we can try pruning the search space and optimize checking step for each item in the search space but then I am confuse how would I make this work in my above solution?
What are the optimizations we can do in this program? Right now it is executing 810000 steps to find the largest palindrome.
What is the least number of steps we can execute to find the largest palindrome in two three digit numbers?
The program looks very good to me. I would make the i loop count from 999 down to 100, and I would only check j values that would actually give a larger product than the current maximum.
This program is able to finish surprisingly soon, at i == 952 to be precise. The mathematical reason for this is that once the solution 906609 (993 * 913) is found, it will no longer be possible to find a larger palindrome where the larger factor is less than the square-root of 906609, which is 952.160....
public static void main(String[] args) {
int value = 0;
for (int i = 999; i >= 100; i--) {
int r = value / i;
if (r >= i) {
System.out.println("We broke at i = " + i);
break;
}
for (int j = i; j > r; j--) {
int value1 = i * j;
if (isPalindrome(value1)) {
value = value1;
break;
}
}
}
System.out.println(value);
}
One pretty simple way of optimizing this would be to simply start with the highest 3-digit numbers instead of the smallest. Since the solution will most likely be closer to the pair (999 , 999) than to (100 , 100).
One useful mechanism to prune the search tree is to notice that the highest digit of the product a * b doesn't change often. E.g.
a = 111; b = 112 a*b = 12432
; b = 113 a*b = 12543
; b = 114 a*b = 12654
; ...
; b = 180 a*b = 19980
; b = 181 a*b = 20091 = (19980 + a)
Thus, for all the values in between (a = 111, a < b < 181), one already knows the MSB, which must equal to the LSB or (a % 10) * (b % 10) % 10 == MSB.
e.g.
LSB = 1 --> a % 10 == 1, b % 10 == 1
OR a % 10 == 3, b % 10 == 7
OR a % 10 == 7, b % 10 == 3
OR a % 10 == 9, b % 10 == 9
Most of the time there's either none, or just one candidate in set 'b' to be checked for any pair MSB, a % 10.
The least number of steps I could get to is 375. Consider multiplying the three-digit number, a1a2a3, by the three-digit number, b1b2b3:
JavaScript code:
var modHash = new Array(10);
var iterations = 0;
for (var i=1; i<10; i++){
modHash[i] = {0: [0]}
for (var j=1; j<10; j++){
iterations ++;
var r = i * j % 10;
if (modHash[i][r])
modHash[i][r].push(j);
else
modHash[i][r] = [j];
}
}
var highest = 0;
function multiples(x,y,carry,mod){
for (var i in modHash[x]){
var m = (10 + mod - i - carry) % 10;
if (modHash[y][m]){
for (var j in modHash[x][i]){
for (var k in modHash[y][m]){
iterations ++;
var palindrome = num(9,modHash[y][m][k],x,9,modHash[x][i][k],y);
if (x == 3 && mod == 0){
console.log(x + " * " + modHash[x][i][j] + " + "
+ y + " * " + modHash[y][m][k] + ": " + palindrome);
}
var str = String(palindrome);
if (str == str.split("").reverse().join("") && palindrome > highest){
highest = palindrome;
}
}
}
}
}
}
function num(a1,a2,a3,b1,b2,b3){
return (100*a1 + 10*a2 + a3)
* (100*b1 + 10*b2 + b3);
}
var a3b3s = [[7,7,4],[9,1,0],[3,3,0]];
for (var i in a3b3s){
for (var mod=0; mod<10; mod++){
var x = a3b3s[i][0],
y = a3b3s[i][1],
carry = a3b3s[i][2];
multiples(x,y,carry,mod);
}
}
console.log(highest);
console.log("iterations: " + iterations);
Output:
3 * 0 + 3 * 0: 815409
3 * 7 + 3 * 3: 907809
3 * 4 + 3 * 6: 908109
3 * 1 + 3 * 9: 906609
3 * 8 + 3 * 2: 907309
3 * 5 + 3 * 5: 908209
3 * 2 + 3 * 8: 907309
3 * 9 + 3 * 1: 906609
3 * 6 + 3 * 4: 908109
3 * 3 + 3 * 7: 907809
906609
iterations: 375
First optimize isPalindrome by seperating 6 digits as 3 digits. i.e. N = ABCDEF => a = ABC = N/1000, b = DEF = N%1000; Then reverse b and return a==reversed_b;
Secondly while producing palindromes loop through till max_palindrome_so_far/999 which is the minimum value that you would use. max_palindrome_so_far is initially equals N.
public class Solution {
public static boolean isPalindrome(int n){
int a = n/1000;
int b = n%1000;
int d, r = 0, i = 3;
while(i-- > 0){
d = b%10;
r = r*10 + d;
b = b/10;
}
if (a == r)
return true;
return false;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
for(int a0 = 0; a0 < t; a0++){
int n = in.nextInt();
int r=0, m=n;
int i,j;
for(i = 999;i>=100;i--){
for(j = 999;j>=m/999;j--){
if (i*j < n && i*j > 100000 && isPalindrome(i*j)){
r = Math.max(i*j, r);
m = r;
}
}
}
// System.out.println(i + " * " + j + " = " + i*j);
System.out.println(r);
}
}
}

Printing a frame within frame

I got this assignment in Java and I don't have a single clue on how to do it.
The task is to receive an integer n > 0, and to print n number of frames constructed by * inside each other, while the inner frame will have the letter "X" constructed by 4n+1 *.
I can't use arrays or strings.
For example:
n=1 will print:
*******
* *
* * * *
* * *
* * * *
* *
*******
n=2 will print:
*************
* *
* ********* *
* * * *
* * * * * *
* * * * * *
* * * * *
* * * * * *
* * * * * *
* * * *
* ********* *
* *
*************
This is what I have so far:
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int size = n * 6 + 1;
int x = 1;
int y = 1;
for (int i = 0; i < n; i = i + 1) {
for (int i3 = 0; i3 < size; i3 = i3 + 1) {
System.out.print("*");
}
System.out.println("");
y = y + 1;
for (int i1 = 0; i1 < size - 2; i1 = i1 + 1) {
System.out.print("*");
for (int i2 = 0; i2 < size - 2; i2 = i2 + 1) {
System.out.print(" ");
}
System.out.println("*");
y = y + 1;
}
for (int i4 = 0; i4 < size; i4 = i4 + 1) {
System.out.print("*");
}
}
There are many different approaches to this problem. This may not be the best, but it's quite simple and educational IMO.
The main idea is: you don't need to know how to print the entire frame. You only need to know how to print 1/4 of it - then repeat it in reverse X order, then repeat it in reverse Y order. Let's start with drawing X, specifically - one diagonal of it. If the "X" has to have 4n+1 *, it has 4 arms with a stars each and one * in the middle - totaling to 4 * a + 1 stars - so, obviously, 4n+1 == 4a+1, and each arm has to have exactly n *'s. Let's use XY Cartesian coordinate system. Thus, we only have an asterisk if x == y - otherwise we have s space there.
for ( int y = 0; y < n; y++ ) {
for ( int x = 0; x < n; x++ ) {
System.out.print( ( x == y ) ? '*' : ' ' );
}
System.out.println();
}
Now, let's add a mirror copy to it by iterating in reverse too:
for ( int y = 0; y < n; y++ ) {
for ( int x = 0; x < n; x++ ) {
System.out.print( ( x == y ) ? '*' : ' ' );
}
for ( int x = n; x >= 0; x-- ) {
System.out.print( ( x == y ) ? '*' : ' ' );
}
System.out.println();
}
Now, let's try to get into valid Cartesian:
int x, y;
for ( y = -n; y <= n; y++ ) {
for ( x = -n; x < 0; x++ ) {
System.out.print( ( x == y || x == -y ) ? '*' : ' ' );
}
for ( ; x <= n; x++ ) {
System.out.print( ( x == y || x == -y ) ? '*' : ' ' );
}
System.out.println();
}
and, finally, we can figure that it's just
for ( int y = -n; y <= n; y++ ) {
for ( int x = -n; x <= n; x++ ) {
System.out.print( hasAsterisk( Math.abs(x), Math.abs(y) ) ? '*' : ' ' );
}
System.out.println();
}
with, for example
static boolean hasAsterisk( int x, int y ) {
return x == y;
}
Extend this code to handle the frames, and you're set. Each "quart part" of the frame is only * for each n, 2n chars total - the cross itself is n in length (see above) plus 1 central asterisk; to sum up, X and Y will range over int [-3n,3n] - call that 3n some m and use it as the range for iteration.
As an additional hint, the formula is different for the inner cross (i.e. abs(x)<n,abs(y)<n), and different for the frames themselves. The formula for the frames can be easily figured out if you notice that it's every second row, in the shape of two asterisk triangles in axis X added to two triangles in axis Y.
return ( x <= n && y <= n ) ? x == y : ( ( x < y ) ? y % 2 == nMod2 : x % 2 == nMod2 );

Categories