How to print the result in descending order in java? - java

I managed to get the result if I enter the base and exponent, but the output should be
For example: the output should look like this
>>base:5 exponent: 2
5^2 = 25
5^1 = 5
I need help to put something somewhere to make this happen...
import java.util.Scanner;
public class recursion {
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
int base = 0;
int expo = 0;
System.out.print("Enter number for base ");
for (int i = 0; i < 1; i++)
base = scanner.nextInt();
System.out.print("Enter number for exponent ");
for (int j = 0; j < 1; j++)
expo = scanner.nextInt();
System.out.println(base + "^" +expo +" = " + pow(base,expo));
}
public static int pow(int x, int p) {
System.out.println(x + "^" +p +" = " );
if (p == 0)
return 1;
if (p % 2 == 0) {
int a = pow(x, (p / 2));
return a * a; // This line
} else {
int a = pow(x, ((p - 1) / 2));
return x * a * a; // This line
}
}
}

Firstly, the following code snippets demands a review:
{
for (int i = 0; i < 1; i++)
/*
* This for loop is unnecessary.
* It asserts that the following clause is run only once,
* which is true for any statements anyway.
*/
// ...
}
return a * a;
} /* if (p % 2 == 0) */ else {
/*
* Statements are unnecessarily nested within else clause.
* The corresponding then clause does not complete normally.
* Moving the following code snippet out of an else block
* would have the same effect, but simplifies the control
* statements.
*/
int a = pow(x, ((p - 1) / 2));
return x * a * a;
}
Within your pow() method, you have a System.out.println() method. You're calling it for debugging, but it's unnecessary as the process returns normally. As you're looking for printing the operations for exponent as "from user-specified exponent -> 1" ("in descending order"), use a loop to print your System.out.println(base + "^" + expo + " = " + TestClass.pow(base, expo));:
do // New!
System.out.println(base + "^" + expo + " = " + TestClass.pow(base, expo));
while (expo-- > 1); // New!
} /* main( args ) */
and you can remove the debugging line in pow().
Example: (>> denotes STDIN)
Enter number for base >> 5
Enter number for exponent >> 2
5^2 = 25
5^1 = 5
Enter number for base >> 4
Enter number for exponent >> 5
4^5 = 1024
4^4 = 256
4^3 = 64
4^2 = 16
4^1 = 4
View a live code demo.

void power(int base, int exp){
//Use for loop to iterate through each exp down to 0
for(int i=exp; i>=0; i--){
int result= exponent(base,i);
System.out.println(base + "^" + i + "=" + result)//Will display result as 5^2=25
}
//Recursively computes the result of b^e.
int exponent(int b, int e){
if(e==0){//Base case occurs when e=0.
return (1);
}
return (b * exponent(b,e-1));
}

Related

how to print " * " n number of times using while loop?

public class Hello {
public static void pattern() {
int s1 = 3;
while(s1 >= 1) {
System.out.println("*");
s1--;
}
}
public static void main(String [] args){
pattern();
}
}
Actual output:
*
*
*
Expected output:
* * *
* *
*
I would like to print " * " (like the above-expected output) using while loop. I made a while loop controlling the number of columns. I'm not able to make a while loop to control the rows to output "*" in the same line 3 times (next line 2 times and so on).
With just you one loop and some String.repeat() you can draw your pattern
Repeat the leading space, starting and 0, and one more each round
Repeat the pattern depending ong s1, 3 times, then 2 then 1
public static void pattern() {
int s1 = 3;
int s2 = 0; // space counter
while(s1 >= 1) {
System.out.print(" ".repeat(s2));
System.out.println("* ".repeat(s1).trim()); // trim to remove last space
s1--;
s2++;
}
}
int lines = 0, asterisks = 3;
String whiteSpace = "";
while (lines++ < 3) {
System.out.print(whiteSpace);
for (int i = 0; i < 3; i++) {
if (i <= (asterisks - lines)) {
System.out.print("* ");
}
}
whiteSpace += " ";
System.out.println();
}

Making sure the logic of my code is sound. This code will eventually lead into a java representation of yahtzee

I'm making a class for the Straight category of Yahtzee. Yahtzee has 2 options for a straight, small or larger. A small straight would be a sequence of 4 consecutive die faces such as 1, 2, 3, 4. A larger straight would be a sequence of 5 consecutive die faces. If a player get a small straight they receive 30 points and if they get a larger that is 40 points.
My Straight class inherits from a class called Scores and only uses one method called getDiceScore. The getDiceScore will accept an argument of type DieInterface. I will attach the DieInterface interface code below.
I just want to make sure the logic of my code is sound for this project I am working on.
public interface DieInterface
{
public static String[] dieFaces =
{"+---+\n| |\n| o |\n| |\n+---+",
"+---+\n|o |\n| |\n| o|\n+---+",
"+---+\n|o |\n| o |\n| o|\n+---+",
"+---+\n|o o|\n| |\n|o o|\n+---+",
"+---+\n|o o|\n| o |\n|o o|\n+---+",
"+---+\n|o o|\n|o o|\n|o o|\n+---+"};
public static String toDieString(DieInterface aDie)
{
return dieFaces[aDie.getFaceValue()-1];
}
// Do not modify above this line
public static String toDiceString(DieInterface[] dice)
{
StringBuilder result = new StringBuilder();
String sideBySide = "";
String die1 = dieFaces[dice[0].getFaceValue()-1];
String die2 = dieFaces[dice[1].getFaceValue()-1];
String die3 = dieFaces[dice[2].getFaceValue()-1];
String die4 = dieFaces[dice[3].getFaceValue()-1];
String die5 = dieFaces[dice[4].getFaceValue()-1];
//String die6 = dieFaces[dice[5].getFaceValue()-1];
String splitter = die1 + "\n" + die2 + "\n" + die3 + "\n"+ die4 + "\n"+ die4+ "\n"+ die5;
String [] temp = splitter.split("\n");
for(int i = 0; i < (temp.length/6); i++)
{
result.append(temp[0*(5)+i] + " " + temp[1*(5)+i] + " " + temp[2*(5)+i] +" " + temp[3*(5)+i] +" "+ temp[4*(5)+i] +"\n");
}
return result.toString();
}
// Do not modify below this line
public int roll();
public int getFaceValue();
}
public class Straight extends Scores
{
protected String name;
protected int numConsecutiveFaces; // indicates how many consecutive faces that a player should have to satisfy this scoring category
public Straight(String aName, int numConsecutiveFaces)
{
super(aName);
this.numConsecutiveFaces = numConsecutiveFaces;
}
public int getDiceScore(DieInterface[] dice)
{
boolean ones = false;//determines that only one side of a die appeared once
int[] straight = new int[numConsecutiveFaces]; // array used to store numbers in the correct straight format
int [] counter = {0, 0, 0, 0, 0 ,0}; //using to track how many times a die appeared
//looping through dice array to determine how many times a die appeared
for(int i = 0; i < dice.length; i++)
{
counter[dice[i].getFaceValue()-1]++;
}
//sorting the die in sequential order
sort(counter);
//determining that a die only appeared once and they are no larger than by one value. ex 1, 2, 3, 4, 5 not 2, 3, 5, 6
for(int i = 0; i < counter.length; i++)
{
if(counter[i] == 1 && byAFactorOfOne(counter, counter) == true)
{
ones = true;
byAFactorOfOne(counter, counter);
counter[i] = straight[i];
}
}
//if 4 die in a row are in correct sequential order return 30 points back
if(straight[numConsecutiveFaces] == 4)
return 30;
//if 5 die in a row are in correct sequential order return 40 points back
else if(straight[numConsecutiveFaces] == 5)
return 40;
else
return 0;
}
private void sort(int[] counter)
{
for (int i = 0; i <counter.length; i++)
{
for (int j = 0; j < counter.length - i - 1; j++)
{
if (counter[j] > counter[j + 1])
{
int temp = counter[j];
counter[j] = counter[j + 1];
counter[j + 1] = temp;
}
}
}
}
private boolean byAFactorOfOne(int[] counter, int[] counter2)
{
int value;
int counting = 0;
boolean repeat = true;
int i = 0;
while(repeat && counting < counter.length)
{
value = counter[i] - counter[i + 1];
i++;
if(value != 1)
{
repeat = false;
return false;
}
counting ++;
}
return true;
}
}
First of all, the following code won't work:
if(straight[numConsecutiveFaces] == 4)
... because you aren't setting any values into the straight array.
You are counting the number of times each die value is displayed:
//looping through dice array to determine how many times a die appeared
for(int i = 0; i < dice.length; i++)
{
counter[dice[i].getFaceValue()-1]++;
}
... and the index of the array is the value on the die. This makes sense.
But as soon as you sort these values, you lose which die value each count represents. Don't do this:
//sorting the die in sequential order
sort(counter);
If you did that, you no longer know which die value was displayed n times.
Instead of sorting counter, what you need to do is look for 4 or 5 consecutive entries that are not 0. In other words, 4 or 5 consecutive entries that had at least one die showing that value.
You can take some shortcuts:
If counter[3] or counter[4] is zero, it's not possible for either a 4-length or 5-length straight
If counter[2] and counter[5] are both 0, it's not possible for a 5-length straight
If there are any counter values > 1, then it's not possible for a 5-length straight to have occurred
And if there are more than 1 counter values > 1, then it's not possible for a 4-length straight to have occurred.
A simpler way to solve this problem that doesn't involve counting values or sorting (uses binary values to represent the presence of a die value):
public class Straight extends Scores
{
static final int valueForOneToFour = Math.pow(2, 0) + Math.pow(2, 1) + Math.pow(2, 2) + Math.pow(2, 3);
static final int valueForTwoToFive = Math.pow(2, 1) + Math.pow(2, 2) + Math.pow(2, 3) + Math.pow(2, 4);
static final int valueForThreeToSix = Math.pow(2, 2) + Math.pow(2, 3) + Math.pow(2, 4) + Math.pow(2, 5);
static final int valueForOneToFive = Math.pow(2, 0) + Math.pow(2, 1) + Math.pow(2, 2) + Math.pow(2, 3) + Math.pow(2, 4);
static final int valueForTwoToSix = Math.pow(2, 1) + Math.pow(2, 2) + Math.pow(2, 3) + Math.pow(2, 4) + Math.pow(2, 5);
...
public int getDiceScore(DieInterface[] dice)
{
// calculate a binary representation of the values available
int occurrenceValue = 0;
for (int i = 0; i < 6; i++) {
occurrenceValue |= Math.pow(2, dice[i] - 1));
}
if (occurrenceValue & valueForOneToFive == valueForOneToFive
|| occurrenceValue & valueForTwoToSix == valueForTwoToSix) {
return 40;
}
if (occurrenceValue & valueForOneToFour == valueForOneToFour
|| occurrenceValue & valueForTwoToFive == valueForTwoToFive
|| occurrenceValue & valueForThreeToSix == valueForThreeToSix) {
return 30;
}
return 0;
}
}

What's wrong with my for-loop?

I am trying to print each digit of an integer and then sum of each digit like this. There is something wrong with the loops but I cant seem to figure it out. I want it to be like this:
Please enter a number: 194
1 * 100 = 100
9 * 10 = 90
4 * 1 = 4
import java.util.Scanner;
public class PrintEachDigits {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Enter the number: ");
int num = scan.nextInt();
String s = ""+num;
double d = 0;
for(int i = 0; i < s.length(); i++) {
for(int j = s.length()-1; j >= 0; j--) {
d = Math.pow(10,j);
System.out.println(s.charAt(i) + " * " + d
+ " = " + (s.charAt(i)*d));
}
}
}
}
This is the output of my code:
Enter the number: 194
1 * 100.0 = 4900.0
1 * 10.0 = 490.0
1 * 1.0 = 49.0
9 * 100.0 = 5700.0
9 * 10.0 = 570.0
9 * 1.0 = 57.0
4 * 100.0 = 5200.0
4 * 10.0 = 520.0
4 * 1.0 = 52.0
There's a couple problems with your code.
The first problem is that you don't need two loops, you just need one.
The second problem is confusing chars and ints. '0' is not the same as 0; instead, '0' is a numeric value representing the encoding of that character (which turns out to be 48). So to get the correct value that you want, you should subtract '0' from the char before doing your math.
for(int i = 0; i < s.length(); i++) {
d = Math.pow(10, s.length() - i - 1);
int value = s.charAt(i) - '0';
System.out.println(value + " * " + d
+ " = " + (value*d));
}
This will get it close to the output you wanted. It's still showing the .0 at the end though, because d is a double. Make it an int to fix that.
//This can be scoped to inside the loop, so you don't need to declare it beforehand
int d = (int)Math.pow(10,j);
import java.util.Scanner;
public class PrintEachDigits {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Enter the number: ");
int num = scan.nextInt();
String s = "" + num;
int len = s.length() - 1;
long d = 0;
if (len < 2) {
d = 1;//For single digit
} else {
d = (long)Math.pow(10, len);
}
for (int i = 0; i < s.length(); i++) {
System.out.println(s.charAt(i) + " * " + d + " = "
+ ((s.charAt(i) - '0') * d));
d = d / 10;
}
}
}

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

Why do I get a "Selection does not contain a main type" message in Eclipse?

import java.util.Scanner;
public class data {
public static int setoriginal() { //prompt user to input 4 digit number
int n = 0;
int l = 0;
do {
Scanner input = new Scanner(System.in);
System.out.println("Please enter a 4 digit number: ");
n = input.nextInt();
if (n >= 1000 && n <= 9999) {
break;
} else {
System.err.
printf("You did not enter 4 digits\n");
}
l = l + 1;
}
while (l < 3);
return n;
} //end method
public static int encrypt(int n) { //encrypt number inputted by user
int e1 = (((n / 1000) + 7) / 10);
int e2 = ((((n % 1000) / 100) + 7) / 10);
int e3 = ((((n % 100) / 10) + 7) / 10);
int e4 = ((((n % 10) / 1) + 7) / 10);
int e = e1 * 1000 + e2 * 100 + e3 * 10 + e4;
int firstPart = e % 100;
int lastPart = e / 100;
int result = firstPart * 100 + lastPart;
return result;
} //end method
public static int decrypt(int result) { //decrypt encrypted number
int d1 = (((result / 1000) - 7) * 10);
int d2 = ((((result % 1000) / 100) - 7) * 10);
int d3 = ((((result % 100) / 10) - 7) * 10);
int d4 = ((((result % 10) / 1) - 7) * 10);
int d = d1 * 1000 + d2 * 100 + d3 * 10 + d4;
int firstPart1 = d % 100;
int lastPart1 = d / 100;
int result1 = firstPart1 * 100 + lastPart1;
return result1;
} //end method
public static int decrypt1(int n) { //decrypted number inputted by user
int dd1 = (((n / 1000) - 7) * 10);
int dd2 = ((((n % 1000) / 100) - 7) * 10);
int dd3 = ((((n % 100) / 10) - 7) * 10);
int dd4 = ((((n % 10) / 1) - 7) * 10);
int dd = dd1 * 1000 + dd2 * 100 + dd3 * 10 + dd4;
int firstPart1 = dd % 100;
int lastPart1 = dd / 100;
int result1 = firstPart1 * 100 + lastPart1;
return result1;
} //end method
public static void display(int n, int result, int result1) { //output results
System.out.println("Originl number is: " + n);
System.out.println("\nEcrypted numebr is: " + result);
} //end method
public static void display1(int n, int result, int result1) { //output results
System.out.println("Originl number is: " + n);
System.out.println("\nDecrypted numebr is: " + result1);
} //end method
public static void getOriginal(int n) { //return original number
System.out.println("The original number is: \n" + n);
} //end method
public static void getEncrypt(int n, int result) { //return encrypted number
System.out.println("The encrypted number is: \n" + result);
} //end method
public static void main(String[]args, int result, int n, int result1) {
int m = 0;
Scanner input1 = new Scanner(System.in);
System.out.print("\nPlease choose from the following menu ");
System.out.print("\n1. Enter an original number");
System.out.print("\n2. Encrypt the number and print it");
System.out.print("\n3. Decrypt a number and print it");
System.out.print("\n4. Quit\n");
m = input1.nextInt();
while (m < 1 || m > 4) {
System.out.print("Error choose a number from 1-4");
m = input1.nextInt();
}
if (m == 1) {
setoriginal();
main(args, m, m, m);
}
else if (m == 2) {
if (setoriginal() == 0) {
System.out.
print
("Please enter an original number first");
main(args, m, m, m);
} else {
encrypt(n);
display(n, result, result1);
main(args, n, result, result1);
}
} else if (m == 3) {
if (encrypt(n) < 0) {
System.out.
print("Please encrypt your number first");
main(args, n, result, result1);
} else {
decrypt(n);
display1(n, result, result1);
main(args, n, result, result1);
}
} else if (m == 4) {
System.exit(0);
}
}
}
I get no compile errors in eclipse but I get an error stating "Selection does not contain a main type". Any ideas what could be wrong? Also if you see any other errors please could you let me know.
You should use:
public static void main(String[] args)
instead of:
public static void main(String[] args, int result, int n, int result1)
In order to run your program, java needs to be able to find a method with the following signature:
public static void main(String[])
Since it can't find one in your program, it has nowhere to begin execution and hence can't compile it.
To get the affect you want, change the signature of the main method to that above, and access the arguments in terms of their indices of the String[], like so:
result = Integer.parseInt( args[0] );
n = Integer.parseInt( args[1] );
result1 = Integer.parseInt( args[2] );
If you add that to the start of your main method you should be fine. :D
public static void main(String[]args, int result, int n, int result1) {
One thing you're going to have to learn doing Java programming is the incantation:
public static void main(String args[]) {
It is this exact (well, String[] args also works -- and the name doesn't matter) incantation that the JVM searches for when it looks for an entry point to run your program.
Update
If you want to get any parameters from your main() function they will be encoded as String objects in the args[] array. Simply index into them:
$ cat Echo.java ; javac Echo.java ; java Echo Hello Cruel World
import java.lang.System;
class Echo {
public static void main(String args[]) {
for(int i=0; i<args.length; i++) {
System.out.println(args[i]);
}
}
}
Hello
Cruel
World
$
Of course, they are String objects. If you need to convert them into other object classes, you'll have to parse the strings correctly. (Integer() and similar things can come in handy for simple cases.)

Categories