Find the number of multiples for a number in range - java

I have a question regarding the CountDiv problem in Codility.
The problem given is: Write a function:
class Solution { public int solution(int A, int B, int K); }
that, given three integers A, B and K, returns the number of integers within the range [A..B] that are divisible by K, i.e.:
{ i : A ≤ i ≤ B, i mod K = 0 }
My code:
class Solution {
public int solution(int A, int B, int K) {
int start=0;
if (B<A || K==0 || K>B )
return 0;
else if (K<A)
start = K * ( A/K +1);
else if (K<=B)
start = K;
return (B-start+1)/K+ 1;
}
}
I don't get why I'm wrong, specially with this test case:
extreme_ifempty
A = 10, B = 10, K in {5,7,20}
WRONG ANSWER
got 1 expected 0
if K =5 then with i=10 A<=i<=B and i%k =0 so why should I have 0? Problem statement.

This is the O(1) solution, which passed the test
int solution(int A, int B, int K) {
int b = B/K;
int a = (A > 0 ? (A - 1)/K: 0);
if(A == 0){
b++;
}
return b - a;
}
Explanation: Number of integer in the range [1 .. X] that divisible by K is X/K. So, within the range [A .. B], the result is B/K - (A - 1)/K
In case A is 0, as 0 is divisible by any positive number, we need to count it in.

Java solution with O(1) and 100% in codility, adding some test cases with solutions for those who want to try and not see others solutions:
// Test cases
// [1,1,1] = 1
// [0,99,2] = 50
// [0, 100, 3] = 34
// [11,345,17] = 20
// [10,10,5] = 1
// [3, 6, 2] = 2
// [6,11,2] = 3
// [16,29,7] = 2
// [1,2,1] = 2
public int solution(int A, int B, int K) {
int offsetForLeftRange = 0;
if ( A % K == 0) { ++offsetForLeftRange; }
return (B/K) - (A /K) + offsetForLeftRange;
}

The way to solve this problem is by Prefix Sums as this is part of that section in Codility.
https://codility.com/programmers/lessons/3/
https://codility.com/media/train/3-PrefixSums.pdf
Using this technique one can subtract the count of integers between 0 and A that are divisible by K (A/K+1) from the the count of integers between 0 and B that are divisible by K (B/K+1).
Remember that A is inclusive so if it is divisible then include that as part of the result.
Below is my solution:
class Solution {
public int solution(int A, int B, int K) {
int b = (B/K) + 1; // From 0 to B the integers divisible by K
int a = (A/K) + 1; // From 0 to A the integers divisible by K
if (A%K == 0) { // "A" is inclusive; if divisible by K then
--a; // remove 1 from "a"
}
return b-a; // return integers in range
}
}

return A==B ? (A%K==0 ? 1:0) : 1+((B-A)/K)*K /K;
Well it is a completely illegible oneliner but i posted it just because i can ;-)
complete java code here:
package countDiv;
public class Solution {
/**
* First observe that
* <li> the amount of numbers n in [A..B] that are divisible by K is the same as the amount of numbers n between [0..B-A]
* they are not the same numbes of course, but the question is a range question.
* Now because we have as a starting point the zero, it saves a lot of code.
* <li> For that matter, also A=-1000 and B=-100 would work
*
* <li> Next, consider the corner cases.
* The case where A==B is a special one:
* there is just one number inside and it either is divisible by K or not, so return a 1 or a 0.
* <li> if K==1 then the result is all the numbers between and including the borders.
* <p/>
* So the algorithm simplifies to
* <pre>
* int D = B-A; //11-5=6
* if(D==0) return B%K==0 ? 1:0;
* int last = (D/K)*K; //6
* int parts = last/K; //3
* return 1+parts;//+1 because the left part (the 0) is always divisible by any K>=1.
* </pre>
*
* #param A : A>=1
* #param B : 1<=A<=B<=2000000000
* #param K : K>=1
*/
private static int countDiv(int A, int B, int K) {
return A==B ? A%K==0 ? 1:0 : 1+((B-A)/K)*K /K;
}
public static void main(String[] args) {
{
int a=10; int b=10; int k=5; int result=1;
System.out.println( a + "..." + b + "/" + k + " = " + countDiv(a,b,k) + (result!=countDiv(a,b,k) ? " WRONG" :" (OK)" ));
}
{
int a=10; int b=10; int k=7; int result=0;
System.out.println( a + "..." + b + "/" + k + " = " + countDiv(a,b,k) + (result!=countDiv(a,b,k) ? " WRONG" :" (OK)" ));
}
{
int a=6; int b=11; int k=2; int result=3;
System.out.println( a + "..." + b + "/" + k + " = " + countDiv(a,b,k) + (result!=countDiv(a,b,k) ? " WRONG" :" (OK)" ));
}
{
int a=6; int b=2000000000; int k=1; int result=b-a+1;
System.out.println( a + "..." + b + "/" + k + " = " + countDiv(a,b,k) + (result!=countDiv(a,b,k) ? " WRONG" :" (OK)" ));
}
}
}//~countDiv

I think the answers above don't provide enough logical explanation to why each solution works (the math behind the solution) so I am posting my solution here.
The idea is to use the arithmetic sequence here. If we have first divisible number (>= A) and last divisible number (<= B) we have an arithmetic sequence with distance K. Now all we have to do is find the total number of terms in the range [newA, newB] which are total divisible numbers in range [newA, newB]
first term (a1) = newA
last/n-th term (an) = newB
distance (d) = K
Sn = a1 + (a1+K) + (a1 + 2k) + (a1 + 3k) + ... + (a1 + (n-1)K)
`n` in the above equation is what we are interested in finding. We know that
n-th term = an = a1 + (n-1)K
as an = newB, a1 = newA so
newB = newA + (n-1)K
newB = newA + nK - K
nK = newB - newA + K
n = (newB - newA + K) / K
Now that we have above formula so just apply it in code.
fun countDiv(A: Int, B: Int, K: Int): Int {
//NOTE: each divisible number has to be in range [A, B] and we can not exceed this range
//find the first divisible (by k) number after A (greater than A but less than B to stay in range)
var newA = A
while (newA % K != 0 && newA < B)
newA++
//find the first divisible (by k) number before B (less than B but greater than A to stay in range)
var newB = B
while (newB % K != 0 && newB > newA)
newB--
//now that we have final new range ([newA, newB]), verify that both newA and newB are not equal
//because in that case there can be only number (newA or newB as both are equal) and we can just check
//if that number is divisible or not
if (newA == newB) {
return (newA % K == 0).toInt()
}
//Now that both newA and newB are divisible by K (a complete arithmetic sequence)
//we can calculate total divisions by using arithmetic sequence with following params
//a1 = newA, an = newB, d = K
// we know that n-th term (an) can also be calculated using following formula
//an = a1 + (n - 1)d
//n (total terms in sequence with distance d=K) is what we are interested in finding, put all values
//newB = newA + (n - 1)K
//re-arrange -> n = (newB - newA + K) / K
//Note: convert calculation to Long to avoid integer overflow otherwise result will be incorrect
val result = ((newB - newA + K.toLong()) / K.toDouble()).toInt()
return result
}
I hope this helps someone. FYI, codility solution with 100% score

Simple solution in Python:
def solution(A, B, K):
count = 0
if A % K == 0:
count += 1
count += int((B / K) - int(A / K))
return count
explanation:
B/K is the total numbers divisible by K [1..B]
A/K is the total numbers divisible by K [1..A]
The subtracts gives the total numbers divisible by K [A..B]
if A%K == 0, then we need to add it as well.

This is my 100/100 solution:
https://codility.com/demo/results/trainingRQDSFJ-CMR/
class Solution {
public int solution(int A, int B, int K) {
return (B==0) ? 1 : B/K + ( (A==0) ? 1 : (-1)*(A-1)/K);
}
}
Key aspects of this solution:
If A=1, then the number of divisors are found in B/K.
If A=0, then the number of divisors are found in B/K plus 1.
If B=0, then there is just one i%K=0, i.e. zero itself.

Here is my simple solution, with 100%
https://app.codility.com/demo/results/trainingQ5XMG7-8UY/
public int solution(int A, int B, int K) {
while (A % K != 0) {
++A;
}
while (B % K != 0) {
--B;
}
return (B - A) / K + 1;
}

Python 3 one line solution with score 100%
from math import ceil, floor
def solution(A, B, K):
return floor(B / K) - ceil(A / K) + 1

This works with O(1) Test link
using System;
class Solution
{
public int solution(int A, int B, int K)
{
int value = (B/K)-(A/K);
if(A%K == 0)
{
value=value+1;
}
return value;
}
}

I'm not sure what are you trying to do in your code, but simpler way would be to use modulo operator (%).
public int solution(int A, int B, int K)
{
int noOfDivisors = 0;
if(B < A || K == 0 || K > B )
return 0;
for(int i = A; i <= B; i++)
{
if((i % K) == 0)
{
noOfDivisors++;
}
}
return noOfDivisors;
}

If I understood the question correctly I believe this is the solution:
public static int solution(int A, int B, int K) {
int count = 0;
if(K == 0) {
return (-1);
}
if(K > B) {
return 0;
}
for(int i = A; i <= B; ++i) {
if((i % K) == 0) {
++count;
}
}
return count;
}
returning -1 is due to an illegal operation (division by zero)

int solution(int A, int B, int K) {
int tmp=(A%K==0?1:0);
int x1=A/K-tmp ;
int x2=B/K;
return x2-x1;
}

100/100 - another variation of the solution, based on Pham Trung's idea
class Solution {
public int solution(int A, int B, int K) {
int numOfDivs = A > 0 ? (B / K - ((A - 1) / K)) : ((B / K) + 1);
return numOfDivs;
}
}

class Solution {
public int solution(int A, int B, int K) {
int a = A/K, b = B/K;
if (A/K == 0)
b++;
return b - a;
}
}
This passes the test.
It's similar to "how many numbers from 2 to 5". We all know it's (5 - 2 + 1). The reason we add 1 at the end is that the first number 2 counts.
After A/K, B/K, this problem becomes the same one above. Here we need to decide if A counts in this problem. Only if A%K == 0, it counts then we need to add 1 to the result b - a (the same with b+1).

Here's my solution, two lines of Java code.
public int solution(int A, int B, int K) {
int a = (A == 0) ? -1 : (A - 1) / K;
return B / K - a;
}
The thought is simple.
a refers to how many numbers are divisible in [1..A-1]
B / K refers to how many numbers are divisible in [1..B]
0 is divisible by any integer so if A is 0, you should add one to the answer.

Here is my solution and got 100%
public int solution(int A, int B, int K) {
int count = B/K - A/K;
if(A%K == 0) {
count++;
}
return count;
}
B/K will give you the total numbers divisible by K [1..B]
A/K will give you the total numbers divisible by K [1..A]
then subtract, this will give you the total numbers divisible by K [A..B]
check A%K == 0, if true, then + 1 to the count

Another O(1) solution which got 100% in the test.
int solution(int A, int B, int K) {
if (A%K)
A = A+ (K-A%K);
if (A>B)
return 0;
return (B-A)/K+1;
}

This is my 100/100 solution:
public int solution1(int A, int B, int K) {
return A == 0 ? B / K - A / K + 1 : (B) / K - (A - 1) / K;
}
0 is divisible by any integer so if A is 0, you should add one to the answer.

This is the O(1) solution, ( There is no check required for the divisility of a)
public static int countDiv(int a, int b, int k) {
double l1 = (double)a / k;
double l = -1 * Math.floor(-1 * l1);
double h1 = (double) b / k;
double h = Math.floor(h1);
Double diff = h-l+1;
return diff.intValue();
}

There is a lot of great answers, but I think this one has some elegance in it, also gives 100% on codility.
public int solution(int a, int b, int k) {
return Math.floorDiv(b, k) - Math.floorDiv(a-1, k);
}
Explanation: Number of integers in the range [1 .. B] that divisible by K is B/K. Range [A .. B] can be transformed to [1 .. B] - [1 .. A) (notice that round bracket after A means that A does not belong to that range). That gives as a result B/K - (A-1)/K. Math.floorDiv is used to divide numbers and skip remaining decimal parts.

I will show my code in go :)
func CountDiv(a int, b int, k int) int {
count := int(math.Floor(float64(b/k)) - math.Floor(float64(a/k)));
if (math.Mod(float64(a), float64(k)) == 0) {
count++
}
return count
}
The total score is 100%

If someone is still interested in this exercise, I share my Python solution (100% in Codility)
def solution(A, B, K):
if not (B-A)%K:
res = int((B-A)/K)
else:
res = int(B/K) - int(A/K)
return res + (not A%K)

int divB = B / K;
int divA = A / K;
if(A % K != 0) {
divA++;
}
return (divB - divA) + 1;
passed 100% in codelity

My 100% score solution with one line code in python:
def solution(A, B, K):
# write your code in Python 3.6
return int(B/K) - int(A/K) + (A%K==0)
pass

int solution(int A, int B, int K)
{
// write your code in C++14 (g++ 6.2.0)
int counter = 0;
if (A == B)
A % K == 0 ? counter++ : 0;
else
{
counter = (B - A) / K;
if (A % K == 0) counter++;
else if (B % K == 0) counter++;
else if ((counter*K + K) > A && (counter*K + K) < B) counter++;
}
return counter;
}

Assumptions:
A and B are integers within the range [0..2,000,000,000];
K is an integer within the range [1..2,000,000,000];
A ≤ B.
int from = A+(K-A%K)%K;
if (from > B) {
return 0;
}
return (B-from)/K + 1;

Related

Calculating the average median of a large array (up to 100,000 elements)

I have a large array that I need to calculate the average median with. I have to use recursion, no loops, and no dot operations except for .length.
The array has to be broken up to 3 pieces at most, and the way to break it up is:
Remainder of 0: Each piece should be [n/3] elements.
Remainder of 1: First and last piece should be [n/3] elements rounded
down, the middle should be [n/3] elements rounded up
Remainder of 2: First and last piece should be [n/3] elements rounded
up, the middle should be [n/3] elements rounded down
I'm getting stumped with how the recursion is supposed to work once the array surpasses the smaller values. This is what I have thus far,
public static double medianAverage(double a, double b, double c) {
if ((a < b && b < c) || (c < b && b < a))
return b;
else if ((b < a && a < c) || (c < a && a < b))
return a;
else if(a == c) return b;
else if(b == c) return a;
else if(a == b) return c;
else
return c;
}
/**
* #return Returns median average
*/
public static double medianHelper(int[] a, int range, int start, int end) {
double avg = 0;
int n = range / 3;
// Base Cases:
if(range == 1) return a[start];
if(range == 2) return (a[start] + a[start + 1]) / 2.0;
if(range == 3) return medianAverage(a[start], a[start + 1], a[start + 2]);
if(range > 3) {
if(range % 3 == 0) {
double p1 = medianHelper(a, n, start, n);
double p2 = medianHelper(a, n, n, n * 2);
double p3 = medianHelper(a, n, n * 2, n * 3);
return medianAverage(p1, p2, p3);
}
if(range % 3 == 1) {
// TODO: Implement
}
if(range % 3 == 2) {
// TODO: Implement
}
}
return avg;
}
public static double median3(int[] a) {
return medianHelper(a, a.length, 0, a.length);
}
Any help at all is appreciated, thank you.
Remainder of 0 means range = 3n. According to the rules, you can divide the array into [0, n], [n + 1, 2n] and [2n + 1, 3n]. Each piece has the size n in this case.
Remainder of 1 means range = 3n + 1. According to the rules, you can divide the array into [0, n], [n + 1, 2n + 1] and [2n + 2, 3n + 1]. The size of first and last piece is n and size of the middle piece is n + 1.
Remainder of 2 means range = 3n + 2. According to the rules, you can divide the array into [0, n + 1], [n + 2, 2n + 1] and [2n + 2, 3n + 2]. The size of first and last piece is n + 1 and the size of the middle piece is n.
Once you divide the array into 3 pieces like this, you can recursively try to find medians of each piece. I'm confused what you want to do with the medians, but I'll let you figure it out.

Comparing integers and creating the smallest integer possible from the digits of the given integers

I need to write the following method: accepts two integer parameters and returns an integer. If either integer is not a 4 digit number than the method should return the smaller integer. Otherwise, the method should return a four digit integer made up of the smallest digit in the thousands place, hundreds place, tens place and ones place. We cannot turn the integers into Strings, or use lists, or arrays.
For example biggestLoser(6712,1234) returns 1212
For example biggestLoser(19,8918) returns 19
Here's how I've started to write it:
public static int biggestLoser(int a, int b){
if(a<9999 || b<9999){
if(a<b)
return a;
else if(b<a)
return b;
}
int at=a/1000;
int ah=a%1000/100;
int an=a%100/10;
int ae=a%10;
int bt=b/1000;
int bh=b%1000/100;
int bn=b%100/10;
int be=a%10;
if(at<bt && ah<bh && an<bn && ae<be)
return at*1000+ah*100+an*10+ae;
else if(at<bt && ah<bh && an<bn && be<ae)
return at*1000+ah*100+an*10+be;
else if(at<bt&& ah<bh && bn<an && ae<be)
else return at*1000+ah*100+bn*10+ae;
However, it looks like I'm going to have to write way too many if statements, is there a shorter way to write the code?
public static int biggestLoser(int a, int b) {
if (a < 1000 || a >= 10000 || b < 1000 || b >= 10000) {
return Math.min(a, b);
} else {
// both a and b are four digits
int result = 0 ;
int multiplier = 1 ;
for (int digit = 0; digit < 4; digit++) {
int nextDigit = Math.min(a % 10, b % 10);
result = result + nextDigit * multiplier ;
multiplier = multiplier * 10 ;
a = a / 10 ;
b = b / 10 ;
}
return result ;
}
}
How does this work? a % 10 is the remainder when a is divided by 10: in other words it is the least significant digit of a (the "ones place").
a = a / 10 performs integer division, so it divides a by 10 and ignores any fraction. So 1234 becomes 123, and on the next iteration 123 becomes 12, etc. In other words, it discards the "ones place".
So the first time through the loop, you look at the "ones" from a and b, find the smallest one, and add it to result. Then you drop the "ones" from both a and b. So what used to be the "tens" are now the "ones". The second time through the loop, you get the smallest "ones" again: but this was originally the smallest "tens". You want to add that to result, but you need to multiply by 10. This is the multiplier: each time through the loop the multiplier is multiplied by 10. So each time, you get the smallest "ones", multiply by the correct thing, add to the result, and then drop the "ones" from a and b.
Just for fun, here's an implementation that needs only one statement (and works if you replace "four digits" with any positive number of digits). You can ask your instructor to explain it ;).
public static final int NUM_DIGITS = 4 ;
public static final int MAX = (int) Math.pow(10, NUM_DIGITS) ;
public static final int MIN = MAX / 10 ;
public static int biggestLoser(int a, int b) {
return (a < MIN || a >= MAX || b < MIN || b >= MAX) ? Math.min(a, b) :
IntStream.iterate(1, multiplier -> multiplier * 10).limit(NUM_DIGITS)
.map(multiplier -> Math.min((a / multiplier) % 10, (b / multiplier) % 10) * multiplier )
.sum();
}
maybe it is stupid but try to take advantage of String ( .charAt(int index) )and Integer ( .parseInt( String value ) ) methods , maybe this example help you :
int x=145;
int y=826;
//to know which number have the biggest tens
String a=x+"";
String b=y+"";
if(Integer.parseInt(a.charAt(1)+"")>Integer.parseInt(b.charAt(1)+""))
{
System.out.println("The number which have the biggest tens is "+a);
}
else
{
System.out.println("The number which have the biggest tens is "+b);
}
Using String and StringBuilder
public class Test
{
public static void main(String []args)
{
System.out.println(biggestLooser(6712,1234));
}
public static int biggestLooser(int _a, int _b)
{
String a = String.valueOf(_a);
String b = String.valueOf(_b);
StringBuilder c = new StringBuilder();
if(a.length() < b.length()) return Integer.parseInt(a);
else if(b.length() < a.length()) return Integer.parseInt(b);
else if(a.length() >= 4 && b.length() >= 4)
{
for(int i = 4; i > 0; i--)
{
char ch = '\0';
if(a.charAt(a.length() - i) < b.charAt(b.length() - i))
ch = a.charAt(a.length() - i);
else ch = b.charAt(b.length() - i);
c.append(ch);
}
return Integer.parseInt(c.toString());
}
else return -1;
}
}
//ouput: 1212
Here is the simple answer
public static int biggestLoser(int a, int b) {
if (a < 1000 || b < 1000) {
if (a < b)
return a;
else
return b;
}
int val = 0;
ArrayList<Integer> data1 = new ArrayList<Integer>();
while (a > 0) {
data1.add(a % 10);
a /= 10;
}
Collections.reverse(data1);
ArrayList<Integer> data2 = new ArrayList<Integer>();
while (b > 0) {
data2.add(b % 10);
b /= 10;
}
Collections.reverse(data2);
val = ((data1.get(0) < data2.get(0)) ? data1.get(0) : data2.get(0))
* 1000
+ ((data1.get(1) < data2.get(1)) ? data1.get(1) : data2.get(1))
* 100
+ ((data1.get(2) < data2.get(2)) ? data1.get(2) : data2.get(2))
* 10
+ ((data1.get(3) < data2.get(3)) ? data1.get(3) : data2.get(3));
return val;
}

Given a number N, find the smallest even number E such that E > N

Given a number N, find the smallest even number E such that E > N and digits in N and E are same.
Print NONE otherwise.
Sample:
Case1
Input
N = 34722641
Output
E = 34724126
Case2
Input
N = 8234961
Output
E = 8236194 (instead of 8236149)
My second case passed first case i am getting wrong output
public static int nextDigit(int number) {
String num = String.valueOf(number);
int stop = 0;
char[] orig_chars = null;
char[] part1 = null;
char[] part2 = null;
orig_chars = num.toCharArray();
for (int i = orig_chars.length - 1; i > 0; i--) {
String previous = orig_chars[i - 1] + "";
String next = orig_chars[i] + "";
if (Integer.parseInt(previous) < Integer.parseInt(next))
{
if (Integer.parseInt(previous) % 2 == 0) {
String partString1 = "";
String partString2 = "";
for (int j = 0; j <= i - 1; j++) {
partString1 = partString1.concat(orig_chars[j] + "");
}
part1 = partString1.toCharArray();
for (int k = i; k < orig_chars.length; k++) {
partString2 = partString2.concat(orig_chars[k] + "");
}
part2 = partString2.toCharArray();
Arrays.sort(part2);
for (int l = 0; l < part2.length; l++) {
char temp = '0';
if (part2[l] > part1[i - 1]) {
temp = part1[i - 1];
part1[i - 1] = part2[l];
part2[l] = temp;
break;
}
}
for (int m = 0; m < part2.length; m++) {
char replace = '0';
if (part2[m] % 2 == 0) {
replace = part2[m];
for (int n = m; n < part2.length - 1; n++) {
part2[n] = part2[n + 1];
}
part2[part2.length - 1] = replace;
break;
}
}
System.out.print(part1);
System.out.println(part2);
System.exit(0);
}
}
}
System.out.println("NONE");
return 0;
}
First idea was to generate the next permutation until an even one is found. This works well for small inputs or when an even permutation is nearby, but badly for large inputs such as 2135791357913579 where many permutations have to happen "to the right" before the sole even digit is moved into place.
גלעד ברקן suggested a patch which with minor adjustment provides a superior algorithm.
As with the next permutation algorithm, we find indices i and j with i < j where the ith digit is less than the jth digit. When we swap those digits, this makes a larger number then N.
Apply the additional constraint that there is an even number to the right of i after the swap.
Take the largest such even number to the right of the index (might not be the one you just swapped), move it to the end. This guarantees evenness.
Then sort the remaining digits in between in ascending order. This provides the smallest permutation available.
The algorithm in Clojure could be written as follows. I tried to stick to a fairly imperative style. See if you can translate.
(defn num->digits [n] (mapv #(Character/getNumericValue %) (str n)))
(defn digits->num [v] (when (seq v) (read-string (apply str v))))
(defn swap
"Swap elements at index i and j in vector v"
[v i j]
(assoc (assoc v i (v j)) j (v i)))
(defn find-max-where
"Find index i in vector v such that (v i) is the largest satisfying pred"
[pred v]
(first
(reduce-kv
(fn [[k m] i x]
(if (and m (> m x))
[k m]
(if (pred x) [i x] [k m])))
[nil nil]
v)))
(defn next-even-perm [v]
(->>
(for [j (range (count v))
i (range j)
:when (< (v i) (v j))
:let [v (swap v i j)
k (find-max-where even? (vec (subvec v (inc i))))]
:when k
:let [v (swap v (+ (inc i) k) (dec (count v)))]]
(concat (subvec v 0 (inc i))
(sort (subvec v (inc i) (dec (count v))))
[(peek v)]))
(map vec) sort first))
(defn next-even-num [n] (-> n num->digits next-even-perm digits->num))
Provided examples:
(next-even-num 34722641)
;=> 34724126
(next-even-num 8234961)
;=> 8236194
(next-even-num 4321)
;=> nil (no solution)
Hard cases for previous algorithm
(time (next-even-num 2135791357913579))
; "Elapsed time: 1.598446 msecs"
;=> 3111335557779992
(time (next-even-num 13244351359135913))
; "Elapsed time: 1.713501 msecs"
;=> 13245111333355994
(time (next-even-num 249999977777555553333311111N))
; "Elapsed time: 1.874579 msecs"
;=> 251111133333555577777999994N
Latest edit fixes problem where we were always wanting to swap with an even number moving right instead of just having any even number to the right whether or not it was involved in the swap. For example, the following failed in the previous edit, now fixed.
(next-even-num 1358)
;=> 1538
Many has suggested permutation, but for this problem, dynamic programming with bit-mask will be another solution.
For dynamic programming, the number of digit can be up to 20 digits, while with normal permutation, it can only be used if N has less than 12 digits. (With time constraint is 1 second , typically for competitive programming)
So the idea is, starting from the most significant digit to the least significant digit, at each step, we try to find the smallest value starting from this digit to the end, at each digit, we have two cases:
If the number being created is already larger than N for example N is 12345 and currently, we are 23xxx. (We need to find the smallest xxx in this case).
If the number is not yet larger than N , example N is 12345 and we have 12xxx.
Moreover, at the last digit, we need to determine if the created number is even or odd.
So, we have our simple recursive code:
public int cal(boolean[] selected, int[] num, int digit, boolean larger) {
//Arrays selected will tell which digit in N has already selected,
//int digit will tell currently, which digit we are checking
//boolean larger tells is the number already larger than N
if (digit + 1 == selected.length) {//Last digit
for (int i = 0; i < selected.length; i++) {
if (!selected[i]) {
if (num[i] % 2 != 0) {
return -1; // -1 means this is an invalid value
} else {
if (larger) {
return num[i];
} else {
return -1;
}
}
}
}
}
int result = -1;
for (int i = 0; i < selected.length; i++) {
if (!selected[i]) {
if (larger) {
selected[i] = true;
int val = (int) (num[i] * Math.pow(10, digit) + cal(selected, num, digit + 1, larger));
if (val != -1 && (result == -1 || result > val)) {
result = val;
}
} else if (num[i] >= num[digit]) {
int val = (int) (num[i] * Math.pow(10, digit) + cal(selected, num, digit + 1, num[i] > num[digit]));
if (val != -1 && (result == -1 || result > val)) {
result = val;
}
}
}
}
return result;
}
From this state, we notice that actually, the boolean [] selected can be replaced by a bit-mask value (Read about bitmask here Link) , So we can easily represent the state of this recursive by this array int [mask][larger] dp
Notice that the parameter digit is not necessary as we can easily determine the digit we are checking by counting the number of digit left to be selected.
Finally, we have our solution:
import java.util.Arrays;
/**
*
* #author Trung Pham
*/
public class Test {
public static void main(String[] args) {
Test test = new Test();
System.out.println(test.largest(2135791357913579L));
}
long[][] dp;
public long largest(long N) {
String val = "" + N;
int[] num = new int[val.length()];
for (int i = 0; i < num.length; i++) {
num[i] = val.charAt(i) - '0';
// System.out.println(num[i] + " " + i);
}
dp = new long[1 << num.length][2];
for (long[] a : dp) {
Arrays.fill(a, -2);
}
return cal(0, num, 0);
}
public long cal(int mask, int[] num, int larger) {
//Arrays selected will tell which digit in N has already selected,
//int digit will tell currently, which digit we are checking
//int larger tells is the number already larger than N, if it is 1, it is larger, 0 is not.
int digit = 0;
for (int i = 0; i < num.length; i++) {
if (((1 << i) & mask) != 0) {
digit++;
}
}
if (dp[mask][larger] != -2) {
return dp[mask][larger];
}
if (digit + 1 == num.length) {//Last digit
//System.out.println(mask + " " + digit);
for (int i = 0; i < num.length; i++) {
if (((1 << i) & mask) == 0) {
if (num[i] % 2 != 0) {
return -1; // -1 means this is an invalid value
} else {
if (larger == 1) {
// System.out.println(num[i] + " " + i);
return num[i];
} else {
return -1;
}
}
}
}
return -1;
}
long result = -1;
int l = num.length;
for (int i = 0; i < num.length; i++) {
if (((1 << i) & mask) == 0) {
if (larger == 1) {
//System.out.println(num[i]* Math.pow(10,l - digit) + " " + digit);
long val = (long) (cal(mask | (1 << i), num, larger));
if (val != -1) {
val += num[i] * Math.pow(10, l - digit - 1);
if (result == -1 || result > val) {
result = val;
}
}
} else if (num[i] >= num[digit]) {
long val = (long) (cal(mask | (1 << i), num, num[i] > num[digit] ? 1 : 0));
if (val != -1) {
val += num[i] * Math.pow(10, l - digit - 1);
if (result == -1 || result > val) {
result = val;
}
}
}
}
}
return dp[mask][larger] = result;
}
}
Notice that this solution can still be improved if you notice that at each digit, we only selected value from 0 to 9 once, and the start digit cannot start with 0.
An attempt at a Haskell version of the newer algorithm in A. Webb's answer:
import qualified Data.Map as M
import Data.Ord (comparing)
import Data.List (sort,maximumBy)
import Data.Maybe (fromJust)
digs :: Integral x => x -> [x]
digs 0 = []
digs x = digs (x `div` 10) ++ [x `mod` 10]
nextE n
| e == -1 = "NONE"
| otherwise = concatMap show $ take (ie' + 1) (M.elems s)
++ sort (drop (ie' + 1) (M.elems s')) ++ [r]
where ds = M.fromList (zip [0..] (digs n))
rightMost (-1) _ = [(-1,0),(-1,0)]
rightMost ix xs
| even (x) && not (null $ filter (>x) xs) = [(x,ix),(y,iy)]
| otherwise = rightMost (ix - 1) (x:xs)
where x = fromJust (M.lookup ix ds)
(y,iy) = minimum . filter ((>= x) . fst)
$ zip xs [ix + 1..M.size ds - 1]
[(e,ie),(l,il)] = rightMost (M.size ds - 1) []
s = M.insert il e . M.insert ie l $ ds
(ir,r) = maximumBy (comparing snd) . M.toList
. M.filter even . snd $ M.split ie s
s' = M.delete ir s
ie' = fromIntegral ie
main = print (map (\x -> (x,nextE x)) [34722641,8234961,13244351359135913,3579])
Output:
*Main> main
[(34722641,"34724126"),(8234961,"8236194")
,(13244351359135913,"13245111333355994"),(3579,"NONE")]
(0.02 secs, 563244 bytes)
Cases where result will be "NONE":
Find the minimum even digit(0, 2, 4, 6, 8) from the given number. Let the digit is x.
Take the other digits, sort them in decreasing order. Let's assume this substring is S.
E = S + x (Here + means concatenation)
If no even digit is found in step 1, There is no such number.
If E, after step 2 is <= N, then there is no such number.
As there are only 5 possible digits those can be placed as the last digit of E, first we consider each of them. Let the current even digit be e. We'll scan N to find if e occurs in N.
If e doesn't occur in N, skip. Otherwise, we remove 1 occurrence of e from N and add it to the end of E. Let's assume the rest digits concatenate to E1.
If e > N % 10, then we need to find the permutation of E1 such that E1 >= N/10 and E1 is minimum. If e <= N %10 then we need a permutation of E1 such that E1 > N/10 and E1 is minimum of every such permutation. So the problem reduces to find a permutation of a number E1, that is greater than or equal to E1 (based on the value of e) and minimum.
You can take it from here and solve this problem as it only needs some careful coding from here to solve the next part of the problem.

Can I make this function more efficient (Project Euler Number 9)?

I just finished Project Euler problem 9 (warning spoilers):
A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,
a^2 + b^2 = c^2
For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2.
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.
Here's my solution:
public static int specPyth(int num)
{
for (int a = 1; a < num; a++)
for (int b = 2; b < a; b++)
{
if (a*a +b*b == (num-a-b)*(num-a-b))
return a*b*(num-a-b); //ans = 31875000
}
return -1;
}
I can't help but think that there's a solution that involves only one loop. Anyone have ideas? I'd prefer answers using only one loop, but anything that's more efficient than what I currently have would be nice.
if a + b +c = 1000
then
a + b + sqroot(a² + b²) = 1000
-> (a² + b²) = (1000 - a - b)²
-> a² + b² = 1000000 - 2000*(a+b) + a² + 2*a*b + b²
-> 0 = 1000000 - 2000*(a+b) + 2*a*b
-> ... (easy basic maths)
-> a = (500000 - 1000*b) / (1000 - b)
Then you try every b until you find one that makes a natural number out of a.
public static int specPyth(int num)
{
double a;
for (int b = 1; b < num/2; b++)
{
a=(num*num/2 - num*b)/(num - b);
if (a%1 == 0)
return (int) (a*b*(num-a-b));
}
return -1;
}
EDIT: b can't be higher than 499, because c>b and (b+c) would then be higher than 1000.
I highly recommend reading http://en.wikipedia.org/wiki/Pythagorean_triple#Generating_a_triple and writing a function that will generate the Pythagorean triples one by one.
Not to give too much of a spoiler, but there are a number of other PE problems that this function will come in handy for.
(I don't consider this giving away too much, because part of the purpose of PE is to encourage people to learn about things like this.)
First, since a is the smallest, you need not to count it up to num, num/3 is sufficient, and even num/(2+sqrt(2)).
Second, having a and constraints
a+b+c=num
a^2+b^2=c^2
we can solve this equations and find b and c for given a, which already satisfy this equations and there is no need to check if a^2+b^2=c^2 as you do now. All you need is to check if b and c are integer. And this is done in one loop
for (int a = 1; a < num/3; a++)
Runs in 62 milli seconds
import time
s = time.time()
tag,n=True,1000
for a in xrange (1,n/2):
if tag==False:
break
for b in xrange (1,n/2):
if a*a + b*b - (n-a-b)*(n-a-b) ==0:
print a,b,n-a-b
print a*b*(n-a-b)
tag=False
print time.time() - s
C solution
Warning : solution assumes that GCD(a, b) = 1. It works here but may not always work. I'll fix the solution in some time.
#include <stdio.h>
#include <math.h>
int main(void)
{
int n = 1000; // a + b + c = n
n /= 2;
for(int r = (int) sqrt(n / 2); r <= (int) sqrt(n); r++)
{
if(n % r == 0)
{
int s = (n / r) - r;
printf("%d %d %d\n", r*r - s*s, 2*r*s, r*r + s*s);
printf("Product is %d\n", (2*r*s) * (r*r - s*s) * (r*r + s*s));
}
}
return 0;
}
Solution uses Euclid's formula for triplets which states that any primitive triple is of form a = r^2 - s^2, b = 2rs, c = r^2 + s^2.
Certain restrictions like sqrt(n / 2) <= r <= sqrt(n) can be added based on the fact that s is positive and r > s.
Warning: you may need long long if the product is large
Definitely not the most optimal solution, but my first instinct was to use a modified 3SUM. In Python,
def problem_9(max_value = 1000):
i = 0
range_of_values = [n for n in range(1, max_value + 1)]
while i < max_value - 3:
j = i + 1
k = max_value - 1
while j < k:
a = range_of_values[i]
b = range_of_values[j]
c = range_of_values[k]
if ((a + b + c) == 1000) and (a*a + b*b == c*c):
return a*b*c
elif (a + b + c) < 1000:
j += 1
else:
k -= 1
i += 1
return -1
You say a < b < c, then b must always be bigger than a, so your starting point in the second loop could be b = a + 1; that would lead certainly to fewer iterations.
int specPyth(int num)
{
for (int a = 1; a < num/3; a++)
for (int b = a + 1; b < num/2; b++)
{
int c = num - a - b;
if (a * a + b * b == c * c)
return a * b * c; //ans = 31875000
}
return -1;
}
In the first given equation, you have three variables a, b, c. If you want to find-out matching values for this equation, you have to run 3 dimension loop. Fortunately there is another equation a+b+c=N where N is known number.
Using this, you can reduce down the dimension to two because if you know two among the three, you can calculate the rest. For instance, if you know a and b, c equals N - a - b.
What if you can reduce one more dimension of the loop? It is possible if you fiddle with the two given equations. Get a pen and paper. Once you get the additional equation with two variables and one constant (N), you will be able to acquire the result in O(n). Solve the two equations a+b+c=n; a^2+b^2=c^2 taking n and a to be constant and solve for b and c:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
for(int a0 = 0; a0 < t; a0++){
int n = in.nextInt();
int max=-1;
int multi=0;
int b=1,c=1;
for(int i=1;i<=n;i++)
{
if(2*(i-n)!=0)
b=(2*i*n-(n*n))/(2*(i-n));
c=n-b-i;
if( (i*i+b*b==c*c)&& i+b+c==n && b>0 && c>=0 && i+b>c && c+i>b && b+c>i)
{
multi=i*b*c;
if(max<multi)
max=multi;
}
}
if(max==-1)
System.out.println(-1);
else
System.out.println(max);
}
}
Python:
Before jump into the code, do a small exercise in algebra.
a^2 + b^2 = c ^2
a + b + c = 1000 --> c = 1000 - (a+b)
a^2 + b^2 = (1000 - (a+b))^2
a = 1000*(500-b)/(1000-b)
Now the time to write the code.
for b in range(2, 500):
a = 1000*(500 - b)/(1000 - b)
if a.is_integer():
c = 1000 - (a+b)
print(a, b, c, a*b*c)
break

Calculating powers of integers

Is there any other way in Java to calculate a power of an integer?
I use Math.pow(a, b) now, but it returns a double, and that is usually a lot of work, and looks less clean when you just want to use ints (a power will then also always result in an int).
Is there something as simple as a**b like in Python?
When it's power of 2. Take in mind, that you can use simple and fast shift expression 1 << exponent
example:
22 = 1 << 2 = (int) Math.pow(2, 2)
210 = 1 << 10 = (int) Math.pow(2, 10)
For larger exponents (over 31) use long instead
232 = 1L << 32 = (long) Math.pow(2, 32)
btw. in Kotlin you have shl instead of << so
(java) 1L << 32 = 1L shl 32 (kotlin)
Integers are only 32 bits. This means that its max value is 2^31 -1. As you see, for very small numbers, you quickly have a result which can't be represented by an integer anymore. That's why Math.pow uses double.
If you want arbitrary integer precision, use BigInteger.pow. But it's of course less efficient.
Best the algorithm is based on the recursive power definition of a^b.
long pow (long a, int b)
{
if ( b == 0) return 1;
if ( b == 1) return a;
if (isEven( b )) return pow ( a * a, b/2); //even a=(a^2)^b/2
else return a * pow ( a * a, b/2); //odd a=a*(a^2)^b/2
}
Running time of the operation is O(logb).
Reference:More information
No, there is not something as short as a**b
Here is a simple loop, if you want to avoid doubles:
long result = 1;
for (int i = 1; i <= b; i++) {
result *= a;
}
If you want to use pow and convert the result in to integer, cast the result as follows:
int result = (int)Math.pow(a, b);
Google Guava has math utilities for integers.
IntMath
import java.util.*;
public class Power {
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
int num = 0;
int pow = 0;
int power = 0;
System.out.print("Enter number: ");
num = sc.nextInt();
System.out.print("Enter power: ");
pow = sc.nextInt();
System.out.print(power(num,pow));
}
public static int power(int a, int b)
{
int power = 1;
for(int c = 0; c < b; c++)
power *= a;
return power;
}
}
Guava's math libraries offer two methods that are useful when calculating exact integer powers:
pow(int b, int k) calculates b to the kth the power, and wraps on overflow
checkedPow(int b, int k) is identical except that it throws ArithmeticException on overflow
Personally checkedPow() meets most of my needs for integer exponentiation and is cleaner and safter than using the double versions and rounding, etc. In almost all the places I want a power function, overflow is an error (or impossible, but I want to be told if the impossible ever becomes possible).
If you want get a long result, you can just use the corresponding LongMath methods and pass int arguments.
Well you can simply use Math.pow(a,b) as you have used earlier and just convert its value by using (int) before it. Below could be used as an example to it.
int x = (int) Math.pow(a,b);
where a and b could be double or int values as you want.
This will simply convert its output to an integer value as you required.
A simple (no checks for overflow or for validity of arguments) implementation for the repeated-squaring algorithm for computing the power:
/** Compute a**p, assume result fits in a 32-bit signed integer */
int pow(int a, int p)
{
int res = 1;
int i1 = 31 - Integer.numberOfLeadingZeros(p); // highest bit index
for (int i = i1; i >= 0; --i) {
res *= res;
if ((p & (1<<i)) > 0)
res *= a;
}
return res;
}
The time complexity is logarithmic to exponent p (i.e. linear to the number of bits required to represent p).
I managed to modify(boundaries, even check, negative nums check) Qx__ answer. Use at your own risk. 0^-1, 0^-2 etc.. returns 0.
private static int pow(int x, int n) {
if (n == 0)
return 1;
if (n == 1)
return x;
if (n < 0) { // always 1^xx = 1 && 2^-1 (=0.5 --> ~ 1 )
if (x == 1 || (x == 2 && n == -1))
return 1;
else
return 0;
}
if ((n & 1) == 0) { //is even
long num = pow(x * x, n / 2);
if (num > Integer.MAX_VALUE) //check bounds
return Integer.MAX_VALUE;
return (int) num;
} else {
long num = x * pow(x * x, n / 2);
if (num > Integer.MAX_VALUE) //check bounds
return Integer.MAX_VALUE;
return (int) num;
}
}
base is the number that you want to power up, n is the power, we return 1 if n is 0, and we return the base if the n is 1, if the conditions are not met, we use the formula base*(powerN(base,n-1)) eg: 2 raised to to using this formula is : 2(base)*2(powerN(base,n-1)).
public int power(int base, int n){
return n == 0 ? 1 : (n == 1 ? base : base*(power(base,n-1)));
}
There some issues with pow method:
We can replace (y & 1) == 0; with y % 2 == 0
bitwise operations always are faster.
Your code always decrements y and performs extra multiplication, including the cases when y is even. It's better to put this part into else clause.
public static long pow(long x, int y) {
long result = 1;
while (y > 0) {
if ((y & 1) == 0) {
x *= x;
y >>>= 1;
} else {
result *= x;
y--;
}
}
return result;
}
Use the below logic to calculate the n power of a.
Normally if we want to calculate n power of a. We will multiply 'a' by n number of times.Time complexity of this approach will be O(n)
Split the power n by 2, calculate Exponentattion = multiply 'a' till n/2 only. Double the value. Now the Time Complexity is reduced to O(n/2).
public int calculatePower1(int a, int b) {
if (b == 0) {
return 1;
}
int val = (b % 2 == 0) ? (b / 2) : (b - 1) / 2;
int temp = 1;
for (int i = 1; i <= val; i++) {
temp *= a;
}
if (b % 2 == 0) {
return temp * temp;
} else {
return a * temp * temp;
}
}
Apache has ArithmeticUtils.pow(int k, int e).
import java.util.Scanner;
class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
for (int i = 0; i < t; i++) {
try {
long x = sc.nextLong();
System.out.println(x + " can be fitted in:");
if (x >= -128 && x <= 127) {
System.out.println("* byte");
}
if (x >= -32768 && x <= 32767) {
//Complete the code
System.out.println("* short");
System.out.println("* int");
System.out.println("* long");
} else if (x >= -Math.pow(2, 31) && x <= Math.pow(2, 31) - 1) {
System.out.println("* int");
System.out.println("* long");
} else {
System.out.println("* long");
}
} catch (Exception e) {
System.out.println(sc.next() + " can't be fitted anywhere.");
}
}
}
}
int arguments are acceptable when there is a double paramter. So Math.pow(a,b) will work for int arguments. It returns double you just need to cast to int.
int i = (int) Math.pow(3,10);
Without using pow function and +ve and -ve pow values.
public class PowFunction {
public static void main(String[] args) {
int x = 5;
int y = -3;
System.out.println( x + " raised to the power of " + y + " is " + Math.pow(x,y));
float temp =1;
if(y>0){
for(;y>0;y--){
temp = temp*x;
}
} else {
for(;y<0;y++){
temp = temp*x;
}
temp = 1/temp;
}
System.out.println("power value without using pow method. :: "+temp);
}
}
Unlike Python (where powers can be calculated by a**b) , JAVA has no such shortcut way of accomplishing the result of the power of two numbers.
Java has function named pow in the Math class, which returns a Double value
double pow(double base, double exponent)
But you can also calculate powers of integer using the same function. In the following program I did the same and finally I am converting the result into an integer (typecasting). Follow the example:
import java.util.*;
import java.lang.*; // CONTAINS THE Math library
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n= sc.nextInt(); // Accept integer n
int m = sc.nextInt(); // Accept integer m
int ans = (int) Math.pow(n,m); // Calculates n ^ m
System.out.println(ans); // prints answers
}
}
Alternatively,
The java.math.BigInteger.pow(int exponent) returns a BigInteger whose value is (this^exponent). The exponent is an integer rather than a BigInteger. Example:
import java.math.*;
public class BigIntegerDemo {
public static void main(String[] args) {
BigInteger bi1, bi2; // create 2 BigInteger objects
int exponent = 2; // create and assign value to exponent
// assign value to bi1
bi1 = new BigInteger("6");
// perform pow operation on bi1 using exponent
bi2 = bi1.pow(exponent);
String str = "Result is " + bi1 + "^" +exponent+ " = " +bi2;
// print bi2 value
System.out.println( str );
}
}

Categories