I have tried to print all the paths which give the given amount. But my code does not work properly. I think I am missing some points to print all possible combinations. For example;
if amount: 7 and startCoin = 25, the program needs to give me:
{5,1,1} and {1,1,1,1,1,1,1}.
Can you help me to fix these problem?
Note: Preferably Java Solutions
class Solution {
static int[] coinSet = {1,5,10,25};
static List<List<Integer>> possibleWays = new ArrayList<>();
static List<Integer> currentWay = new ArrayList<>();
private static int makeChange(int amount, int startCoin){
boolean flag = false;
for(int i =0 ; i < coinSet.length ; i++){
if(coinSet[i] == startCoin) {
flag =true;
}
}
if(!flag){
throw new IllegalArgumentException("startCoin has to be in the specified range");
}
int nextCoin = 0;
switch(startCoin) {
case 25:
nextCoin = 10;
break;
case 10:
nextCoin = 5;
break;
case 5:
nextCoin = 1;
break;
case 1:
possibleWays.add(currentWay);
currentWay = new ArrayList<>();
return 1;
}
int ways = 0;
for(int count = 0; count * startCoin <= amount; count++){
ways += makeChange(amount - (count * startCoin),nextCoin);
}
return ways;
}
public int calculateNumberOfWays(int amount, int startCoin) throws Exception {
if (amount == 0) {
throw new Exception(); }
return makeChange(amount, startCoin);
}
public static void main(String[] args) {
System.out.println(makeChange(5,25));
System.out.println(possibleWays);
}
}
This can be solved using backtracking but that is not very efficient, below is the working java code
/**
* Created by sumit sharma on 3/1/2016.
*/
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
public class Main {
static int[] coinSet = {1,5,10,25};
static List<List<Integer>> possibleWays = new ArrayList<>();
static List<Integer> currentWay = new ArrayList<>();
public static void main(String[] args) {
List<Integer> countOfCoins = new ArrayList<>();
makeChange(7, 0, countOfCoins);
//System.out.print(possibleWays);
}
private static int makeChange(int amount, int startCoinIdx, List<Integer> coinsSoFar) {
if(startCoinIdx == coinSet.length){
if(amount == 0){
possibleWays.add(coinsSoFar);
System.out.println(coinsSoFar);
}
//System.out.println(coinsSoFar);
return 0;
}
for(int count = 0;(count*coinSet[startCoinIdx]) <= amount;count++){
List<Integer> temp = new ArrayList<>();
for(int i = 0;i < coinsSoFar.size();i++) temp.add(coinsSoFar.get(i));
for(int i = 0;i < count;i++) temp.add(coinSet[startCoinIdx]);
makeChange(amount - (count * coinSet[startCoinIdx]),startCoinIdx+1, temp);
temp.clear();
}
return 0;
}
}
Link to solution on Ideone : http://ideone.com/kIckmG
Related
I have a function that receives a target and a numbers array, and the goal is to return the combination that uses less array numbers to achieve the target.
Example:
sum(8, [1,4,5]) should return [4,4]
sum(7, [5,3,4,7]) should return [7]`
sum(8, [2,3,5]) should return [3,5]
sum(100, [1,2,5,25]) should return [25, 25, 25, 25]
The function was working just fine before I attempted to do the memoization... Here is my code:
import java.util.ArrayList;
public class BestSum {
ArrayList<Integer> memoInt;
ArrayList<ArrayList<Integer>> memoList;
BestSum () {
memoList = new ArrayList<ArrayList<Integer>>();
memoInt = new ArrayList<Integer>();
}
public ArrayList<Integer> sum (int target, int nums[]) {
for(int i = 0; i < memoInt.size(); i++) {
if(memoInt.get(i) == target) {
return memoList.get(i);
}
}
if(target == 0) {
return new ArrayList<Integer>();
}
if(target < 0) {
return null;
}
ArrayList<Integer> shortestCombination = null;
for(int i = 0; i < nums.length; i++) {
int rest = target-nums[i];
ArrayList<Integer> currentCombination = sum(rest, nums);
if(currentCombination != null) {
currentCombination.add(nums[i]);
if(shortestCombination == null || currentCombination.size() < shortestCombination.size()){
shortestCombination = new ArrayList<Integer>();
shortestCombination = (ArrayList)currentCombination.clone();
}
}
}
memoInt.add(target);
memoList.add(shortestCombination);
return shortestCombination;
}
public static void main(String[] args) {
int target = 8;
int nums[] = {1,4,5};
BestSum bs = new BestSum();
System.out.println(bs.sum(target, nums).toString()); //[4,4]
}
}
However when I run this instead of [4,4], I get [4,1,4]... Any suggestions?
Ok So I fix the code :D
import java.util.ArrayList;
import java.util.*;
public class BestSum {
HashMap<Integer, ArrayList<Integer>> hp;
BestSum () {
hp = new HashMap<Integer, ArrayList<Integer>>();
}
public ArrayList<Integer> sum (int target, int nums[]) {
if(hp.containsKey(target)) {
return hp.get(target);
}
if(target == 0) {
return new ArrayList<Integer>();
}
if(target < 0) {
return null;
}
ArrayList<Integer> shortestCombination = null;
for(int i = 0; i < nums.length; i++) {
int rest = target-nums[i];
ArrayList<Integer> currentCombination = sum(rest, nums);
if(currentCombination != null) {
ArrayList<Integer> combination = new ArrayList<Integer>();
combination = (ArrayList)currentCombination.clone();
combination.add(nums[i]);
if(shortestCombination == null || combination.size() < shortestCombination.size()){
shortestCombination = new ArrayList<Integer>();
shortestCombination = (ArrayList)combination.clone();
}
}
}
hp.put(target, shortestCombination);
return shortestCombination;
}
public static void main(String[] args) {
int target = 8;
int nums[] = {1,4,5};
BestSum bs = new BestSum();
System.out.println(bs.sum(target, nums).toString()); //[4,4]
}
}
Tweaked the for loop a little,
for(int i = 0; i < nums.length; i++) {
int rest = target-nums[i];
ArrayList<Integer> currentCombination = sum(rest, nums);
if(currentCombination != null) {
ArrayList<Integer> tempCombination = new ArrayList<>(currentCombination);
tempCombination.add(nums[i]);
if(shortestCombination == null || tempCombination.size() < shortestCombination.size()){
shortestCombination = tempCombination;
}
}
}
It's an important step as the previous memory is being reassigned hence all the old values are pre-stored which caused the issue. I found out while debugging. Always a good idea to assign a new list while using recursion technique.
For my parallel computing class I have to think and create a parallel implementation of the selection sort algorithm. The idea is to be able to scale it to multiple threads so that it becomes faster than the serial implementation.
My idea was as follows:
Parallel selection sort idea
I have created the following implementation over the last few days but it is much slower than the serial algorithm. Whenever I use more threads it is also much slower vs when I use one thread. This is the first time I am working with threads as well so I am not sure if I implemented that correctly.
SelectionSort.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class SelectionSort {
private static final int availableProcessors = Runtime.getRuntime().availableProcessors();
private static final int NUMBER_COUNT = 10000;
private static List<Integer> sortedList = new ArrayList<>();
private static int[][] splitArray;
private static List<Integer> lowestNumbers = new ArrayList<>();
public static void main(String[] args) throws InterruptedException {
List<Integer> numbers = Numbers.GenerateNumber(NUMBER_COUNT);
class Lowest {
synchronized int getLowest(int index) {
int lowestInArray = Integer.MAX_VALUE;
for (int i = 0; i < splitArray[index].length; i++) {
if (splitArray[index][i] < lowestInArray) {
lowestInArray = splitArray[index][i];
}
}
return lowestInArray;
}
}
Lowest lowest = new Lowest();
class SelectionSortThread extends Thread {
private int splitArrayIndex;
private SelectionSortThread(int splitArrayIndex) {
this.splitArrayIndex = splitArrayIndex;
}
public void run() {
lowestNumbers.add(lowest.getLowest(splitArrayIndex));
}
}
long startingTime = System.currentTimeMillis();
for (int i = 0; i < NUMBER_COUNT; i++) {
List<Thread> threads = new ArrayList<>();
splitArray = fillSplitArray(availableProcessors, numbers);
lowestNumbers.clear();
for (int j = 0; j < availableProcessors; j++) {
if(splitArray[j] != null) {
threads.add(new SelectionSortThread(j));
}
}
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
thread.join();
}
int lowestInArray = getLowest(lowestNumbers);
numbers = swap(numbers, lowestInArray);
sortedList.add(numbers.get(0));
numbers.remove(0);
}
System.out.println("Sorted list: " + Arrays.toString(sortedList.toArray()));
System.out.println(System.currentTimeMillis() - startingTime);
}
private static int getLowest(List<Integer> lowestNumbers) {
int lowestInArray = Integer.MAX_VALUE;
for (Integer lowestNumber : lowestNumbers) {
if (lowestNumber < lowestInArray) {
lowestInArray = lowestNumber;
}
}
return lowestInArray;
}
private static List<Integer> swap(List<Integer> list, int lowest)
{
int n = list.size();
for(int i = 0; i < n; i++)
{
if(list.get(i) == lowest) {
Collections.swap(list, 0, i);
return list;
}
}
return null;
}
static int[][] fillSplitArray(int arrayAmount, List<Integer> listToUse) {
if (listToUse.size() == 0) {
return new int[0][0];
}
int splitLength = (int) Math.ceil((double) listToUse.size() / (double) arrayAmount);
int[][] splits = new int[arrayAmount][];
int j = 0;
int k = 0;
for (int i = 0; i < listToUse.size(); i++) {
if (k == splitLength) {
k = 0;
j++;
}
if (splits[j] == null) {
int remainingNumbers = listToUse.size() - i;
splits[j] = new int[Math.min(remainingNumbers, splitLength)];
}
splits[j][k++] = listToUse.get(i);
}
return splits;
};
}
Numbers.java
import java.util.ArrayList;
import java.util.List;
class Numbers {
static List<Integer> GenerateNumber(int numberCount) {
List<Integer> temp = new ArrayList<>();
for (int i = numberCount; i > 0; i--) {
temp.add(i);
}
return temp;
}
}
Is there anything I am doing totally wrong or that I could improve? I am expecting the parallel implementation to be faster than the serial one but so far this is not the case. It is currently a lot slower.
I'm trying to solve this question:
https://www.hackerrank.com/contests/projecteuler/challenges/euler003/submissions/code/2977447
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of a given number N?
Input Format
First line contains T, the number of test cases. This is followed by T lines each containing an integer N.
Output Format
For each test case, display the largest prime factor of N.
Constraints
1≤T≤10
10≤N≤1012
and my code below gets a timeout error for the fifth test (which we don't know about the actual content). any thought why did it fail the test? thanks
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
/* Author: Derek Zhu
* 1and1get2#gmail.com
* https://www.hackerrank.com/contests/projecteuler/challenges/euler003
* */
// The part of the program involving reading from STDIN and writing to STDOUT has been provided by us.
public class Solution {
public static boolean D = true;
static BufferedReader in = new BufferedReader(new InputStreamReader(
System.in));
static StringBuilder out = new StringBuilder();
public static void main(String[] args) throws NumberFormatException,
IOException {
int numOfCases = Integer.parseInt(in.readLine());
for (int i = 0; i < numOfCases; i++){
calculateCase(Long.parseLong(in.readLine()));
}
}
private static void calculateCase(Long input) throws IOException{
if (D) System.out.println("Processing: " + input);
long largestPF = prime(input);
if (D) System.out.print("Final calculate: ");
System.out.println(largestPF);
}
private static long prime(long n){
long i = 2;
while ( n % i != 0 && i < n){
i ++;
}
if (D) System.out.println("found i: " + i);
if (i < n){
return prime(n/i);
} else {
return n;
}
}
public static int primeFactors(BigInteger number) {
BigInteger copyOfInput = number;
int lastFactor = 0;
for (int i = 2;
BigInteger.valueOf(i)
.compareTo(copyOfInput) <= 0; i++) {
if (copyOfInput.mod(BigInteger.valueOf(i))
.compareTo(BigInteger.ZERO) == 0)
{
lastFactor = i;
copyOfInput = copyOfInput
.divide(BigInteger.valueOf(i));
i--;
}
}
return lastFactor;
}
}
Thanks #ajb
as it turns out, taking another method would be much efficient.
private static long method2(long NUMBER){
long result = 0;
for(int i = 2; i < NUMBER; i++) {
if(NUMBER % i == 0 && isPrime(NUMBER / i)) {
result = NUMBER / i;
break;
}
}
return result;
}
private static boolean isPrime(long l) {
for(long num = 2, max = l / 2 ; num < max; num++) {
if(l % num == 0) {
return false;
}
}
return true;
}
complete code with comparison of time can be found here:
https://github.com/1and1get2/hackerrank/blob/master/Contests/ProjectEuler%2B/003_LargestPrimeFactor/src/Solution.java
if (NUMBER<2){
return -1;
}
int result = 0;
for (int i =2; NUMBER>i; i++ ){
if (NUMBER%i==0){
result = NUMBER / i;
if (result/1==result && result/result==1 && result%2!=0 && result%3!=0 && result%5!=0 && result%7!=0){
break;
}
}
}
return result;
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
int count,k=0,n=0;
long arr[]=new long[1000000];
long arr1[]=new long[1000000];
long arr2[]=new long[10000000];
for(int a0 = 0; a0 < t; a0++){
arr[a0] = in.nextLong();
}
for(int i=0;i<t;i++)
{
for(int j=2;j<=arr[i];j++)
{
if(arr[i]%j==0)
{
arr1[k]=j;
k++;
}
}
for(int l=0;l<k;l++)
{
count=0;
for(int m=1;m<=arr1[l];m++)
{
if(arr1[l]%m==0)
{
count++;
}
}
if(count==2)
{
arr2[n]=arr1[l];
n++;
}
}
Arrays.sort(arr2);
System.out.println(arr2[arr2.length-1]);
}
}
}
I have a programming assignment for an introductory level Java class (the subset sum problem) - for some reason, my recursive method isn't executing properly (it just goes straight to the end of the method and prints out the sorted list). Any help would be appreciated - I'm a newbie and recursive functions are really confusing to me.
package programmingassignment3;
import java.io.*;
import java.util.*;
public class ProgrammingAssignment3 {
static int TARGET = 10;
static ArrayList<Integer> list = new ArrayList<>();
static int SIZE = list.size();
public static void main(String[] args) {
populateSortSet();
sumInt(list);
recursiveSS(list);
}//main
public static void populateSortSet() {
try {
File f = new File("set0.txt");
Scanner input = new Scanner(f);
while (input.hasNext()) {
int ele = input.nextInt();
if (ele < TARGET && !list.contains(ele)) {
list.add(ele);
}//if
}//while
Collections.sort(list);
}//try
catch (IOException e) {
e.printStackTrace();
}//catch
}//populateSet
public static void recursiveSS(ArrayList<Integer> Alist) {
if (Alist.size() == SIZE) {
if (sumInt(Alist) == TARGET) {
System.out.println("The integers that equal " + TARGET + "are: " + Alist);
} //if==TARGET
}//if==SIZE
else {
for (int i = 0; i < SIZE; i++) {
ArrayList<Integer> list1 = new ArrayList<>(Alist);
ArrayList<Integer> list0 = new ArrayList<>(Alist);
list1.add(1);
list0.add(0);
if (sumInt(list0) < TARGET) {
recursiveSS(list0);
}//if
if (sumInt(list1) < TARGET) {
recursiveSS(list1);
}//if
}//for
}//else
System.out.println("echo" + Alist);
}//recursiveSS
public static int sumInt(ArrayList<Integer> Alist) {
int sum = 0;
for (int i = 0; i < SIZE - 1; i++) {
sum += Alist.get(i);
}//for
if (Alist.size() == TARGET) {
sum += Alist.get(Alist.size() - 1);
}//if
return sum;
}//sumInt
}//class
This thing that you do at class level:
static ArrayList<Integer> list = new ArrayList<>();
static int SIZE = list.size();
means that SIZE will be initiated to 0, and stay 0 (even if you add elements to the list.)
This means that the code inside the for-loop will be executed 0 times.
Try something like:
public class ProgrammingAssignment3 {
private static int initialSize;
//...
public static void populateSortSet() {
//populate the list
initialSize = list.size();
}
So you don't set the value of the size variable until the list is actually populated.
That being said, there a quite a few other strange things in your code, so I think you need to specify exactly what you are trying to solve here.
Here's how I'd do it. I hope it clarifies the stopping condition and the recursion. As you can see, static methods are not an issue:
import java.util.ArrayList;
import java.util.List;
/**
* Demo of recursion
* User: mduffy
* Date: 10/3/2014
* Time: 10:56 AM
* #link http://stackoverflow.com/questions/26179574/recursive-method-not-properly-executing?noredirect=1#comment41047653_26179574
*/
public class RecursionDemo {
public static void main(String[] args) {
List<Integer> values = new ArrayList<Integer>();
for (String arg : args) {
values.add(Integer.valueOf(arg));
}
System.out.println(String.format("input values : %s", values));
System.out.println(String.format("iterative sum: %d", getSumUsingIteration(values)));
System.out.println(String.format("recursive sum: %d", getSumUsingRecursion(values)));
}
public static int getSumUsingIteration(List<Integer> values) {
int sum = 0;
if (values != null) {
for (int value : values) {
sum += value;
}
}
return sum;
}
public static int getSumUsingRecursion(List<Integer> values) {
if ((values == null) || (values.size() == 0)) {
return 0;
} else {
if (values.size() == 1) { // This is the stopping condition
return values.get(0);
} else {
return values.get(0) + getSumUsingRecursion(values.subList(1, values.size())); // Here is recursion
}
}
}
}
Here is the case I used to test it:
input values : [1, 2, 3, 4, 5, 6]
iterative sum: 21
recursive sum: 21
Process finished with exit code 0
Thanks everyone. I really appreciate the help. I did figure out the problem and the solution is as follows (closing brace comments removed for the reading pleasure of #duffymo ):
public class ProgrammingAssignment3 {
static int TARGET = 6233;
static ArrayList<Integer> set = new ArrayList<>();
static int SIZE;
static int count = 0;
public static void populateSortSet() {
try {
File f = new File("set3.txt");
Scanner input = new Scanner(f);
while (input.hasNext()) {
int ele = input.nextInt();
if (ele < TARGET && !set.contains(ele)) {
set.add(ele);
}
}
Collections.sort(set);
SIZE = set.size();
System.out.println("The original sorted set: " + set + "\t subset sum = " + TARGET);
}
catch (IOException e) {
e.printStackTrace();
}
}
public static void recursiveSS(ArrayList<Integer> list) {
if (list.size() == SIZE) {
if (sumInt(list) == TARGET) {
System.out.print("The Bit subset is: " + list + "\t");
System.out.println("The subset is: " + getSubset(list));
count++;
}
}
else {
ArrayList<Integer> list1 = new ArrayList<>(list);//instantiate list1
ArrayList<Integer> list0 = new ArrayList<>(list);//instantiate list0
list1.add(1);
list0.add(0);
if (sumInt(list0) <= TARGET) {
recursiveSS(list0);
}
if (sumInt(list1) <= TARGET) {
recursiveSS(list1);
}
}
}
public static int sumInt(ArrayList<Integer> list) {
int sum = 0;
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == 1) {
sum += set.get(i);
}
}
return sum;
}
public static ArrayList<Integer> getSubset(ArrayList<Integer> list) {
ArrayList<Integer> l = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == 1) {
l.add(set.get(i));
}
}
return l;
}
}
anyone has any idea how can I limit this program to print only 5 of the 20 elements of the array.
Greetings and thanks.
import java.util.*;
public class lot {
public static void main(String[] args) {
int n[] = {1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
Random rd = new Random();
for (int i = 0; i < n.length; i++) {
System.out.println(rd.nextInt(n[i]) + 1);
}
}
}
import java.util.*;
public class Lot {
public static void main(String[] args) {
int n[] = {1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
Random rd = new Random();
for (int i = 0; i < 5; i++) {
System.out.println(rd.nextInt(n[i]) + 1);
}
}
}
Learn how to use a for loop http://en.wikipedia.org/wiki/For_loop#Java