Add numbers of array until certain value - java

For an exercise, I have to add values of an array until a certain value is reached, showing all possible combinations.
Example: value = 4, array = {1, 2, 3}
Possible combinations are: 1+1+1+1, 1+1+2, 1+2+1, 1+3, 2+1+1, 2+2, 3+1
However, my code doesn't seem to work:
public static void main(String[] args) {
double[] array = { 1., 2., 3. };
double value = 4.;
for (int i = 0; i < array.length; i++) {
addNumber(array, value, i);
}
}
public static void addNumber(double[] array, double value, int index) {
double startNumber = array[index];
double checkSum = 0;
for (int i = 0; i < array.length; i++) {
checkSum += array[i] + startNumber;
if (checkSum == value){
System.out.println(startNumber + " + " + array[i] + " = " + checkSum);
} else if (checkSum < value){
moreNumbers(array, value, checkSum);
}
checkSum = 0;
}
}
public static void moreNumbers (double[] array, double value, double current){
if (current == value){
System.out.println(current);
} else if (current < value) {
for (int i = 0; i < array.length; i++){
current += array[i];
System.out.println("+ " + array[i] + " = " + current);
}
moreNumbers(array, value, current);
}
}
Output:
+ 1.0 = 3.0
+ 2.0 = 5.0
+ 3.0 = 8.0
+ 1.0 = 4.0
+ 2.0 = 6.0
+ 3.0 = 9.0
1.0 + 3.0 = 4.0
+ 1.0 = 4.0
+ 2.0 = 6.0
+ 3.0 = 9.0
2.0 + 2.0 = 4.0
3.0 + 1.0 = 4.0
I believe I'm having trouble finding the right algorithm, since I'm only getting some of the combinations, but not all.
And there is my question: I'm looking for an algorithm that helps me understand this exercise and it's logic, not the final code.
EDIT: In further development of this exercise, I have to use numbers like 0.5 or 0.2 too, but the numbers are always positive, so this is another problem I'm hoping to find answers for.

This seems to be solvable easily with recursion, like this :
Getting the solution for 4 and {1,2,3} (written below as solution(4, {1,2,3}) is like getting the solution for
"1 + " + solution(3, {1, 2, 3})
"2 + " + solution(2, {1, 2, 3})
"3 + " + solution(1, {1, 2, 3})
At each step, you decrease the number (if there is not 0 in the list of available numbers, of course), so you are sure that the recursion will finish.
You can have two outcome :
no possibility (like you need to produce 1, but there is not 1 in the list of available numbers)
1 or more potential solutions
There is another thing to pay attention to : floating point equality. == will not work everytime.
the code would like like :
public static void main(String[] args) {
ArrayList<String> solutions = new ArrayList<String>();
solve("", 1.0d, new Double[] {0.2d, 0.50d}, solutions);
System.out.println(solutions);
// [0.2 + 0.2 + 0.2 + 0.2 + 0.2, 0.5 + 0.5]
solutions.clear();
solve("", 4d, new Double[] {1d, 2d, 3d}, solutions);
System.out.println(solutions);
// [1.0 + 1.0 + 1.0 + 1.0, 1.0 + 1.0 + 2.0, 1.0 + 2.0 + 1.0, 1.0 + 3.0, 2.0 + 1.0 + 1.0, 2.0 + 2.0, 3.0 + 1.0]
}
public static void solve(String subSolution, Double remaining, Double[] authorizedNumbers, List<String> solutions) {
if (doubleEquals(remaining, 0d)) {
solutions.add(subSolution);
} else {
for(Double authorizedNumber : authorizedNumbers) {
if (doubleEquals(authorizedNumber, remaining)) {
solutions.add(subSolution + authorizedNumber);
} else if (authorizedNumber < remaining) {
solve(subSolution + authorizedNumber + " + ", remaining - authorizedNumber, authorizedNumbers, solutions);
}
}
}
}
public static boolean doubleEquals(double d1, double d2) {
return Math.abs(d1 - d2) < 0.000000001d;
}

Here is one of the solutions based on Combination Technique.
Algorithm:
Compute all the combination (with repetition) from length {input} to 1.
Print only those combinations which satisfy the sum condition.
For Example, if input is 4 then some of the different combinations of length = 4 will be as follows:
1 1 1 1
1 1 1 2
.
.
2 1 2 3
.
.
3 3 3 3
Now, we'll only print 1 1 1 1 since it sums up to input i.e. 4 and satisfies the condition.
Similarly, for length = 3 some of the different combinations will be as follows:
1 1 1
1 1 2
.
.
1 2 1
.
.
3 3 3
Now, we'll only print 1 1 2, 1 2 1 and 2 1 1 since they all satisfy the sum condition.
Here is a brief description of how different combinations are computed:
Combination function checks for the last element of the array and increments it if it is not MAX and branches the function.
If the last element is max then we scan through the array for next number that is not MAX.
If the above scan fails as the array is exhausted then we return the flow to our main function but, if the scan return a position which is not max then we increment the value at that position by 1 and reset all the values after that position to MIN. We again branches the function.
(It computes all the combinations for a given length using recursion)
Code Snippet:
class Combinations
{
/* Constants Array (Sorted) */
private static final double[] ARR_CNST = {0.1,0.2,0.3};
/* Size of Constant Array */
private static final int SIZE = 3;
public static void main (String[] args)
{
/* Input Number */
double input = 0.4;
/* Start Permutations {Length --> 1} */
for(int i = (int) (input/ARR_CNST[0]); i > 0; i--) {
double[] storage = new double[i];
/* Fill Array With Least Element */
Arrays.fill(storage,ARR_CNST[0]);
/* Check Sum Condition */
if(check(storage,input)) {
/* Print */
print(storage);
}
/* Calculate Rest of the Combinations */
calc(storage, input);
}
}
private static void calc(double[] arr, double input) {
/* Increment Last Element if not MAX */
if(arr[arr.length - 1] < ARR_CNST[SIZE - 1]) {
int k = 0;
while(k < SIZE && arr[arr.length - 1] != ARR_CNST[k++]);
arr[arr.length - 1] = ARR_CNST[k];
if(check(arr,input)) {
print(arr);
}
calc(arr, input);
}
/* Increment & Reset */
int i = arr.length - 1;
while(i >= 0 && arr[i] >= ARR_CNST[SIZE - 1])
i--;
if(i >= 0) {
int k = 0;
while(k < SIZE && arr[i] != ARR_CNST[k++]);
arr[i] = ARR_CNST[k];
for(int x = i + 1; x < arr.length; x++) {
arr[x] = ARR_CNST[0];
}
if(check(arr,input)) {
print(arr);
}
calc(arr, input);
}
/* Return */
return;
}
/* Check Sum Condition */
private static boolean check(double[] arr, double input) {
double sum = 0;
for(int i = 0; i < arr.length; i++) {
sum += arr[i];
}
if(sum == input) {
return true;
}
return false;
}
/* Print Array Values */
private static void print(double[] arr) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < arr.length; i++) {
sb.append(arr[i] + " + ");
}
System.out.println(sb.substring(0,sb.length() - 3));
}
}
Output:
0.1 + 0.1 + 0.1 + 0.1
0.1 + 0.1 + 0.2
0.1 + 0.2 + 0.1
0.2 + 0.1 + 0.1
0.1 + 0.3
0.2 + 0.2
0.3 + 0.1

The general approach is:
Pick one of the available numbers, and see if that equals the target.
If not, you can pick any other number from the available numbers and add it to the previously picked number; again, check if you have reached the target.
Keep going until you have reached (or gone past) the target sum.
This can be implemented like this:
public static void startRecursion(int target, int[] numbers) {
int min = numbers[0];
for (int i = 1; i < numbers.length; ++i) {
min = Math.min(min, numbers[i]);
}
// We need to choose at most ceil(target / min) numbers.
int maxPicks = (target + min - 1) / min;
recurse(new int[maxPicks], 0, 0, target, numbers);
}
private static void recurse(
int[] picked, int numPicked, int sumOfPicked,
int target, int[] numbers) {
if (sumOfPicked == target) {
// We reached the target! Print out the numbers we chose to get here.
for (int i = 0; i < numPicked; ++i) {
if (i != 0) System.out.print(" + ");
System.out.print(picked[i]);
}
System.out.println(" = " + target);
} else if (sumOfPicked < target) {
// We haven't reached the target yet.
// Go through each of the numbers that you can choose from numbers
// in turn, increasing the sum by this amount.
for (int i = 0; i < numbers.length; ++i) {
picked[numPicked] = numbers[i];
recurse(
picked, numPicked + 1, sumOfPicked + numbers[i],
target, numbers);
}
} else {
// We have overshot the target. Since no numbers are negative,
// we can't get back to the target again.
}
}

Related

Print optimal solution for coin change algorithm

Given a value N, if we want to make change for N cents, and we have infinite supply of each of S = { S1, S2, .. , Sm} valued coins, what is the optimal way to make change for N cents.
Example:
S = {2, 5, 10}
N = 6, then optimal solution is : 2, 2, 2
I have below working code:
public static void main(String argv[]) {
long n = 10L;
int[] combo = new int[100];
int[] amounts = { 2, 5, 10 };
ways(n, amounts, combo, 0, 0, 0);
}
public static void ways(long n, int[] amounts, int[] combo, int startIndex, int sum, int index) {
if (sum == n) {
printArray(combo, index);
}
if (sum > n) {
return;
}
for (int i = 0; i < amounts.length; i++) {
sum = sum + amounts[i];
combo[index] = amounts[i];
ways(n, amounts, combo, startIndex, sum, index + 1);
sum = sum - amounts[i];
}
}
public static void printArray(int[] combo, int index) {
for (int i = 0; i < index; i++) {
System.out.print(combo[i] + " ");
}
System.out.println();
}
Output:
2 2 2 2 2
5 5
10
Here I just need to optimal combination with less number of coins so only 10 in this example code.
But this code uses recursive approach, my value for N is Long type so as the value of N increases I am getting stackoverflow error.
The recursive approach I am following here is not correct, What is the correct way to solve this problem?
Update:
Based on MBo answer I tried below program, but I am not able to get the correct results:
static void testcase() {
// make int array A of size N+1
int N = 6;
int[] A = new int[N + 1];
// make int array P of size N+1
int[] P = new int[N + 1];
// fill A[] with large value (len(S) + 1)
int[] S = { 2, 5, 10 };
int lengthOfS = S.length;
for (int i = 0; i < A.length; i++) {
A[i] = lengthOfS + 1;
}
A[0] = 0;
for (int s : S) {// coin value
for (int i = s; i <= N; i++) {
if (A[i - s] < A[i] + 1) { // using this coin we can get better
// result for sum i
A[i] = A[i - s] + 1;
P[i] = s; // write down coin for this sum
}
}
}
System.out.println(Arrays.toString(P)); // [0, 0, 2, 2, 2, 5, 2]
System.out.println(A[N]);// 3
int idx = N;
for (int i = 0; i < A[N]; i++) {
int result = idx - P[idx];
System.out.println(result); // 4 2 0
idx = result;
}
}
This code prints:
[0, 0, 2, 2, 2, 5, 2]
3
4
2
0
How to fix this code?
For fixed set S = {2, 5, 10} solution is rather simple:
No solutions for N=1,3
if N is odd, you must use 5 - so N=N-5
Now use greedy approach: get as much 10-s as possible, then as much 2-s as possible
def best(N):
print(N, end = ": ")
if (N % 2):
print("5", end = " ")
N = N - 5
if N >= 10:
print("10*", N//10, end = " ")
N = N % 10
if N > 1:
print("2*", N//2, end = " ")
21: 5 10* 1 2* 3
22: 10* 2 2* 1
23: 5 10* 1 2* 4
24: 10* 2 2* 2
In general you can find optimal solution using dynamic programming.
The first way is "memoization" - you have to implement recursive approach with the choice of the best solution, then add storing intermediate results in hashmap or another structure. Simple implementation:
S = [2, 3, 5, 7, 11]
dic = {}
def rec(summ):
if summ == 0:
return 0
rd = dic.get(summ)
if rd != None:
return rd
minn = 9999999999999
for s in S:
if s <= summ:
minn = min(minn, 1 + rec(summ - s))
dic[summ] = minn
return minn
N = 1000
print(rec(N))
>>92
Another way is using table - you fill it with the best possible results using the first item, then update solution using the second item and so on.
Pseudocode
make int array A of size N+1
make int array P of size N+1
fill A[] with large value (MaxInt` or at least `N/min(S))
A[0] = 0
for s in S: //coin value
for (i = s; i <= N; i++)
if A[i - s] < A[i] + 1 //using this coin we can get better result for sum i
A[i] = A[i - s] + 1
P[i] = s //write down coin for this sum
Now we have A[N] with the best count, and can retrieve needed coins using P[N], P[N - P[N]]... sequence.
Working Python code
S = [2, 3, 5, 7, 11]
N = 17
A = [0] + [10000] * N
P = [0] * (N + 1)
for s in S: #coin value
for i in range(s, N + 1):
if A[i - s] < A[i] + 1: #using this coin we can get better result for sum i
A[i] = A[i - s] + 1
P[i] = s #write down coin for this sum
print(A) #for reference
i = N
while i > 0:
print(P[i], end = " ")
i = i - P[i]
>> [0, 10000, 1, 1, 2, 1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 3, 2, 3]
>> 11 3 3
Note - if we can use every coin only once, we have to make inner loop in backward direction to avoid multiple adding the same coin
As the number of coins is small, and since the amount can be large, it is likely that backtracking can provide a good solution
Here is an implementation in C++
(Note: this code was already posted, but I can't find the post. Question deleted ?)
The coins are first sorted if descending order, to fasten the search.
In order to minimize the number of coins, we first try solutions with maximum possible number of coins of largest value.
In a given search, if the current number of coins is larger than the current minimum number of coins, we stopped the search ("premature abandon").
In the code, "UP" means that we will consider adding coins with a lower value
"DOWN" means that we will try to decrease the number of coins of higher value.
At a given step, we maintain an array corresponding to the number of coins for each coin value
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
// The order of array coins is modified
std::vector<int> get_change(std::vector<int>& coins, int amount) {
std::vector<int> n_coins(coins.size(), 0);
std::vector<int> n_coins_opt(coins.size(), 0);
int n = coins.size();
std::sort(coins.begin(), coins.end(), std::greater<int>());
int sum = 0; // current sum
int i = 0; // index of the coin being examined
int n_min_coins = amount / coins[n - 1] + 1;
int n_total_coins = 0;
bool up_down = true;
while (true) { // UP
if (up_down) {
n_coins[i] = (amount - sum) / coins[i]; // max possible number of coins[i]
sum += n_coins[i] * coins[i];
n_total_coins += n_coins[i];
if (sum == amount) {
if (n_total_coins < n_min_coins) {
n_min_coins = n_total_coins;
n_coins_opt = n_coins;
}
up_down = false;
sum -= n_coins[i] * coins[i];
n_total_coins -= n_coins[i];
n_coins[i] = 0;
i--;
}
else {
if (i == (n - 1) || (n_total_coins >= n_min_coins)) { // premature abandon
sum -= n_coins[i] * coins[i];
n_total_coins -= n_coins[i];
n_coins[i] = 0;
up_down = false;
i--;
}
else {
i++;
}
}
}
else { // DOWN
if (i < 0) break;
if (n_coins[i] == 0) {
if (i == 0) break;
i--;
}
else {
sum -= coins[i];
n_coins[i] --;
n_total_coins--;
i++;
up_down = true;
}
}
}
return n_coins_opt;
}
int main() {
std::vector<int> coins = {2, 5, 10};
int amount = 1731;
auto n_coins = get_change(coins, amount);
int sum = std::accumulate (n_coins.begin(), n_coins.end(), 0);
if (sum == 0) {
std::cout << "no solution\n";
} else {
std::cout << amount << " = ";
for (int i = 0; i < n_coins.size(); i++) {
std::cout << n_coins[i] << "*" << coins[i] << " ";
}
std::cout << "\n";
}
return 1;
}

Java : How to print heap stored as array, level by level

I have an array that represents a Max Heap. For example
84 81 41 79 17 38 33 15 61 6
so the root is max. Each mid tier node at index i can have at most two children. They would be at 2*i+1 and 2*i+2.
How can i print this heap out in a level by level fashion? like
84(0)
81(1) 41(2)
79(3) 17(4) 38(5) 33(6)
15(7) 61(8) 6(9)
the index of each element in the array is shown in paranthesis for clarification. i dont have to print the index. I was thinking it would be similar to printing a BST in level order but here, the heap is stored in an array not a list which makes it a bit tricky!
Try this code:
public class NewClass56 {
public static void main(String args[]){
int a[] = new int[] {84 ,81 ,41 ,79 ,17 ,38 ,33 ,15 ,61 ,6};
for(int i=0;i<10;i++){
for(int j=0;j<Math.pow(2,i)&&j+Math.pow(2,i)<10;j++){
System.out.print(a[j+(int)Math.pow(2,i)-1]+" ");
}
System.out.println();
}
}
}
If you have n number of numbers then replace 10 by n.
and you want the spaces then try this code:
public class NewClass56 {
public static void main(String args[]){
int a[] = new int[] {84 ,81 ,41 ,79 ,17 ,38 ,33 ,15 ,61 ,6};
StringBuilder sb = new StringBuilder();
int max=0;
for(int i=0;i<10;i++){
for(int j=0;j<Math.pow(2,i)&&j+Math.pow(2,i)<10;j++){
if(j>max){
max=j;
}
}
}
for(int i=0;i<10;i++){
for(int j=0;j<Math.pow(2,i)&&j+Math.pow(2,i)<10;j++){
for(int k=0;(k<max/((int)Math.pow(2, i)));k++){
sb.append(" ");
}
sb.append(a[j+(int)Math.pow(2,i)-1]+" ");
}
sb.append("\n");
}
System.out.println(sb.toString());
}
}
There is another way to print heap. Imagine you have the structure with the following indexes (index 0 is guardian and equals to Integer.MIN_VALUE, not shown here):
1
/ \
2 3
/ \ / \
4 5 6 7
/ \ /\ /\ /\
8 9 10 11 12 13 14 15
and it's represented by array of numbers. What do you see here? Right, 1, 3, 7, 15. If you increase it by 1 it will be 2, 4, 8, 16.
And what are these numbers? It's just 2^level. Where level is level from 1 to 4.
How we can calculate this level? It's logarithm of index with base 2.
Here is the code that implements this approach (see dump function):
package org.solutions;
import java.util.ArrayList;
import java.util.Arrays;
class Heap {
public ArrayList<Integer> arr;
public Heap() {
this.arr = new ArrayList<>();
arr.add(Integer.MIN_VALUE); // add guardian
}
public void add(int x) {
int i = arr.size();
arr.add(x);
while(arr.get(i) < arr.get(i / 2)) {
swap(i, i/2);
i = i / 2;
}
}
private void swap(int i, int j) {
int tmp = arr.get(i);
arr.set(i, arr.get(j));
arr.set(j, tmp);
}
public void dump() {
int height = log2(arr.size()) + 1;
for (int i = 1, len = arr.size(); i < len; i++) {
int x = arr.get(i);
int level = log2(i) + 1;
int spaces = (height - level + 1) * 2;
System.out.print(stringOfSize(spaces, ' '));
System.out.print(x);
if((int)Math.pow(2, level) - 1 == i) System.out.println();
}
}
private String stringOfSize(int size, char ch) {
char[] a = new char[size];
Arrays.fill(a, ch);
return new String(a);
}
// log with base 2
private int log2(int x) {
return (int)(Math.log(x) / Math.log(2)); // = log(x) with base 10 / log(2) with base 10
}
}
public class Main {
public static void main(String[] args) {
Heap heap = new Heap();
heap.add(30);
heap.add(2);
heap.add(15);
heap.add(10);
heap.add(31);
heap.dump();
}
}
The existing solutions didn't work for me so here's slightly different way of doing it that I think is also more human readable. Additionally, this doesn't use any external libraries. Note that this assumes that the first spot of the array is null, because often array-based heaps skip the array[0]. This will automatically determine the number of levels based on the input size which should be the number of nodes in the heap. It will add -- in every spot that is empty (e.g. if you have a 13-node heap the last two nodes will show up as empty).
private void printHeap(int[] heap, size) {
int maxDepth = (int) (Math.log(size) / Math.log(2)); // log base 2 of n
StringBuilder hs = new StringBuilder(); // heap string builder
for(int d = maxDepth; d >= 0; d--) { // number of layers, we build this backwards
int layerLength = (int) Math.pow(2, d); // numbers per layer
StringBuilder line = new StringBuilder(); // line string builder
for(int i = layerLength; i < (int) Math.pow(2, d + 1); i++) {
// before spaces only on not-last layer
if(d != maxDepth) {
line.append(" ".repeat((int) Math.pow(2, maxDepth - d)));
}
// extra spaces for long lines
int loops = maxDepth - d;
if(loops >= 2) {
loops -= 2;
while(loops >= 0) {
line.append(" ".repeat((int) Math.pow(2, loops)));
loops--;
}
}
// add in the number
if(i <= size) {
line.append(String.format("%-2s", heap[i])); // add leading zeros
} else {
line.append("--");
}
line.append(" ".repeat((int) Math.pow(2, maxDepth - d))); // after spaces
// extra spaces for long lines
loops = maxDepth - d;
if(loops >= 2) {
loops -= 2;
while(loops >= 0) {
line.append(" ".repeat((int) Math.pow(2, loops)));
loops--;
}
}
}
hs.insert(0, line.toString() + "\n"); // prepend line
}
System.out.println(hs.toString());
}
Example input:
int[] heap = new int[]{0, 84, 81, 41, 79, 17, 38, 33, 15, 61, 6};
int size = heap.length-1 = 10
Example output:
84
81 41
79 17 38 33
15 61 6 -- -- -- -- --
You should be able to fairly easily change this to work as a toString method instead if necessary. The spacing will have to be modified if you want to use 3-digit numbers, if someone requests it I can edit with modified code for that.
Divide & Conquer. Create the line lists of the subtrees, concatenate the lines and prepend the String for the root node of the subtree. Also make sure the lines have the same length and all are centered:
static String pad(String s, int lengthRigth, int length) {
StringBuilder sb = new StringBuilder();
for (int i = length - lengthRigth - s.length(); i > 0; i--) {
sb.append(' ');
}
sb.append(s);
for (int i = 0; i < lengthRigth; i++) {
sb.append(' ');
}
return sb.toString();
}
static StringBuilder withSpacesAppended(String s, int spaceCount) {
StringBuilder sb = new StringBuilder(s.length()+spaceCount).append(s);
for (int i = 0; i < spaceCount; i++) {
sb.append(' ');
}
return sb;
}
static void joinLists(List<String> list1, List<String> list2) {
int i;
final int size = list2.size();
for (i = 0; i < size; i++) {
list1.set(i, withSpacesAppended(list1.get(i), 2).append(list2.get(i)).toString());
}
}
static List<String> createTreeStrings(int index, int[] array) {
int child1 = 2 * index + 1;
int child2 = 2 * index + 2;
if (child1 >= array.length) {
return new ArrayList<>(Collections.singletonList(toText(index, array)));
} else {
List<String> childList1 = createTreeStrings(child1, array);
if (child2 < array.length) {
joinLists(childList1, createTreeStrings(child2, array));
}
String text = toText(index, array);
int currentLength = childList1.get(0).length();
if (currentLength >= text.length()) {
text = pad(text, (currentLength - text.length()) / 2, currentLength);
} else {
for (int i = 0, size = childList1.size(); i < size; i++) {
childList1.set(i, pad(childList1.get(i), (currentLength - text.length()) / 2, currentLength));
}
}
childList1.add(0, text);
return childList1;
}
}
static String toText(int index, int[] array) {
return Integer.toString(array[index]) + '(' + index + ')';
}
Example use:
createTreeStrings(0, new int[]{84, 81, 41, 79, 17, 38, 33, 15, 61, 6}).forEach(System.out::println);
createTreeStrings(0, new int[]{Integer.MAX_VALUE, 6}).forEach(System.out::println);
The accepted answer created many new lines and ignores last element while displaying. Hence sharing optimised code,
public void display() {
// n is number of elements in the heap
// It can be further optimised by calculating height of the heap
// and looping i only till height of the tree
for (int i = 0; i <= n / 2; i++) {
for (int j = 0; j < Math.pow(2, i) && j + Math.pow(2, i) <= n; j++) { // Each row has 2^n nodes
System.out.print(heap[j + (int) Math.pow(2, i) - 1] + " ");
}
System.out.println();
}
}
If you want to store it in a list of lists (level order) , just split it once for every power of 2, like 1,2,4,8,16 ..
private ArrayList<ArrayList<Integer>> heapParse(int[] arr) {
ArrayList<ArrayList<Integer>> heap = new ArrayList<ArrayList<Integer>>();
int j=-1;
for (int i=0; i< arr.length;i++){
if(isPowerOfTwo(i+1)){
heap.add(new ArrayList<>());
j++;
}
heap.get(j).add(arr[i]);
}
return heap;
}
private boolean isPowerOfTwo(int i){
return (i&(i-1))==0;
}
The following algorithm will print value as defined grid length.
For example, the max element equals 100, mean each digits sit in placeholder that has length == 3. If max length is even, for ex: 4. Then the placeholder value will be 5. Always odds for center alignment.
Result: [placeholder == 3] && [maxWidthLine == 31]
100 // [rear == 14] && [between == 29 -> Not Use]
15- 17- // [rear == 6] && [between == 13]
-9- -6- 13- 10- // [rear == 2] && [between == 5]
-4- -8- -3- -1- -5- --- --- --- // [rear == 0] && [between == 1]
Result: [placeholder == 5] && [maxWidthLine == 5 * 2^3 + 2 ^ 3 - 1 == 47]
1000- // [Level == 0]
-17-- -13-- // [Level == 1]
--9-- -15-- --5-- -10-- // [Level == 2]
--4-- --8-- --3-- --6-- --1-- ----- ----- ----- // [Level == 3]
TypeScript source code:
/** #example
** > format(10, 3) -> "10-"
** > format(10, 4) -> "-10-"
** > format(100, 3) -> "100"
** > format(100, 4) -> "100-"
**/
const format = <T extends string | number>(value: T, placeholder: number): string => {
if (!value && value !== 0) {
return "-".repeat(placeholder);
}
const number = Number.call(null, value).toString();
const size = number.length;
if (size > placeholder) {
throw new EvalError(">>> Place-Holder is smaller than Number Length <<<");
}
const pads = (placeholder - size) >> 1;
return "-".repeat(pads) + number + "-".repeat(placeholder - size - pads);
};
public print(): void {
const size = this.heap.length;
const maxDigit = Math.max(...this.heap as Array<number>);
/** Place holder must be odds [1, 3, 5, 7, 9, 11, ...] ~!*/
const placeholder = (Number.call(null, maxDigit).toString().length & ~1) + 1;
/** Max Depth of Binary Search Tree from [0] to [N] ~!*/
const maxDepth = Math.floor(Math.log(size) / Math.log(2)); // Min Depth = 0; [Root Level]
/** Total Spaces of Line == <The Amount of placeholders> && <The Amount of Space-1 between Placeholders> ~!*/
const totalLineSpaces = placeholder * (2 ** maxDepth) + (2 ** maxDepth - 1);
/** Calculate the spaces need to pad to the Rear-Side and Between each Placeholders ~!*/
const calculateSpace = (level: number): [number, number] => {
/** #equation: ${TotalSpaces} - ${placeholder} * (2 ^ level) == 2x + (2 ^ level - 1)(2x + 1) ~!*/
/** #constraint: ${BetweenSpaces} == (2x + 1) <- Space between each placeholders ~!*/
const rear = (totalLineSpaces - (placeholder + 1) * (2 ** level) + 1) / Math.pow(2, level + 1);
return [rear, 2 * rear + 1];
};
console.log("------------------------------------------");
console.log(">>> Array representation of Heap Array <<<");
console.log("------------------------------------------\n");
let str = ''; /** Heap string builder ~!*/
for (let level = 0; level <= maxDepth; level++) {
const [rear, middle] = calculateSpace(level);
if (level === 0) {
str += " ".repeat(rear) + this.format(this.heap[0], placeholder) + " ".repeat(rear) + "\n";
continue;
}
const elements: Array<string> = [];
/** #description: Looping through each Tree-Layer. Ranged from [2^level - 1] to [2^(level+1) - 2] ~!*/
for (let i = Math.pow(2, level) - 1; i <= Math.pow(2, level + 1) - 2; i++) {
elements.push(this.format(this.heap[i], placeholder));
}
str += " ".repeat(rear) + elements.join(" ".repeat(middle)) + " ".repeat(rear) + "\n";
}
str += "\n" + "------------------------------------------";
return console.log(str);
};

Mean, Median, Variance calculator

I have created a program that calculates the mean, median, and variance. the program accepts up to 500 inputs. All of my methods work perfectly when there are 500 inputs (max size of my array). When there are less inputs, only the 'mean' calculator works. Here's the entire program:
public class StatsPackage{
static int i = 0, arrayLength;
static double sum = 0, mean, median, sumOfSquares, variance, stdDev;
static double calcMean (int inputs[], int count) throws IOException{
for (i = 0; i < count; i++){
sum += inputs[i];
}
mean = (sum/count);
return mean;
}
static double calcMedian (int inputs[], int count){
Arrays.sort(inputs);
if (count % 2 == 0){
median = ((inputs[(count/2)] + inputs[(count/2)- 1])/2) ;
}
if (count % 2 != 0){
median = inputs[(count-1)/2];
}
return median;
}
static double calcVariance (int inputs[], int count){
sum = 0;
for (i = 0; i < count; i++){
sumOfSquares += (inputs[i]*inputs[i]);
}
for (i = 0; i < count; i++){
sum = sum + inputs[i];
}
variance = ((sumOfSquares/count) - (sum * sum)/(count * count));
return variance;
}
static double calcStdDev (double varianceInput){
stdDev = Math.sqrt(variance);
return stdDev;
}
public static void main(String[] args) throws IOException {
NumberFormat nf = new DecimalFormat("0.##");
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
BufferedReader stdin = new BufferedReader (new InputStreamReader (System.in));
String str = "test";
int inputs[] = new int [500];
int counter = 0;
int i = 0;
while ((str = stdin.readLine()) != null && i < 500) {
inputs[i] = Integer.parseInt(str);
i++;
counter++;
}
System.out.println("Mean: " + nf.format(StatsPackage.calcMean(inputs, counter)));
System.out.println("Median: " + nf.format(StatsPackage.calcMedian(inputs, counter)));
System.out.println("Variance: " + nf.format(StatsPackage.calcVariance(inputs, counter)));
System.out.println("Standard Deviation: " + nf.format(StatsPackage.calcStdDev(variance)));
}
}
Here is an example output when 10 random numbers are entered:
Mean: 47.90
Median: 0.00
Variance: 0.00
Standard Deviation: 0.00
Here is the same code when 500 numbers are entered (the max size of my array):
Mean: 47.27
Median: 47.00
Variance: 856.71
Standard Deviation: 29.27
These outputs are consistent. I input 10 numbers, and I only get the mean method to work. I input 500 numbers and I get all of them working. I'm running this program against another tester program, not by inputting the numbers myself in eclipse. The tester program is my instructor's and I trust his program is working correctly.
Can anyone please help? I'm about to tear my hair out.
The problem is that you are initializing an array of size 500, but then not using all 500 indices. That means you have an array like:
[2,5,3,7,8,2,......,0,0,0,0,0,0,0,0,0,0,0,0]
So your code is going to calculate the median and std devation with all those 0s. What you should be using is an ArrayList. An ArrayList will expand in size as you add elements, whereas a regular list cannot change size.
If you cannot use an ArrayList, then you have to do a bit more work.
while ((str = stdin.readLine()) != null && i < 500) {
inputs[i] = Integer.parseInt(str);
i++;
counter++;
}
Your counter variable already has the information you need. Now, before passing this array to your mean/median/stddev methods, you need to reduce the size of the array. The easiest way to do this is to use an existing method provided to all arrays, called CopyOf() : CopyOf() method for Arrays
int[] newArray = Arrays.copyOf(inputs, counter);
Now replace your old input array with your new newArray in your method calls:
System.out.println("Mean: " + nf.format(StatsPackage.calcMean(newArray, counter)));
System.out.println("Median: " + nf.format(StatsPackage.calcMedian(newArray, counter)));
System.out.println("Variance: " + nf.format(StatsPackage.calcVariance(newArray, counter)));
System.out.println("Standard Deviation: " + nf.format(StatsPackage.calcStdDev(variance)));
I assume you tested it with random positive integers, as it seems to be the case for these results.
When you input n (where n is small in comparison to 500) positive integers, your array is mostly full of 0's.
As Array.sort sorts the array in-place, calcMedian modifies the actual array passed, placing all these 0's to the front, and the median is, naturally, 0, as all n of them are in the back.
Then calcVariance calculates the variance of the first n 0's, as the array was sorted previously.
Finally, calcStdDev refers to the result of calcVariance.
To fix this, you should consider:
Sorting the array with this method taking a starting and ending indices.
Making a copy of the array before sorting.
Keeping the class stateless - all these methods could take anything required as arguments (while this is not strictly necessary, it will save you a lot of time in the future).
Your method of calculating variance is wrong. Have a look at the definition of the variance (for instance on wikipedia).
import java.util.Arrays;
public class StatisticalCalculations {
public static void main(String[] args) {
double[] array = { 49, 66, 73, 56, 3, 39, 33, 77, 54, 29 };
double mean = getMean(array);
double var = getVariance(array);
double med = getMedian(array);
System.out.println(Arrays.toString(array));
System.out.println("mean : " + mean);
System.out.println("variance : " + var);
System.out.println("median : " + med);
}
private static double getMean(double[] array) {
int l = array.length;
double sum = 0;
for (int i = 0; i < l; i++)
sum += array[i];
return sum / l;
}
private static double getVariance(double[] array) {
double mean = getMean(array);
int l = array.length;
double sum = 0;
for (int i = 0; i < l; i++)
sum += (array[i] - mean) * (array[i] - mean);
return sum / l;
}
private static double getMedian(double[] array) {
int l = array.length;
// copy array to leave original one untouched by sorting
double[] a = new double[l];
for (int i = 0; i < l; i++)
a[i] = array[i];
Arrays.sort(a);
if (l % 2 == 0)
return (a[l / 2 - 1] + a[l / 2]) / 2;
else
return a[(l - 1) / 2];
}
}
Also, you have an issue with your array, as it is fixed size versus a variable size of user inputs. Consider using ArrayList<Double> or something similar as a container for your values to avoid this problem.

Listing the total sum of all possible sums in a set with constraints

I am keen to find out the following:
Given a set with N elements, my friend and I are playing a game.I always make the first move.
We can only remove either the first or the last element with 50% chance each.We take alternate turns in the game.If only one element remains,we can remove it for sure.What is the expected sum that I can collect?
For example:N=2 {10,20} Possible sets that I can collect are {10},{20}.
So expected sum is 0.5*10+0.5*20=15.
My approach:
Since probability of getting a possible sum is equal in all cases,we only need to compute the sum of all possible sums and then multiply it by (0.5)^N/2.
I tried to use recursion to compute the required sum:
f(i,j)-computes the sum between i and j recursively
f(i,j)=2*a[i]+func(i,j-2)+func(i+1,j-1)+func(i+1,j-1)+func(i+2,j)+2*a[j]);
Initial call f(1,N)
But the approach doesn't seem to work. What should I do?
Complete function is below:
class CandidateCode {
static long v[][] = new long[1003][1003];
public static long func(int a[], int i, int j) {
if (i == j)
return v[i][j] = a[i];
if (v[i][j] != 0)
return v[i][j];
else {
if (i > j - 2 && i + 1 > j - 1 && i + 2 > j)
return (v[i][j] += 2 * a[i] + 2 * a[j]);
else
return (v[i][j] += 2 * a[i] + func(a, i, j - 2) + func(a, i + 1, j - 1) + func(a, i + 1, j - 1)
+ func(a, i + 2, j) + 2 * a[j]);
}
}
public static void main(String args[]) {
int n;
int a[] = { 0, 6, 4, 2, 8 };
n = a.length - 1;
System.out.println(func(a, 1, 4) / Math.pow(2, n / 2));
}
}
This problem can be solved by applying dynamic programming.
First, we have the state of the game is (player ,start, end) ,which indicates the current player, and the range of values that's available in the original set. At the beginning, we start at player 0 and start is 0, end is N - 1.
Denote that the first player is 0 and the second player is 1, we have the expected value of player 0:
if(player == 0){
double result = 0.5*( set[start] + f(1, start + 1,end) ) + 0.5*(set[end] + f(1,start, end - 1));
}else{
double result = 0.5*( f(0, start + 1,end) ) + 0.5*(f(0,start, end - 1));
}
So for each state, we can store all calculated state in a dp[player][start][end] table, which reduce the time complexity to O(2*N*N) with N is number of value in set.
Pseudo code:
double expectedValue(int player, int start, int end, int[]set){
if(start == end)
if(player == 0)
return set[start];
return 0;
if(already calculated this state)
return dp[player][start][end];
double result= 0;
if(player == 0){
result = 0.5*( set[start] + f(1, start + 1,end) ) + 0.5*(set[end] + f(1,start, end - 1));
}else{
result = 0.5*( f(0, start + 1,end) ) + 0.5*(f(0,start, end - 1));
}
return dp[player][start][end] = result;
}

Find the largest palindrome made from the product of two 3-digit numbers

package testing.project;
public class PalindromeThreeDigits {
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;
StringBuilder sb1 = new StringBuilder(""+value1);
String sb2 = ""+value1;
sb1.reverse();
if(sb2.equals(sb1.toString()) && value<value1) {
value = value1;
}
}
}
System.out.println(value);
}
}
This is the code that I wrote in Java... Is there any efficient way other than this.. And can we optimize this code more??
We suppose the largest such palindrome will have six digits rather than five, because 143*777 = 111111 is a palindrome.
As noted elsewhere, a 6-digit base-10 palindrome abccba is a multiple of 11. This is true because a*100001 + b*010010 + c*001100 is equal to 11*a*9091 + 11*b*910 + 11*c*100. So, in our inner loop we can decrease n by steps of 11 if m is not a multiple of 11.
We are trying to find the largest palindrome under a million that is a product of two 3-digit numbers. To find a large result, we try large divisors first:
We step m downwards from 999, by 1's;
Run n down from 999 by 1's (if 11 divides m, or 9% of the time) or from 990 by 11's (if 11 doesn't divide m, or 91% of the time).
We keep track of the largest palindrome found so far in variable q. Suppose q = r·s with r <= s. We usually have m < r <= s. We require m·n > q or n >= q/m. As larger palindromes are found, the range of n gets more restricted, for two reasons: q gets larger, m gets smaller.
The inner loop of attached program executes only 506 times, vs the ~ 810000 times the naive program used.
#include <stdlib.h>
#include <stdio.h>
int main(void) {
enum { A=100000, B=10000, C=1000, c=100, b=10, a=1, T=10 };
int m, n, p, q=111111, r=143, s=777;
int nDel, nLo, nHi, inner=0, n11=(999/11)*11;
for (m=999; m>99; --m) {
nHi = n11; nDel = 11;
if (m%11==0) {
nHi = 999; nDel = 1;
}
nLo = q/m-1;
if (nLo < m) nLo = m-1;
for (n=nHi; n>nLo; n -= nDel) {
++inner;
// Check if p = product is a palindrome
p = m * n;
if (p%T==p/A && (p/B)%T==(p/b)%T && (p/C)%T==(p/c)%T) {
q=p; r=m; s=n;
printf ("%d at %d * %d\n", q, r, s);
break; // We're done with this value of m
}
}
}
printf ("Final result: %d at %d * %d inner=%d\n", q, r, s, inner);
return 0;
}
Note, the program is in C but same techniques will work in Java.
What I would do:
Start at 999, working my way backwards to 998, 997, etc
Create the palindrome for my current number.
Determine the prime factorization of this number (not all that expensive if you have a pre-generated list of primes.
Work through this prime factorization list to determine if I can use a combination of the factors to make 2 3 digit numbers.
Some code:
int[] primes = new int[] {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,
73,79,83,89,97,101,103,107,109,113,,127,131,137,139,149,151,157,163,167,173,
179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,
283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,
419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,
547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,
661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,
811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,
947,953,967,971,977,983,991,997};
for(int i = 999; i >= 100; i--) {
String palstr = String.valueOf(i) + (new StringBuilder().append(i).reverse());
int pal = Integer.parseInt(pal);
int[] factors = new int[20]; // cannot have more than 20 factors
int remainder = pal;
int facpos = 0;
primeloop:
for(int p = 0; p < primes.length; i++) {
while(remainder % p == 0) {
factors[facpos++] = p;
remainder /= p;
if(remainder < p) break primeloop;
}
}
// now to do the combinations here
}
We can translate the task into the language of mathematics.
For a short start, we use characters as digits:
abc * xyz = n
abc is a 3-digit number, and we deconstruct it as 100*a+10*b+c
xyz is a 3-digit number, and we deconstruct it as 100*x+10*y+z
Now we have two mathematical expressions, and can define a,b,c,x,y,z as € of {0..9}.
It is more precise to define a and x as of element from {1..9}, not {0..9}, because 097 isn't really a 3-digit number, is it?
Ok.
If we want to produce a big number, we should try to reach a 9......-Number, and since it shall be palindromic, it has to be of the pattern 9....9. If the last digit is a 9, then from
(100*a + 10*b + c) * (100*x + 10*y + z)
follows that z*c has to lead to a number, ending in digit 9 - all other calculations don't infect the last digit.
So c and z have to be from (1,3,7,9) because (1*9=9, 9*1=9, 3*3=9, 7*7=49).
Now some code (Scala):
val n = (0 to 9)
val m = n.tail // 1 to 9
val niners = Seq (1, 3, 7, 9)
val highs = for (a <- m;
b <- n;
c <- niners;
x <- m;
y <- n;
z <- niners) yield ((100*a + 10*b + c) * (100*x + 10*y + z))
Then I would sort them by size, and starting with the biggest one, test them for being palindromic. So I would omit to test small numbers for being palindromic, because that might not be so cheap.
For aesthetic reasons, I wouldn't take a (toString.reverse == toString) approach, but a recursive divide and modulo solution, but on todays machines, it doesn't make much difference, does it?
// Make a list of digits from a number:
def digitize (z: Int, nums : List[Int] = Nil) : List[Int] =
if (z == 0) nums else digitize (z/10, z%10 :: nums)
/* for 342243, test 3...==...3 and then 4224.
Fails early for 123329 */
def palindromic (nums : List[Int]) : Boolean = nums match {
case Nil => true
case x :: Nil => true
case x :: y :: Nil => x == y
case x :: xs => x == xs.last && palindromic (xs.init) }
def palindrom (z: Int) = palindromic (digitize (z))
For serious performance considerations, I would test it against a toString/reverse/equals approach. Maybe it is worse. It shall fail early, but division and modulo aren't known to be the fastest operations, and I use them to make a List from the Int. It would work for BigInt or Long with few redeclarations, and works nice with Java; could be implemented in Java but look different there.
Okay, putting the things together:
highs.filter (_ > 900000) .sortWith (_ > _) find (palindrom)
res45: Option[Int] = Some(906609)
There where 835 numbers left > 900000, and it returns pretty fast, but I guess even more brute forcing isn't much slower.
Maybe there is a much more clever way to construct the highest palindrom, instead of searching for it.
One problem is: I didn't knew before, that there is a solution > 900000.
A very different approach would be, to produce big palindromes, and deconstruct their factors.
public class Pin
{
public static boolean isPalin(int num)
{
char[] val = (""+num).toCharArray();
for(int i=0;i<val.length;i++)
{
if(val[i] != val[val.length - i - 1])
{
return false;
}
}
return true;
}
public static void main(String[] args)
{
for(int i=999;i>100;i--)
for(int j=999;j>100;j--)
{
int mul = j*i;
if(isPalin(mul))
{
System.out.printf("%d * %d = %d",i,j,mul);
return;
}
}
}
}
package ex;
public class Main {
public static void main(String[] args) {
int i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, flag = 0;
for (i = 999; i >= 100; i--) {
for (j = i; j >= 100; j--) {
k = i * j;
// System.out.println(k);
m = 0;
n = k;
while (n > 0) {
l = n % 10;
m = m * 10 + l;
n = n / 10;
}
if (m == k) {
System.out.println("pal " + k + " of " + i + " and" + j);
flag = 1;
break;
}
}
if (flag == 1) {
// System.out.println(k);
break;
}
}
}
}
A slightly different approach that can easily calculate the largest palindromic number made from the product of up to two 6-digit numbers.
The first part is to create a generator of palindrome numbers. So there is no need to check if a number is palindromic, the second part is a simple loop.
#include <memory>
#include <iostream>
#include <cmath>
using namespace std;
template <int N>
class PalindromeGenerator {
unique_ptr <int []> m_data;
bool m_hasnext;
public :
PalindromeGenerator():m_data(new int[N])
{
for(auto i=0;i<N;i++)
m_data[i]=9;
m_hasnext=true;
}
bool hasNext() const {return m_hasnext;}
long long int getnext()
{
long long int v=0;
long long int b=1;
for(int i=0;i<N;i++){
v+=m_data[i]*b;
b*=10;
}
for(int i=N-1;i>=0;i--){
v+=m_data[i]*b;
b*=10;
}
auto i=N-1;
while (i>=0)
{
if(m_data[i]>=1) {
m_data[i]--;
return v;
}
else
{
m_data[i]=9;
i--;
}
}
m_hasnext=false;
return v;
}
};
template<int N>
void findmaxPalindrome()
{
PalindromeGenerator<N> gen;
decltype(gen.getnext()) minv=static_cast<decltype(gen.getnext())> (pow(10,N-1));
decltype(gen.getnext()) maxv=static_cast<decltype(gen.getnext())> (pow(10,N)-1);
decltype(gen.getnext()) start=11*(maxv/11);
while(gen.hasNext())
{
auto v=gen.getnext();
for (decltype(gen.getnext()) i=start;i>minv;i-=11)
{
if (v%i==0)
{
auto r=v/i;
if (r>minv && r<maxv ){
cout<<"done:"<<v<<" "<<i<< "," <<r <<endl;
return ;
}
}
}
}
return ;
}
int main(int argc, char* argv[])
{
findmaxPalindrome<6>();
return 0;
}
You can use the fact that 11 is a multiple of the palindrome to cut down on the search space. We can get this since we can assume the palindrome will be 6 digits and >= 111111.
e.g. ( from projecteuler ;) )
P= xyzzyx = 100000x + 10000y + 1000z + 100z + 10y +x
P=100001x+10010y+1100z
P=11(9091x+910y+100z)
Check if i mod 11 != 0, then the j loop can be subtracted by 11 (starting at 990) since at least one of the two must be divisible by 11.
You can try the following which prints
999 * 979 * 989 = 967262769
largest palindrome= 967262769 took 0.015
public static void main(String... args) throws IOException, ParseException {
long start = System.nanoTime();
int largestPalindrome = 0;
for (int i = 999; i > 100; i--) {
LOOP:
for (int j = i; j > 100; j--) {
for (int k = j; k > 100; k++) {
int n = i * j * k;
if (n < largestPalindrome) continue LOOP;
if (isPalindrome(n)) {
System.out.println(i + " * " + j + " * " + k + " = " + n);
largestPalindrome = n;
}
}
}
}
long time = System.nanoTime() - start;
System.out.printf("largest palindrome= %d took %.3f seconds%n", largestPalindrome, time / 1e9);
}
private static boolean isPalindrome(int n) {
if (n >= 100 * 1000 * 1000) {
// 9 digits
return n % 10 == n / (100 * 1000 * 1000)
&& (n / 10 % 10) == (n / (10 * 1000 * 1000) % 10)
&& (n / 100 % 10) == (n / (1000 * 1000) % 10)
&& (n / 1000 % 10) == (n / (100 * 1000) % 10);
} else if (n >= 10 * 1000 * 1000) {
// 8 digits
return n % 10 == n / (10 * 1000 * 1000)
&& (n / 10 % 10) == (n / (1000 * 1000) % 10)
&& (n / 100 % 10) == (n / (100 * 1000) % 10)
&& (n / 1000 % 10) == (n / (10 * 1000) % 10);
} else if (n >= 1000 * 1000) {
// 7 digits
return n % 10 == n / (1000 * 1000)
&& (n / 10 % 10) == (n / (100 * 1000) % 10)
&& (n / 100 % 10) == (n / (10 * 1000) % 10);
} else throw new AssertionError();
}
i did this my way , but m not sure if this is the most efficient way of doing this .
package problems;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class P_4 {
/**
* #param args
* #throws IOException
*/
static int[] arry = new int[6];
static int[] arry2 = new int[6];
public static boolean chk()
{
for(int a=0;a<arry.length;a++)
if(arry[a]!=arry2[a])
return false;
return true;
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
InputStreamReader ir = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(ir);
int temp,z,i;
for(int x=999;x>100;x--)
for(int y=999;y>100;y--)
{
i=0;
z=x*y;
while(z>0)
{
temp=z%10;
z=z/10;
arry[i]=temp;
i++;
}
for(int k = arry.length;k>0;k--)
arry2[arry.length- k]=arry[k-1];
if(chk())
{
System.out.print("pelindrome = ");
for(int l=0;l<arry2.length;l++)
System.out.print(arry2[l]);
System.out.println(x);
System.out.println(y);
}
}
}
}
This is code in C, a little bit long, but gets the job done.:)
#include <stdio.h>
#include <stdlib.h>
/*
A palindromic number reads the same both ways. The largest palindrome made from the product of two
2-digit numbers is 9009 = 91 99.
Find the largest palindrome made from the product of two 3-digit numbers.*/
int palndr(int b)
{
int *x,*y,i=0,j=0,br=0;
int n;
n=b;
while(b!=0)
{
br++;
b/=10;
}
x=(int *)malloc(br*sizeof(int));
y=(int *)malloc(br*sizeof(int));
int br1=br;
while(n!=0)
{
x[i++]=y[--br]=n%10;
n/=10;
}
int ind = 1;
for(i=0;i<br1;i++)
if(x[i]!=y[i])
ind=0;
free(x);
free(y);
return ind;
}
int main()
{
int i,cek,cekmax=1;
int j;
for(i=100;i<=999;i++)
{
for(j=i;j<=999;j++)
{
cek=i*j;
if(palndr(cek))
{
if(pp>cekmax)
cekmax=cek;
}
}
}
printf("The largest palindrome is: %d\n\a",cekmax);
}
You can actually do it with Python, it's easy just take a look:
actualProduct = 0
highestPalindrome = 0
# Setting the numbers. In case it's two digit 10 and 99, in case is three digit 100 and 999, etc.
num1 = 100
num2 = 999
def isPalindrome(number):
number = str(number)
reversed = number[::-1]
if number==reversed:
return True
else:
return False
a = 0
b = 0
for i in range(num1,num2+1):
for j in range(num1,num2+1):
actualProduct = i * j
if (isPalindrome(actualProduct) and (highestPalindrome < actualProduct)):
highestPalindrome = actualProduct
a = i
b = j
print "Largest palindrome made from the product of two %d-digit numbers is [ %d ] made of %d * %d" % (len(str(num1)), highestPalindrome, a, b)
Since we are not cycling down both iterators (num1 and num2) at the same time, the first palindrome number we find will be the largest. We don’t need to test to see if the palindrome we found is the largest. This significantly reduces the time it takes to calculate.
package testing.project;
public class PalindromeThreeDigits {
public static void main(String[] args) {
int limit = 99;
int max = 999;
int num1 = max, num2, prod;
while(num1 > limit)
{
num2 = num1;
while(num2 > limit)
{
total = num1 * num2;
StringBuilder sb1 = new StringBuilder(""+prod);
String sb2 = ""+prod;
sb1.reverse();
if( sb2.equals(sb1.toString()) ) { //optimized here
//print and exit
}
num2--;
}
num1--;
}
}//end of main
}//end of class PalindromeThreeDigits
I tried the solution by Tobin joy and vickyhacks and both of them produce the result 580085 which is wrong here is my solution, though very clumsy:
import java.util.*;
class ProjEu4
{
public static void main(String [] args) throws Exception
{
int n=997;
ArrayList<Integer> al=new ArrayList<Integer>();
outerloop:
while(n>100){
int k=reverse(n);
int fin=n*1000+k;
al=findfactors(fin);
if(al.size()>=2)
{
for(int i=0;i<al.size();i++)
{
if(al.contains(fin/al.get(i))){
System.out.println(fin+" factors are:"+al.get(i)+","+fin/al.get(i));
break outerloop;}
}
}
n--;
}
}
private static ArrayList<Integer> findfactors(int fin)
{
ArrayList<Integer> al=new ArrayList<Integer>();
for(int i=100;i<=999;i++)
{
if(fin%i==0)
al.add(i);
}
return al;
}
private static int reverse(int number)
{
int reverse = 0;
while(number != 0){
reverse = (reverse*10)+(number%10);
number = number/10;
}
return reverse;
}
}
Most probably it is replication of one of the other solution but it looks simple owing to pythonified code ,even it is a bit brute-force.
def largest_palindrome():
largest_palindrome = 0;
for i in reversed(range(1,1000,1)):
for j in reversed(range(1, i+1, 1)):
num = i*j
if check_palindrome(str(num)) and num > largest_palindrome :
largest_palindrome = num
print "largest palindrome ", largest_palindrome
def check_palindrome(term):
rev_term = term[::-1]
return rev_term == term
What about : in python
>>> for i in range((999*999),(100*100), -1):
... if str(i) == str(i)[::-1]:
... print i
... break
...
997799
>>>
I believe there is a simpler approach: Examine palindromes descending from the largest product of two three digit numbers, selecting the first palindrome with two three digit factors.
Here is the Ruby code:
require './palindrome_range'
require './prime'
def get_3_digit_factors(n)
prime_factors = Prime.factors(n)
rf = [prime_factors.pop]
rf << prime_factors.shift while rf.inject(:*) < 100 || prime_factors.inject(:*) > 999
lf = prime_factors.inject(:*)
rf = rf.inject(:*)
lf < 100 || lf > 999 || rf < 100 || rf > 999 ? [] : [lf, rf]
end
def has_3_digit_factors(n)
return !get_3_digit_factors(n).empty?
end
pr = PalindromeRange.new(0, 999 * 999)
n = pr.downto.find {|n| has_3_digit_factors(n)}
puts "Found #{n} - Factors #{get_3_digit_factors(n).inspect}, #{Prime.factors(n).inspect}"
prime.rb:
class Prime
class<<self
# Collect all prime factors
# -- Primes greater than 3 follow the form of (6n +/- 1)
# Being of the form 6n +/- 1 does not mean it is prime, but all primes have that form
# See http://primes.utm.edu/notes/faq/six.html
# -- The algorithm works because, while it will attempt non-prime values (e.g., (6 *4) + 1 == 25),
# they will fail since the earlier repeated division (e.g., by 5) means the non-prime will fail.
# Put another way, after repeatedly dividing by a known prime, the remainder is itself a prime
# factor or a multiple of a prime factor not yet tried (e.g., greater than 5).
def factors(n)
square_root = Math.sqrt(n).ceil
factors = []
while n % 2 == 0
factors << 2
n /= 2
end
while n % 3 == 0
factors << 3
n /= 3
end
i = 6
while i < square_root
[(i - 1), (i + 1)].each do |f|
while n % f == 0
factors << f
n /= f
end
end
i += 6
end
factors << n unless n == 1
factors
end
end
end
palindrome_range.rb:
class PalindromeRange
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
def initialize(min = 0, max = FIXNUM_MAX)
#min = min
#max = max
end
def downto
return enum_for(:downto) unless block_given?
n = #max
while n >= #min
yield n if is_palindrome(n)
n -= 1
end
nil
end
def each
return upto
end
def upto
return enum_for(:downto) unless block_given?
n = #min
while n <= #max
yield n if is_palindrome(n)
n += 1
end
nil
end
private
def is_palindrome(n)
s = n.to_s
i = 0
j = s.length - 1
while i <= j
break if s[i] != s[j]
i += 1
j -= 1
end
i > j
end
end
public class ProjectEuler4 {
public static void main(String[] args) {
int x = 999; // largest 3-digit number
int largestProduct = 0;
for(int y=x; y>99; y--){
int product = x*y;
if(isPalindormic(x*y)){
if(product>largestProduct){
largestProduct = product;
System.out.println("3-digit numbers product palindormic number : " + x + " * " + y + " : " + product);
}
}
if(y==100 || product < largestProduct){y=x;x--;}
}
}
public static boolean isPalindormic(int n){
int palindormic = n;
int reverse = 0;
while(n>9){
reverse = (reverse*10) + n%10;
n=n/10;
}
reverse = (reverse*10) + n;
return (reverse == palindormic);
}
}

Categories