I'm trying to resolve this problem: Given integer N. Print all the squares of natural numbers, not exceeding N, in ascending order.
For example, lets say N = 50, it prints =
1
4
9
16
25
36
49
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int b = 0;
while (N > b){
b++;
int m = b*b;
System.out.println(m);
if (N < m){
break;
}
With my code I'm getting
1
4
9
16
25
36
49
64
So, it's kinda working but it's exceeding my int N for some reason. Even though the condition states that if N < m, it should break.
What you should do is to, break from loop if condition is met, else print the value. I have rearranged the code below by moving the print statement below the condition -
if (N < m){
break;
}
System.out.println(m);
Your logic is a bit off, you want b + 1 <= Math.sqrt(N). Like,
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int b = 0;
while (b + 1 <= Math.sqrt(N)) {
b++;
System.out.println(b * b);
}
This program pulls two columns from the input.txt file where the first column indicates the value of the object, and the second column represents the weight. The values are imported and placed into two arrays: the value array and the weight array. The knapsack calculations are then made. There are 23 objects in total represented by the rows of the arrays. My code correctly calculates the total value that is being held in the knapsack, and will print out the correct IDs if the weight capacity entered is 5, but for any other weight the IDs being held in the id array are not correct, but the total value printed out is. Here is my code for both files, and if anyone is able to figure out how to correctly save and print the IDs being held in the knapsack please let me know . . .
input.txt file:
17 5
12 8
15 22
17 11
33 21
43 15
15 4
44 35
23 19
10 23
55 39
8 6
21 9
20 28
20 13
45 29
18 16
21 19
68 55
10 16
33 54
3 1
5 9
knapsack.java file:
//We did borrow concepts from:
//http://www.sanfoundry.com/java-program-solve-knapsack-problem-using-dp/
import java.util.Scanner;
import java.util.*;
import java.lang.*;
import java.io.*;
public class knapsack
{
static int max(int a, int b)
{
if(a > b)
{
//System.out.println(a);
return a;
}
else
//System.out.println(b);
return b;
}
static int knapSack(int maxCapacity, int weight[], int value[], int n)
{
int track = 0;
int i, w;
int foo1 = 0;
int foo2 = 0;
K = new int[n+1][maxCapacity+1];
// Build table K[][] in bottom up manner
for (i = 0; i <= n; i++)
{
for (w = 0; w <= maxCapacity; w++)
{
if (i==0 || w==0)
K[i][w] = 0;
else if (weight[i-1] <= w)
{
//K[i][w] = max(value[i-1] + K[i-1][w-weight[i-1]], K[i-1][w]);
if(value[i-1] + K[i-1][w-weight[i-1]] > K[i-1][w])
{
K[i][w] = value[i-1] + K[i-1][w-weight[i-1]];
//System.out.println("A: "+i);
}
else
{
K[i][w] = K[i-1][w];
id[track++] = i;
//System.out.println("B: "+i);
}
}
else
{
K[i][w] = K[i-1][w];
}
}
//System.out.println(K[foo1][foo2]);
}
return K[n][maxCapacity];
}
public static void main(String args[])throws java.io.FileNotFoundException
{
Scanner sc = new Scanner(System.in);
int n = 23;
File file = new File("input.txt");
Scanner scanner = new Scanner(file);
id = new Integer [n];
//knapval = new int[n];
//knapweight = new int [n];
int []value = new int[n];
int []weight = new int[n];
for(int i=0; i<n; i++)
{
value[i] = scanner.nextInt();
weight[i] = scanner.nextInt();
}
System.out.println("Enter the maximum capacity: ");
int maxCapacity = sc.nextInt();
System.out.println("The maximum value that can be put in a knapsack with a weight capacity of "+maxCapacity+" is: " + knapSack(maxCapacity, weight, value, n));
System.out.println();
System.out.println("IDs Of Objects Held In Knapsack: ");
//System.out.println();
for(int z = 0; z < n && id[z] != null; z++)
{
System.out.println(id[z]);
}
if(id[0] == null)
System.out.println("All objects are too heavy, knapsack is empty.");
sc.close();
scanner.close();
}
protected static Integer [] id;
protected static int [][]K;
}
Your way of recording your solution in the id array is flawed. At the time you do id[track++] = i;, you don’t yet know whether i will be in your final solution. Because of the nested loops you may even add i more than once. This in turn may lead to overflowing the array with a java.lang.ArrayIndexOutOfBoundsException: 23 (this happens for max capacity 12 and above).
I suggest instead of using id, after your solution is complete you track your way backward through the K array (by Java naming conventions, it should be a small k). It holds all the information you need to find out which objects were included in the maximum value.
private static void printKnapsack(int maxCapacity, int weight[], int value[], int n) {
if (K[n][maxCapacity] == 0) {
System.out.println("No objects in knapsack");
} else {
int w = maxCapacity;
for (int i = n; i > 0; i--) {
if (K[i][w] > K[i - 1][w]) { // increased value from object i - 1
System.out.format("ID %2d value %2d weight %2d%n", i, value[i - 1], weight[i - 1]);
// check that value in K agrees with value[i - 1]
assert K[i - 1][w - weight[i - 1]] + value[i - 1] == K[i][w];
w -= weight[i - 1];
}
}
}
}
The above prints the objects backward. Example run:
Enter the maximum capacity:
13
The maximum value that can be put in a knapsack with a weight capacity of 13 is: 36
ID 13 value 21 weight 9
ID 7 value 15 weight 4
If you want the objects in forward order, inside the for loop put them into a list (you may for instance use id from your old attempt), and then print the items from the list in opposite order.
I'm trying to write a program which takes as arguments a number of digits and a base, and counts upward through the numbers that have their nonzero digits in ascending order. For instance, in base 4 with 3 digits, it should print:
000 001 002 003 010 011 012 013 020 022 023 030 033 100 101 102 103
110 111 112 113 120 122 123 130 133 200 202 203 220 222 223 230 233
300 303 330 333
and in base 3 with 4 digits it should print:
0000 0001 0002 0010 0011 0012 0020 0022 0100 0101 0102 0110 0111 0112
0120 0122 0200 0202 0220 0222 1000 1001 1002 1010 1011 1012 1020 1022
1100 1101 1102 1110 1111 1112 1120 1122 1200 1202 1220 1222 2000 2002
2020 2022 2200 2202 2220 2222
I have done this successfully, but my algorithm seems unnecessarily complicated and time-consuming (time is very important for my application). Is there any way of either making it faster, or simplifying it if the speed cannot be improved?
Here is the program:
public static void count(int base, int size)
{
int[] array = new int[size];
print(array); // private print method prints out the array
int index = 0;
while (index < array.length)
{
if (array[index] < base - 1)
{
// check whether we need to increase array[index] by extra to maintain the order
if (array[index] == 0)
{
int i;
// search for the next nonzero digit
// this search seems to take unnecessary time; is there a faster alternative?
for (i = index + 1; i < array.length && array[i] == 0; i++);
// check whether there was, in fact, some later nonzero digit
if (i < array.length) array[index] = array[i];
else array[index] = 1;
}
else array[index]++;
print(array);
index = 0;
}
// carry over to the next digit
else array[index++] = 0;
}
}
I would go for a recursive solution:
public static void count(int base, int size) {
int[] configuration = new int[size];
placeDigits(configuration, base, 0, 1);
}
public static void placeDigits(int[] configuration, int base, int pos, int minNonZero) {
if (pos >= configuration.length) {
print(configuration);
} else {
// 0 is a possible candidate
configuration[pos] = 0;
placeDigits(configuration, base, pos + 1, minNonZero);
// digits between minNonZero and base
for (int d = minNonZero; d < base; d++) {
configuration[pos] = d;
placeDigits(configuration, base, pos + 1, d);
}
}
}
It places digits one after the other into the array and observes the constraint that the non-zero digits must be non decreasing.
Okay, this is a bit of a cheat, but here's a solution expressed in pseudocode:
results : list
for i in 1..max
if '0' not in str(i)
append i to results
fi
rof
print results
On the other hand, is it a cheat? "numbers with nonzero digits" is inherently a question about the decimal representation of the numbers, not in some sense the numbers themselves.
Time complexity is O(n) of course -- at least counting str(i) as a single step, which is where it is a little bit of a cheat.
Just for fun, here's the same solution in Python:
print [i for i in xrange(max) if '0' not in str(i)]
And a sketch of a recursive solution:
Let dig be a list of the nonzero digits, i.e., ['1','2','3','4','5','6','7','8','9']. Enumerate all strings on that list of length ceil(log10(max)) (quiz question, why that limit?).
Print those strings in order, stopping when max is exceeded.
If you don't mind keeping the numbers in memory, you could code the following algorithm:
Start with the numbers 0,1...base-1
For each added digit, d, first add zero, then all previous numbers that begin with digits d or higher (indexing those by starting digit and number of digits, you could access them directly).
Or, as some like to phrase, dp style: Let dp[i][j] represent the sequence of numbers with i digits and left-most digit j. Then dp[i][j] = [d] ++ map (d +) dp[l][k], for all l < i and k >= j, where d = j * 10 ^ (i - 1)
(I borrowed the ++ from Haskell, where it often means to concat lists).
For example, base 4, 3 digits:
Start with one digit:
0,1,2,3
Add to the second digit from the first sequence:
10,11,12,13
20,22,23
30,33
Third digit, add from all previous sequences:
100,101,102,103
110,111,112,113
120,122,123
130,133
200,202,203
220,222,223
230,233
300,303
330,333
JavaScript code:
var base = 4;
var dp = [,[]];
for (var j=0; j<base; j++){
dp[1][j] = [j];
}
for (var i=2; i<4; i++){
dp[i] = [];
for (var j=1; j<base; j++){
var d = j * Math.pow(10,i - 1);
dp[i][j] = [d];
for (var l=1; l<i; l++){
for (var k=j; k<base; k++){
dp[i][j] = dp[i][j].concat(
dp[l][k].map(function(x){
return d + x;
}));
}
}
}
}
console.log(JSON.stringify(dp))
/*
[null,[[0],[1],[2],[3]]
,[null,[10,11,12,13]
,[20,22,23]
,[30,33]]
,[null,[100,101,102,103,110,111,112,113,120,122,123,130,133]
,[200,202,203,220,222,223,230,233]
,[300,303,330,333]]]
*/
Late to the party for this faster answer:
Base 8
Size 20 digits
Current solution: 79 seconds (76~82)
Solution below: 23 seconds (22~24)
Possible numbers: 12245598208
without prints. Principle:
The rule "a digit may be followed by a 0 or a digit >= preceding ones" is also valid for (valid) groups of digits: "a group may be followed by a group of zeroes, or a group which smaller digit is >= any of the preceding ones among the preceding groups". Processing is done at the group level, rather than at the digit level.
Given T total size, and N smaller number of digits in each group (T % N == 0), by calculating all possible groups of N digits they can then be assembled together (T / N groups per solution).
pre-calculate all possible digits on a smaller size, eg 5 (2668 numbers), in an array (takes less than half a second)
keep the maximum digit for each of the "parts" in another array
set in another "atleast" array the indexes of groups based on their smaller digit
build the large numbers by sticking all possible chunks (eg 4x5), provided that the lower digit of a group has to be >= highest of the preceding groups.
Sample code to precalculate the small chunks (parts)
static ArrayList<int[]> parts = new ArrayList<int[]>();
static ArrayList<ArrayList<Integer>> atleast = new ArrayList<ArrayList<Integer>>();
static ArrayList<Integer> maxi = new ArrayList<Integer>();
static int stick[];
static int base;
static long num = 0;
public static void makeParts(int min, int ptr)
{
int me = 0;
do {
array[ptr] = me;
if (ptr > 0) makeParts(Math.max(me,min), ptr-1);
else {
// add part
int[] newa = new int [array.length];
int i,mi,ma,last=array.length-1;
for (i=0 ; i<array.length ; i++) newa[i] = array[i];
parts.add(newa);
// maxi
for (i=0 ; i<=last && newa[i]==0 ; i++) /* */;
maxi.add(ma = i<=last ? newa[i] : 0);
// mini
for (i=last ; i>=0 && newa[i]==0 ; i--) /* */;
mi = i>=0 ? newa[i] : 0;
// add to atleast lists
int pi = parts.size() - 1;
ArrayList<Integer> l;
int imi = mi == 0 ? base-1 : mi;
for (i=0 ; i<=imi ; i++) {
if (i < atleast.size()) l = atleast.get(i);
else {
l = new ArrayList<Integer>();
atleast.add(i, l);
}
l.add(pi);
}
}
me = me == 0 ? (min > 0 ? min : 1) : me+1;
} while (me < base);
}
Sticking the "parts"
public static void stickParts(int minv, int ptr)
{
// "atleast" gives indexes in "parts" of groups which min digit
// is at least "minv" (or only zeroes)
for (int pi: atleast.get(minv)) {
stick[ptr] = pi;
if (ptr > 0) {
stickParts(Math.max(minv,maxi.get(pi)), ptr-1);
}
else {
// count solutions
// the number is made of "parts" from indexes
// stored in "stick"
num++;
}
}
}
Calling this in "main"
base = 8;
int leng = 20;
int pleng = 4;
array = new int [pleng];
makeParts(0,array.length-1);
num = 0;
stick = new int [leng / pleng];
stickParts(0, (leng/pleng) - 1);
out.print(String.format("Got %d numbers\n", num));
If T (total size) is prime, for instance, another specific group has to be calculated, eg for size 17, we could have 3 groups (of 5 digits) + one group of two digits.
Quite an interesting program you have written.
I've tried to increase the performance of the nested search, but so far I haven't found a way to make the worst-case scenario of searching for the next nonzero digit less than O(n).
In the worst-case scenario, the subarray A[i..array.length-1] is not sorted, and array[i] = 0,therefore to find the next non-zero digit, you have to do a linear search.
Aditionally, if there is no next non-zero digit, you have to search the whole array to "find it".
(For example: we have that i = 1 for the sequence '0040'. The subarray [0, 4, 0] is not sorted, so you have to do a linear search to find the next largest/smallest nonzero digit, which would be located in array[2])
The complexity for the worst case will be O(n).
Can you improve running time? I guess you can if you do some parallel programming, but I have no knowledge of that field to help you, unfortunately.
This recursive function tries to avoid any unnecessary loop
public static void count0(int min, int ptr)
{
int me = 0; // joker
do {
array[ptr] = me;
if (ptr > 0) count0(Math.max(me,min), ptr-1);
else print(array);
me = me == 0 ? (min > 0 ? min : 1) : me+1;
} while (me < base);
}
Called like this (base 8 for length of 17) to carry less arguments:
static int array[];
static int base;
int leng = 17;
base = 8;
array = new int [leng];
count0 (0, array.length-1);
Recursivity has its price, though.
I didn't measure performance, but think my code is better readable.
The idea is, to produce every number of base b and length l by Integer-iteration from 0 to the known number in decimal, using the Java-build-in conversion decimal to base b, then removing the zeros in that number (which is of type String) and testing for ascending order.
The output has to be padded with zeros, so therefore the complicated printf in the end.
public static boolean isAscending (String digits) {
for (int i = 1; i < digits.length (); ++i)
if (digits.charAt (i-1) > digits.charAt (i))
return false;
return true;
}
public static void count (int base, int size)
{
/**
Build numbers,i.e. from 000 to 333, for base 4 at length 3
or 4^3 = 4*4*4 = 64 combinations
*/
double max = Math.pow (base, size);
for (int i = 0; i < max; ++i)
{
String res = Integer.toString (i, base);
if (isAscending (res.replaceAll ("0", "")))
System.out.printf ("%0"+size+"d ", Long.parseLong (res));
}
}
i had a question regarding counting all possible combinations. For example if i have a recursive method that gives me an output of:
a. 0 0
b. 0 1
c. 1 0
d. 1 1
in this case i have 8 possible outputs. how should i count them using java?
i tried to use a counter but its giving me 4.
Please help.
Thanks.
here is my code.
public static void printAllAssignments(char set[], int k) {
int n = set.length;
printAllAssignments(set, "", n, k);
}
// The main recursive method to print all possible strings of length k
public static void printAllAssignments(char set[], String prefix, int n, int k) {
// Base case: k is 0, print prefix
if (k == 0) {
counterTotalAssignments++;
System.out.println("Occupancies: " + prefix);
return;
}
// One by one add all characters from set and recursively
// call for k equals to k-1
for (int i = 0; i < n; ++i) {
// Next character of input added
String newPrefix = prefix + set[i];
// k is decreased, because we have added a new character
printAllAssignments(set, newPrefix, n, k - 1);
}
}
public static void main(String[] args) {
char charSet[] = {'0', '1'};
int k = 2;
printAllAssignments(charSet, k);
System.out.println("Total number of assignments: " + counterTotalAssignments);
}
output:
Occupancies: 00
Occupancies: 01
Occupancies: 10
Occupancies: 11
Total number of assignments: 4
There's no reason to count them, when they can be calculated from your input:
combinations = exp (possible values per digit, number of digits)
If you insist on counting them I'd use the in your case unused return value:
Have the base case return 1 and return the sum of the return values of the recursive calls in the recursive case.
I just noticed that your counter is giving you the correct value. Why were you expecting it to be 8?
00 // 1.
01 // 2.
10 // 3.
11 // 4.
i want to print all armstrong number between 1 to 1000 in a textfield using awt or swing but i only get last value by my code .So pls help me
public void actionPerformed(ActionEvent e)
{
String s1=tf.getText();
int n1=Integer.parseInt(s1);
for(int n=0;n<10000;n++)
{
int sum=0;
int number=n;
int original=number;
while(number>0)
{
int r=number%10;
sum+=r*r*r;
number=number/10;
}
if(sum==original)
{
tf1.setText(String.valueOf(original[i]));
}
}
}
For those who don't know, an Armstrong number (or narcissistic number) is a number with n digits that is equal to the sum of each of its digits to the nth power.
(x1*10(n-1))+(x1*10(n-2))...+(x1*10(n-n)) = (x1)n+(x2)n...+(xn)n
This means that if the number is 1 digit, the power will be 1.
Therefore there are 10 1 digit numbers that are Armstrong numbers:
0 = 01
1 = 11
2 = 21
3 = 31
4 = 41
5 = 51
6 = 61
7 = 71
8 = 81
9 = 91
Your code, as written, will not identify any of those numbers as Armstrong numbers.
Your code will also incorrectly identify some numbers as 4 digit Armstrong numbers because you only look for the the cubes (3rd power) of your numbers not the 4th power.
(You don't have to worry about twos because there are no two digit Armstrong numbers)
In order to correctly determine all the possible Armstrong numbers between 1 and 10000, you need to write a "power" loop that finds the nth power of a number by multiplying the number n times.
This would look something like:
//... beginning of your original function
//added a string to hold all the values before printing
string holder = "";
for(int n=0;n<10000;n++){
int sum=0;
//n=original you had duplicate variables (just use n as original)
int number = n;
//while there are still digits left
while(number>0){
//get the smallest digit
int r=number%10;
//----------"Power" loop-----------
int foo = n;
//once smaller than 10, it's only a power of 1 (which is itself)
while(foo>=10){
//this means foo = foo/10
foo /= 10;
//this means r = r*r
r*=r;
}
//this means sum = sum+r
sum += r;
//you should have the hang of it by now
number/=10;
}
//if the sum equals the original number
if(sum==n){
//put that number into the end of a string (separated by newlines `\n`)
holder+=n+"\n";
}
}
//All done, so set the text box value
tf1.setText(holder);
//... whatever code you want to finish up
This should also take care of your problem with the textBox getting overwritten each time. By saving the numbers into a string and then printing all of them at once, only once (no overwriting), you'll get better results.
You always set the current found value. But you should set the previous found values + current found value.
tf1.setText(String.valueOf(original));
But more performant would be to use a stringbuilder object and append the result each time and set this value to the textfield outside the loop.
public void actionPerformed(ActionEvent e)
{
StringBuilder s = new StringBuilder ();
for(int n=0;n<10000;n++)
{
int sum=0;
int number=n;
int original=number;
while(number>0)
{
int r=number%10;
sum+=r*r*r;
number=number/10;
}
if(sum==original)
{
s.append(original + " ");
}
}
tf1.setText (stringBuilder.toString ());
}
Easy, all you do is change the setText() method of the TextField1 component with append().
It works! The remaining will do! Try it once.
public void actionPerformed(ActionEvent e)
{
String s1=tf.getText();
int n1=Integer.parseInt(s1);
for(int n=0;n<10000;n++)
{
int sum=0;
int number=n;
int original=number;
while(number>0)
{
int r=number%10;
sum+=r*r*r;
number=number/10;
}
if(sum==original)
{
tf1.append(String.valueOf(original[i] + " "));
}
}
}
Very simple program in C to list all armstrong number between 1 to 1000000.
#include<stdio.h>
#include<conio.h>
#include<math.h>
main()
{
long a = 1, c=0, b, e, f, d = 0,g=0,p,j,count=0;
printf("All armstron number between 1 and 1000000 is listed below!\n");
while (c <= 1000000)
{
j = c;
if (j >= 10)
{
while (j >= 10)
{
j = j / 10;
g++;
}
}
p = g + 1;
g = 0;
a = c;
f = a;
while (a >= 10)
{
b = a % 10;
d = d + pow(b,p);
a = a / 10;
}
e = pow(a,p) + d;
d = 0;
if (e == f)
{
count++;
printf("%ld\t",count );
printf("%ld\n", f);
}
c++;
}
getch();
}