I wrote the following code to get all of the numbers from 0 to 1000 that are multiples of three:
public class Hi {
public static void main(String[] args) {
for(int i = 0; i<1000; i++)
if(i % 3 == 0)
System.out.println(i);
}
}
Now I would like to add these numbers together and print the result after the loop.
No need to test for multiplicity of 3 if you iterate by multiples of 3. Finally, to add numbers you should be performing arithmetic. Something like,
long sum = 0;
for (int i = 3; i < 1000; i += 3) {
sum += i;
}
System.out.println(sum);
Or, in Java 8+, using an IntStream (for the same result) like
System.out.println(IntStream.rangeClosed(1, 1000 / 3).map(i -> i * 3).sum());
....And because we all will need java-8 and lambdas oneday...
final List<Integer> myList = new ArrayList<>(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 4, 2, 2 }));
final int sum = myList.stream().filter((i) -> i.intValue() % 3 == 0).mapToInt(Integer::intValue).sum();
System.out.println("Sum of divisible by 3 is " + sum);
As you go through the numbers from 1 to 1000, you can add the multiple of 3 to a list. Then, you could go through that list, and add each number in that list to a sum.
public class Hi {
public static void main(String[] args) {
int[] multiples = new int[1000]; // default initialized with zeroes
mIndex = 0;
for(int i = 0; i<1000; i++) {
if(i % 3 == 0) {
System.out.println(i);
multiples[mIndex] = i;
mIndex++;
}
}
int sum2 = 0;
for(int i2 = 0; i2<mIndex; i2++)
sum2 += multiples[i2];
System.out.println(sum2);
}
}
But that involves going through the numbers twice, and creating another list. It's simpler and more efficient to add the multiple of 3 to a sum as you go from 1 to 1000.
public class Hi {
public static void main(String[] args) {
int sum = 0;
for(int i = 0; i<1000; i++)
if(i % 3 == 0) sum += i;
System.out.println(sum);
}
}
Edit: As the other poster said, there are smarter ways to do this. There are also math formulas for getting this sum in O(1).
Related
I'm currently stuck on a problem with finding pairs in an sorted array with big values. Example: if i get the array sortedarr=[1, 2, 2, 2, 2, 2, 2, 3] as input. It should return pairs = 15.
I have written the below code, which works in O(N2) for both unsorted and sorted arrays. But the code is very basic and i would like for it to be able to manage sorted arrays in an faster time. I guess that the easiest way is to just compare the current element with the one next to it. But i don't know how i can do that. How can i manage to change the code so it will fulfill my requirements?
public static int countpairs(int[] sortedarr) {
int N = sortedarr.length;
int pairs = 0;
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
if (sortedarr[i] == sortedarr[j]) {
pairs++;
}
}
}
return pairs;
}
}
Here is one way to do it in O(N), instead of O(N^2):
public static void main(String[] args) {
int[] a= new int[] {1, 2, 2, 2, 2, 2, 2, 3};
int i = 0;
int n = a.length;
int ans = 0;
while(i < n - 1) {
int dupeCount = 1;
while(i < n - 1 && a[i] == a[i + 1]) {
dupeCount++;
i++;
}
if(dupeCount > 1) {
ans = ans + (dupeCount * (dupeCount-1) / 2);
}
i++;
}
System.out.println(ans);
}
Outputs 15.
The idea is somewhat similar to what Bubble sort uses. We just need to look at each item and its successor in the array to see if it is a duplicate or not. From there, the number of distinct pairs that can be created is just C(dupeCount,2) = dupeCount * (dupeCount - 1) / 2. And we sum all such occurrences to get the final answer.
While running this code I am getting ArrayIndexOutOfBoundsException.
public class Evensum {
public static void main(String[] args) {
int num = Integer.parseInt(args[0]);
int even[] = new int[num];
int sum = 0,j = 0;
String evennums = "";
//Insert your code here
for(j=0; j<=num; j++) {
if(num%2==0) {
even[j]=num;
sum=sum+num;
args[j]= Integer.toString(num);
}
evennums=String.join(",", args);
}
System.out.println(evennums);
System.out.println(sum);
}
}
for (j=0; j<=num; j++)
This is wrong. It should be:
for (j = 0; j < num; j++)
Why? Assume num is 5. Before this line you initialized even to 5. The indices of even would be 0, 1, 2, 3, 4.
Now, with j<=num, you are trying to access the index 5, which does not exist and hence the exception.
args[j]= Integer.toString(num);
This line will raise another exception. I am assuming you're only passing one parameter from the command line which is args[0]. This means the args array is of size 1 and you cannot add more elements to it.
Also, it is not a good practice to add/modify elements to the args array. You should create a new array for this.
Please find the much simpler version of the Code by avoiding the Integer.toString and String.join to pass on the Arguments. Simple Integer Arraylist and adding the elements to will do the Trick.
package com.umapathy.java.learning.programs;
import java.util.ArrayList;
import java.util.List;
public class EvenSum
{
public static void main(String[] args)
{
int num = 20; //Initialize the user-defined value for the loop execution
int sum = 0 ; //Initialize the Sum Value as 0
List<Integer> evenlist = new ArrayList<Integer>(); //Define an integer
Array list
for (int i=2; i<=num; i++) //Begin the loop from the value of 2
{
if(i%2==0) //Logic to find whether a given number is Even Number or not
{
sum = sum + i; // If the logic returns true, Calculate the Sum Value
evenlist.add(i); // Add the Integer to the previous defined Integer
// Arraylist by calling add method
}
}
System.out.println(evenlist); // Print the Output outside the loops
System.out.println(sum);
}
}
Output Generated as follows:--
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20] 110
package javaApp;
public class EvenSum {
public static void main(String[] args) {
int num = 20;
int even[] = new int[num];
int sum = 0,j = 0;
String evennums = "";
for(j=1; j<=num; j++) {
if(j%2==0) {
sum=sum+j;
evennums=evennums+","+j;
}
}
evennums=evennums.replaceFirst(",","");
System.out.println(evennums);
System.out.println(sum);
}
}
Why initialized the even array size if its actual length is unknown in initially. It's better to go with ArrayList in this case which have characteristic to grow dynamically.
Try in this way
public static void main(String[] args) {
int num = Integer.parseInt(args[0]);
List<Integer> evens = new ArrayList<Integer>();
int sum = 0;
for (int j = 0; j <= num; j++) {
if (j % 2 == 0) {
sum += j;
evens.add(j);
}
}
System.out.println("Even Numbers List : "+evens);
System.out.println("Total Sum : "+sum);
// If you want an array of int instead of ArrayList you can convert ArrayList into int[] with following two lines
int evenArray[] = even.stream().mapToInt(x->x).toArray();
System.out.println("Even Numbers Array : "+evenArray);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
//System.out.println("Args: "+args[0]);
int num = Integer.parseInt(args[0]);
int even[] = new int[num];
int sum = 0,j = 0;
String evennums = "";
//Insert your code here
for(j=0; j<=num; j++) {
if(j%2==0) {
//even[j]=num;
sum=sum+j;
if(j!=0) evennums=evennums+","+j;
}
}
evennums=evennums.substring(1);
System.out.println(evennums);
System.out.println(sum);
}
At time of running in eclipse follow below steps:
Right click on class--> Run AS --> Run Configuration
Go to Arguments tab and pass value as 10
Click Run
Output:
2,4,6,8,10
30
I'm developing a game in Android Studio using Java, and I have some troubles with the method that does the counting of the score. Basically in the game I have an array of dices that have values from 1 to 6. Among these values I need to find how many times a special value appears.
Right now I have a method that makes it work fine for finding all single values (like all dices that have the value 5), and also if two dices add up to the special value (like 2 + 3, or 1 + 4). But it doesn't find the special value when there's more than two dices adding up to the number (like 1 + 1 + 3)
Example: If I have the dices with values [1, 2, 2, 2, 3, 5]
The result should be three "numberOfPairs" (1+2+2, 2+3, 5) and therefore the method should return 15, but for me it only returns 10.
I would really appreciate some ideas how to change this method to work better.
Here's the method I've been working on now:
public static int evaluatePoints(Dice dices[], int sumToReach) {
int values[] = new int[dices.length];
int numberOfPairs = 0;
int left = 0;
int right = values.length - 1;
for(int i = 0; i < dices.length; i++){
values[i] = dices[i].getValue();
if(values[i] == sumToReach){
numberOfPairs++;
values[i] = 0;
}
}
Arrays.sort(values);
while (values[right] > sumToReach + values[0]) {
right--;
}
while (left < right) {
if (values[left] + values[right] == sumToReach) {
numberOfPairs++;
left++;
right--;
}
else if(values[left] + values[right] < sumToReach) {
left++;
}
else right--;
}
return numberOfPairs*sumToReach;
}
Your question can be paraphrased as "Get all possible number representations as sum of other natural numbers". Here is pretty good solution.
Explanation of the Algorithm:
Suppose the input array is [1 2 2 2 3 5]
First the program will search for grpSize 6 i.e. 6 elements that sum upto sum of 5
Then the program will search for grpSize 5 i.e. 5 elements that sum upto sum of 5
.
.
.
then the program will search for grpSize 1 i.e. 1 element that sums upto sum of 5
If a set is found then elements will be removed from the resultList
Warning: This approach is recursive, may lead to stack overflow if number of dice increases manyfold
public static boolean func(int grpSize,int sum,int index,List<Integer> resultList,ArrayList<Integer> values) {
if(grpSize==1) {
int j;
for(j = index; j < resultList.size(); j++) {
if(resultList.get(j) == sum) {
values.add(resultList.get(j));
resultList.remove(j);
return true;
}
}
}
for(; index < resultList.size(); index++) {
if(func(grpSize-1, sum-resultList.get(index), index+1, resultList, values)) {
values.add(resultList.get(index));
resultList.remove(index);
return true;
}
}
return false;
}
public static void main(String[] args) {
List<Integer> resultList = new ArrayList<>();
ArrayList<ArrayList<Integer>> values = new ArrayList<>();
resultList.add(1);
resultList.add(2);
resultList.add(2);
resultList.add(2);
resultList.add(3);
resultList.add(5);
//3 2 2 2 3 5
int sum = 5;
int n = resultList.size();
for(int i = 0; i < n; i++) {
int k=i;
while(true) {
values.add(new ArrayList<>());
func(n-i, sum, 0, resultList, values.get(values.size() - 1));
if(values.get(k).isEmpty()) {
break;
} else {
k++;
}
}
}
values.removeIf(p -> p.isEmpty());
System.out.println("Number of pairs: "+values.size());
values.forEach((it) -> {
System.out.println(it);
});
int temp = 0;
for(int i = 0; i < values.size(); i++) {
for(int j = 0; j < values.get(i).size(); j++) {
temp += values.get(i).get(j);
}
}
System.out.println("sum: "+temp);
}
}
Working of recursive function:
This function requires
Group Size to search for
The sum to search for
The starting index which is always zero(could(should) be cleaned up)
The list of each die roll
The list to add found values
This is boolean function which will return true if a particular set if found to add up to THE SUM. The concept is that of basic Backtracking
i am trying to solve some basic java question:
i have an array like int[] x = { 12, 24, 33 };. I need to break it into digits like {1, 2, 2, 4, 3 ,3} and then count the repeating numbers this way: 1:1, 2:2, 3:2, 4:1.
Until now i got this code but i can't save the digits into array.
Can some one help me ?
public class targil_2_3 {
public static void main(String[] args) {
int[] x = { 12, 24, 33 };
int[] ara = new int[x.length * 2];
for (int i = 0; i < x.length; i++) {
for (int j = 0; j < 2; j++) {
ara[j] = x[i] % 10;
x[i] = x[i] / 10;
System.out.println(ara[j]);
}
}
}
}
You dont need to store individual digits, you need to store just count for digits. Lets assume, that you're working with 10 based numbers, then code can looks like
public static void main(String[] args) {
int[] x = { 12, 24, 33, 0, 10, 555 };
int[] count = new int[10];
for (int i = 0; i < x.length; i++) {
int num = x[i];
if (num == 0) {
count[0]++;
continue;
}
while (num > 0) {
count[num % 10]++;
num = num / 10;
}
}
System.out.println(Arrays.toString(count));
}
Output is
[2, 2, 2, 2, 1, 3, 0, 0, 0, 0]
import java.util.Arrays;
import java.util.Map;
import static java.util.stream.Collectors.*;
public class Use {
public static void main(String[] args) {
int[] x = { 12, 24, 33 };
Map<Integer, Long> result = Arrays.stream(x).boxed()
.map(String::valueOf)
.collect(joining())
.chars().boxed()
.collect(groupingBy(Character::getNumericValue, counting()));
System.out.println(result); //prints {1=1, 2=2, 3=2, 4=1}
}
}
Explanation
First line convert an int[] to a Stream<Integer> (for each element)
Convert Stream<Integer> to Stream<String>
Reduce the Stream<String> to String
Create a Stream<Integer> (for each digit)
Count the occurences of each digit in a Map
we have only 10 decimal digits from 0 to 9 , [0..9]
so we make an array with length 10 , like count :
int count[] = new int[10];
for(int i = 0 ; i < x.length ; i++){
if( x[i] == 0 ){
count[0]++;
continue;
}
while(x[i]!=0){
int index = x[i] % 10;
count[index]++;
x[i] /= 10;
}
}
then we will have the number of digits in count array , so we can print it :
for(int i = 0 ; i < 10 ; i++)
System.out.println(i+" : "+count[i]);
if your data is so big it is better to use Map
there are many ways to do this
Digits are 0-9. Build a counter array of size 10, and count each digit extracted in the proper index of the counter array ("counter[digit]++").
Edit: Of- course, in the end you can build the desired result array based on the counter array.
For example: result[0] = "0:" + counter[0];"
Good Luck!
I'm currently working on a problem that asks me to find the millionth lexicographic permutation of 0,1,2,3,4,5,6,7,8,9. I thought of a very crude solution at first glance that had a complexity of around O(n^3)
public static String permute(char[] a){
ArrayList<String> array = new ArrayList<String>();
int counter = 1;
for (int i = 0; i < a.length; i++){
array[counter] += a[i];
for (int j = 0; j < i; j++){
array[counter] += a[j];
for(int k = a.length; k > i; k--){
array[counter] += a[k];}counter++;}
}
}
The code may not be perfect but the idea is that a single digit is selected and then moves to the end of an array. The second array creates the numbers behind the selected digit and the third array creates numbers after it. This seems like a terrible algorithm and i remembered a past algorithm that's like this.
public static HashSet<String> Permute(String toPermute) {
HashSet<String> set = new HashSet<String>();
if (toPermute.length() <= 1 )
set.add(toPermute);
else {
for (int i = 0; i < toPermute.length(); i++ )
for (String s: Permute(toPermute.substring(0,i)+ toPermute.substring(i+1)))
{
set.add(toPermute.substring(i,i+1)+s);}
}
return set;
}
}
The problem is that this algorithm uses unordered sets and I have no idea about how it can become ordered enough for me to find the millionth permutation. I also do not know the complexity other than the fact it could be O(n^2) because it calls itself n times and then unstacks.
A couple of things in general about your code above:
You should implement to interfaces and not concrete classes I.e. List<String> array = .... Similarly with your Set.
Array's start at index 0, you are starting your counter at index 1.
Finally to answer your question there is a brute force way and a more elegant way that uses some principles in math. Have a look at this site which explains the approaches.
It seems to me (1) which permutation is the millionth depends absolutely on the order you use, and (2) permutations of this sort are ripe problems for recursion. I would write this as a recursive program and increment the count for each iteration. [was that your question? I didn't really see a question...]
Here is a solution that is more efficient:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class P24 {
static final int digits[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
static List<Integer> remainedDigits = new ArrayList(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
static final int factorials[] = new int[digits.length + 1];
static final int N = 1000_000;
static int low = -1;
static int lowIndex = -1;
static int highIndex = -1;
public static void main(String args[]) {
populateFactorials(digits.length);
validateN(N);
identifyMargins();
int n = N; // it will be changed
int fixedDigits = digits.length - highIndex;
String result = "";
for (int i = 0; i < fixedDigits; i++) {
result += remainedDigits.get(0);
remainedDigits.remove(0);
}
for (int i = fixedDigits; i < digits.length; i++) {
int pos = 0;
int firstDigit = remainedDigits.get(pos);
low = factorials[lowIndex];
while (n - low > 0) {
pos++;
n -= low;
}
lowIndex--;
result += remainedDigits.get(pos);
remainedDigits.remove(pos);
}
System.out.println(result);
}
private static void validateN(int n) {
if (n < 0 || n > factorials[factorials.length - 1]) {
System.out.println("The input number is not valid");
System.exit(0);
}
}
private static void identifyMargins() {
for (int i = 0; i < factorials.length - 1; i++) {
if (factorials[i] <= N && N < factorials[i + 1]) {
lowIndex = i;
highIndex = i + 1;
}
}
}
private static void populateFactorials(int max) {
for (int i = 0; i <= max; i++) {
factorials[i] = fact(i);
}
}
private static int fact(int x) {
if (x == 0 || x == 1) {
return 1;
}
int p = 1;
for (int i = 2; i <= x; i++) {
p *= i;
}
return p;
}
}
Time: 305 microseconds.
Explanation:
Because the total number of permutations for {a1, ..., an} is n!, I decided that I need a factorials array. I stored in it: {0!, ..., 10!}.
I identified where is the number placed in this sequence, and for our case (N = 1000000) it is between 9! and 10!. If it was lower than 9! I add a padding of fixedDigits digits taken from the remainedDigits array.
Because the number is bigger than 9!, I count how many times I can extract 9! from the number and the result helps me to obtain the first digit. Then, I have a similar approach for 8!, 7!, etc.
The above explanation is based on the following simple observation. If we have a set {a1,...,ai,...,an} and we fix a1, ..., ai, we can obtain (n-i)! different strings.
Notice that if you use:
static List<Integer> remainedDigits = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
you cannot remove elements from the list.
`