Codechef Q - Why am I getting a "Wrong Answer" error - c++

Question - A Little Elephant from the Zoo of Lviv likes lucky numbers very much. Everybody knows that the lucky numbers are positive integers whose decimal representation contains only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are not.
Let F4(X) be the number of digits 4 in the decimal representation of X, and F7(X) be the number of digits 7 in the decimal representation of X. For example, F4(456) = 1, F4(444) = 3, F7(1) = 0, F7(747) = 2. The Little Elephant wants to know the largest product F4(X) ∙ F7(X), where L ≤ X ≤ R. In other words he wants to know the value
max{F4(X) ∙ F7(X) : L ≤ X ≤ R}.
1 <= L <= R <= 1018
Example:
1) For the range, 1 100 answer will be 1 {47,74}
2) 4199 6000 answer will be 4 {4747, 4477}
I feel my code is correct, but on submitting it's getting the verdict Wrong Answer. Can anybody help me find out exactly what is going wrong?
My algorithm cannot be wrong (it's very straightforward). I've double checked the implementation (it handles all possible cases). It's difficult to believe that it's going wrong for some input.
Here's the C++ code:
#include <cstdio>
#include <cstring>
using namespace std;
char buf1[20],buf2[20];
int *L, *R, *ans, len, ansn;
bool flagL, flagR;
inline int count(int n)
{
int a=0,c=0;
for(;a<len;a++) if(ans[a] == n) c++;
return c;
}
inline int max(int a, int b) { return a>b ? a:b; }
inline int min(int a, int b) { return a<b ? a:b; }
inline void f(int i, int n)
{
int a=0,n4=0,n7=0,t;
for(;a<=i;a++) if(ans[a] == 4) n4++; else if(ans[a] == 7) n7++;
while(n)
{
if(n4 == n7)
{
n4 += n/2;
n7 += (n-n/2);
break;
}
else if(n4 > n7)
{
t = min(n,n4-n7);
n -= t;
n7 += t;
}
else if(n7 > n4)
{
t = min(n,n7-n4);
n -= t;
n4 += t;
}
}
ansn = max(ansn,n4*n7);
}
void solve(int i, bool flagL, bool flagR)
{
while(i<len)
{
if(flagL && !flagR)
{
if(4 > L[i])
{
f(i-1,len-i);
return;
}
if(4 == L[i])
{
ans[i] = 4;
solve(i+1, 1, 0);
ans[i] = 7;
f(i,len-i-1);
return;
}
if(7 > L[i])
{
ans[i] = 7;
f(i,len-i-1);
return;
}
if(7 == L[i])
{
ans[i] = 8;
f(i,len-i-1);
ans[i] = 7;
i++;
continue;
}
// else
ans[i] = 9;
if(ans[i] > L[i])
{
f(i,len-i-1);
return;
}
else
{
i++;
continue;
}
}
if(!flagL && flagR)
{
if(7 < R[i])
{
f(i-1,len-i);
return;
}
if(7 == R[i])
{
ans[i] = 4;
f(i,len-i-1);
ans[i] = 7;
i++;
continue;
}
if(4 < R[i])
{
ans[i] = 4;
f(i,len-i-1);
return;
}
if(4 == R[i])
{
ans[i] = 3;
f(i,len-i-1);
ans[i] = 4;
i++;
continue;
}
// else
ans[i] = 0;
if(ans[i] < R[i])
{
f(i,len-i-1);
return;
}
else
{
i++;
continue;
}
}
if(flagL && flagR)
{
if(R[i] - L[i] == 1)
{
ans[i] = L[i];
solve(i+1,1,0);
ans[i]++;
solve(i+1,0,1);
return;
}
bool four = 4 > L[i] && 4 < R[i];
bool sev = 7 > L[i] && 7 < R[i];
if (four && sev)
{
f(i-1,len-i);
return;
}
else if (four && !sev)
{
ans[i] = 4;
f(i,len-i-1);
}
else if (!four && sev)
{
ans[i] = 7;
f(i,len-i-1);
}
if (L[i] == 4 || L[i] == 7 || R[i] == 4 || R[i] == 7)
{
if(L[i] == R[i]) { ans[i] = L[i]; i++; continue; }
if(L[i] == 4 && R[i] == 7)
{
ans[i] = 4;
solve(i+1,1,0);
ans[i] = 7;
solve(i+1,0,1);
ans[i] = 5;
f(i,len-i-1);
return;
}
if(R[i] - L[i] >= 2)
{
ans[i] = L[i]+1;
f(i,len-i-1);
if(L[i] == 4 || L[i] == 7)
{
ans[i] = L[i];
solve(i+1,1,0);
}
if(R[i] == 4 || R[i] == 7)
{
ans[i] = R[i];
solve(i+1,0,1);
}
return;
}
}
else
{
if (R[i] - L[i] >= 2)
{
ans[i] = L[i]+1;
f(i,len-i-1);
return;
}
ans[i] = L[i];
}
}
i++;
} // end of while
ansn = max(ansn, count(4)*count(7));
}
int main()
{
int a,t; scanf("%d\n",&t);
while(t--) // test cases
{
scanf("%s %s",&buf1,&buf2);
len = strlen(buf2);
L = new int[len];
R = new int[len];
ans = new int[len];
for(a=0;a<len;a++) R[a] = buf2[a]-48;
for(a=0;a<len-strlen(buf1);a++) L[a] = 0;
int b=a;
for(;a<len;a++) L[a] = buf1[a-b]-48;
flagL = flagR = 1; ansn = 0;
solve(0,1,1);
printf("%d\n",ansn);
}
return 0;
}
The algorithm:
Firstly, put the digits of L,R in arrays L[],R[] of length = no. of digits in R. And initialize an array ans[] for keeping track of the answer integer (integer for which F4(ans)*F7(ans) is maximum).
Pad L by 0 on the left, to make it equal to R in length. (so 1,100 becomes 001,100)
This is done in main() itself, before making a call to solve()
The real logic:
Run a loop, for i in range(0,len(R))
For each i, compare L[i] and R[i]
Variables flagL and flagR tell you whether or not, you need to check L and R respectively.
Supposing the L[], R[] is initially:
238 967
First we need to check both of them starting from 0th index (hence solve(0,1,1) or solve(0,true,true) ).
Now 4 and 7 both fall between L[0] and R[0]. So any permutation of {4,7} can be put in the 3 digits, without ans[] going out of range [L,R]. So answer will be 2.
If the range would have been:
238 and 545
Only 4 would fall in between 2 and 5, so we shall put 4 in ans[0], and any permutation of {4,7} can be put in the remaining places. So answer is again 2.
What if the range is:
238 and 410
Neither 4 nor 7 fall in between L[0] and R[0].
But note that R[0] is 4.
So we shall now have 2 choices to put, 4 and L[0]+1 (this is where recursion comes in)
Why L[0]+1 ? Because if we put L[0]+1 in ans[0], ans[0] would fall in between L[0] and R[0] (for this R[0] - L[0] >= 2) and whatever we put in the remaining digits, ans[] would never go out of range. But we also have to check with ans[0] being 4. In the last example, it won't help, but it would if R was >= 477.
So the answer would be 1. (2 if R was >= 477)
Let's discuss another example:
Range: 4500 5700
Because R[0] and L[0] differ by only 1, we will have to check for both, once for ans[i] = L[i], then ans[i] = R[i] (or ans[i]++ )
Now if we check for ans[i] = 4, we won't have to compare ans[i] and R[i] anymore, since ans[0] < R[0], hence ans will always be < R. So we call solve() recursively like this: solve(i+1, true, false)
Next time, when ans[0] = R[0], then we won't have to compare ans with L (since ans > L, whatever we put in the remaining 2 places). Then we call solve() like this: solve(i+1, false, true).
You get the idea of how it's working, and also, if you look at my code, no possible test case is being left out. I don't know why I'm getting a WA.
PS: Andrew pointed out the mistake. The order of conditions was wrong. The if block 4 == L[i] should have come before the if block 7 > L[i]. Now the code works correctly.

if(7 > L[i]) // 7 > 4 ?
{
ans[i] = 7;
f(i,len-i-1);
return;
}
if(4 == L[i]) // how is this ever reachable?
{
ans[i] = 4;
solve(i+1, 1, 0);
ans[i] = 7;
f(i,len-i-1);
return;
}
I think you mean:
- if(7 > L[i])
+ if(7 < L[i])

Related

Triangle: Determine if an array includes a triangular triplet (Codility)

This is the Triangle problem from Codility:
A zero-indexed array A consisting of N integers is given.
A triplet (P, Q, R) is triangular if 0 ≤ P < Q < R < N and:
A[P] + A[Q] > A[R],
A[Q] + A[R] > A[P],
A[R] + A[P] > A[Q].
Write a function:
int solution(vector<int> &A);
that, given a zero-indexed array A consisting of N integers, returns 1
if there exists a triangular triplet for this array and returns 0
otherwise.
For example, given array A such that:
A[0] = 10, A[1] = 2, A[2] = 5, A[3] = 1, A[4] = 8, A[5] = 20
Triplet (0, 2, 4) is triangular, the function should return 1.
Given array A such that:
A[0] = 10, A[1] = 50, A[2] = 5, A[3] = 1
function should return 0.
Assume that:
N is an integer within the range [0..100,000];
each element of array A is an integer within the range
[−2,147,483,648..2,147,483,647].
And here is my solution in C++:
int solution(vector<int> &A) {
if(A.size()<3) return 0;
sort(A.begin(), A.end());
for(int i=0; i<A.size()-2; i++){
//if(A[i] = A[i+1] = A[i+2]) return 1;
if(A[i]+A[i+1]>A[i+2] && A[i+1]+A[i+2]>A[i] && A[i+2]+A[i]>A[i+1]){
return 1;
}
}
return 0;
}
I've checked the comments there and all the solutions seems similar to mine.
However, while others claimed to have gotten 100%, I only got a 93% score.
I got all the tests cases correct EXCEPT for one:
extreme_arith_overflow1
overflow test, 3 MAXINTs
I assume this case has some input like this:
[2147483647, 2147483647, 2147483647]
So I add this to the custom test case, and the answer turns out to be 0 when it clearly should be 1.
I also tried [1900000000, 1900000000, 1900000000], and the answer is still 0.
However, [1000000000, 1000000000, 1000000000] is correct with answer of 1.
Can anyone clue me in on why this result occured?
Greatly appreciated.
My solution in Java with 100/100 and time complexity of O(N*log(N))
With comments explaining the logic
// you can also use imports, for example:
// import java.util.*;
// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
import java.util.Arrays;
class Solution {
public int solution(int[] A) {
int N = A.length;
if (N < 3) return 0;
Arrays.sort(A);
for (int i = 0; i < N - 2; i++) {
/**
* Since the array is sorted A[i + 2] is always greater or equal to previous values
* So A[i + 2] + A[i] > A[i + 1] ALWAYS
* As well ass A[i + 2] + A[i + 1] > A[i] ALWAYS
* Therefore no need to check those. We only need to check if A[i] + A[i + 1] > A[i + 2]?
* Since in case of A[i] + A[i + 1] > MAXINT the code would strike an overflow (ie the result will be greater than allowed integer limit)
* We'll modify the formula to an equivalent A[i] > A[i + 2] - A[i + 1]
* And inspect it there
*/
if (A[i] >= 0 && A[i] > A[i + 2] - A[i + 1]) {
return 1;
}
}
return 0;
}
Basically when you check X + Y value of integers, that is greater than integer limit the code will fail on overflow. so instead of checking if X + Y > Z, we can simply check the equivalent statement if X > Z - Y (simple math isn't it?). Alternatively you could always use long but it will be a worse solution memory wise.
Also make sure you skip the negatives as a triangle cannot have a negative side value.
Cheers
Java 100 %:
public int solution(int[] A){
Arrays.sort(A);
for(int i=0;i<A.length-2;i++){
if(
((long)A[i] + (long)A[i+1] > A[i+2]) &&
((long)A[i+1] + (long)A[i+2] > A[i]) &&
((long)A[i] + (long)A[i+2] > A[i+1])
)
return 1;
}
return 0;
}
Here's my clean solution in Python. I got a 100% in Codility.
This logic can be adapted to any other programming language.
Note: If the array is sorted, you only have to check that the sum of two consecutive elements is greater than the next element (A[i] + A[i+1] > A[i+2]), because in that case, the other two conditions (A[i+1]+A[i+2] > A[i], A[i]+A[i+2] > A[i+1]) will always be true.
I hope it helps.
def solution(A):
#edge case check
if len(A) < 3:
return 0
A.sort()
for i in range(len(A)-2):
if A[i]+A[i+1] > A[i+2]:
return 1
return 0
There are couple of issues here
Side of a triangle can't be 0, since it is a length. You have to add that check or you'll fail that corner case. i.e. Wouldn't get 100%.
Since you can have an input array of all INT_MAX or LONG_MAX (see http://www.cplusplus.com/reference/climits/), you need to store the sum in a double or long long.
You don't have to check all three conditions here i.e.
A[P] + A[Q] > A[R],
A[Q] + A[R] > A[P],
A[R] + A[P] > A[Q].
If you have sorted the array than
A[Q] + A[R] > A[P] &&
A[R] + A[P] > A[Q]
are always true because 0 ≤ P < Q < R i.e. R is greater than P and Q.
So you should only check for A[P] + A[Q] > A[R].
You have already placed a check for A.size() < 3 so that is good.
I have added a C implementation at https://github.com/naveedrasheed/Codility-Solutions/blob/master/Lesson6_Sorting/triangle.c.
You can compare it with solution.
I have used 3 for loop here( without sorting the array) to solve this problem.
public static int solution(int[] A) {
for (int p = 0; p < A.length; p++) {
for (int q = p + 1; q < A.length; q++) {
for (int r = q + 1; r < A.length; r++) {
if ((A[p] + A[q] > A[r]) && (A[q] + A[r] > A[p]) && (A[r] + A[p] > A[q])) {
System.out.println(A[p] + " " + A[q] + " " + A[r]);
return 1;
}
}
}
}
return 0;
}
the trick is to find a number on the array that is less the sum of the other two on the array so sorting the array then searching for that number will solve it. casting to long that on sometimes the value of summation wil exceed the allowed integer
public int solution(int[] A) {
int n = A.length;
if(n<3){
return 0;
}
Arrays.sort(A);
for(int i=2; i<n; i++){
if(A[i]<(long)A[i-1]+(long)A[i-2])
return 1;
}
return 0;
}
My solution in C# with 100 score.
using System;
class Solution {
public int solution(int[] A) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
if(A.Length) <3)
return 0;
Array.Sort(A);
int p,q,r;
for(int i=A.Length-1;i>1; i--){
p = A[i];
q = A[i-1];
r = A[i-2];
if(p+q>r && q+r > p && r+p > q)
return 1;
}
return 0;
}
}
Straightforward solution in JavaScript.
Note: I excluded the options where any side could be 0 or less. The rest is the same.
function solution(A) {
if (A.length < 3) return 0;
A.sort((a, b) => (a - b));
for (i = A.length - 1; i >= 0; i--) {
if (A[i - 2] <= 0) return 0;
if (
A[i] + A[i - 1] > A[i - 2] &&
A[i] + A[i - 2] > A[i - 1] &&
A[i - 1] + A[i - 2] > A[i]
) return 1;
}
return 0;
}
javascript 100% on codility
function solution(a) {
if (a.length < 3) {
return 0;
}
a.sort((a, b) => a - b);
for (let i = 0; i < a.length - 2; i++) {
if (a[i] + a[i + 1] > a[i + 2]) {
return 1;
}
}
return 0;
}
My solution to this problem, written in Swift.
public func Triangle(_ A : inout [Int]) -> Int {
A.sort()
for i in 1..<A.count-1 {
if(A[i] + A[i-1] > A[i+1]) {
print("Triangle has edges: \(A[i-1]), \(A[i]), \(A[i+1])")
return 1
}
}
return 0
}
A = [10,2,5,1,8,20]
print("Triangle: ", Triangle(&A))
Or you can change the if clause, like below
if(A[i]>A[i+2]-A[i+1] && A[i+1]>A[i]-A[i+2] && A[i+2]>A[i+1]-A[i])
using subtraction instead of addition.
Works 100%, tested with different scenario's.
I think all the possibilities are not covered above solution
Combination with
P,Q,R
A[0] = 10, A[1] = 2, A[2] = 5, A[3] = 1, A[4] = 8, A[5] = 20
index combination
0+1>2, 1+2>0, 2+0>1
1+2>3, 2+3>1, 3+1>2
....
These are combinations needed to achieve this problem.
//Triangle
/**
* A[P] + A[Q] > A[R],
A[Q] + A[R] > A[P],
A[R] + A[P] > A[Q]
*/
public int triangleSolution(int[] A) {
int status = 0;
for(int i=0; i<A.length; i++) {
int[] B = removeTheElement(A, i);
for(int j=0; j<B.length; j++) {
int[] C = removeTheElement(B, j);
for(int k=0; k<C.length; k++) {
if((A[i] + B[j] > C[k]) &&
(B[j] + C[k] > A[i]) &&
(C[k] + A[i] > B[j])) {
return 1;
}
}
}
}
return status;
}
// Function to remove the element
public int[] removeTheElement(int[] arr, int index)
{
// Create another array of size one less
int[] anotherArray = new int[arr.length - 1];
// Copy the elements except the index
// from original array to the other array
for (int i = 0, k = 0; i < arr.length; i++) {
// if the index is
// the removal element index
if (i == index) {
continue;
}
// if the index is not
// the removal element index
anotherArray[k++] = arr[i];
}
//Java >8
//IntStream.range(0, arr.length).filter(i -> i != index).map(i -> arr[i]).toArray();
return anotherArray;
}
//My solution in C++ it avoid overflow
inline int Triangle(vector<int> &A) {
if(A.size() < 3) return 0;
sort(A.begin(), A.end());
for(int i = 0; i < (int)A.size() - 2; ++i){
int P = A[i], Q = A[i + 1], R =A[i + 2];
if(( R - P - Q < 0) && ( P - Q - R < 0) && (Q - R - P < 0))
return 1;
}
return 0;
}
Ruby 100% solution
def solution(a)
arr = a.select{|x| x >=0 }.sort
arr.each_with_index do |p, pi|
arr[(pi+1)..-1].each_with_index do |q, qi|
arr[(qi+pi+2)..-1].each do |r|
break if p+q <=r
break if p+r <=q
break if r+q <=p
return 1
end
end
end
0
end
It's javascript solution(TC: O(N*log(N)) though, in case you guys want :).
function solution(A) {
if(A.length<3) return 0;
A.sort((a,b)=>b - a);
for(let i = 0,j = i+1;j < A.length-1;j++){
let p = A[j],q = A[j+1],r = A[i]
if(r - p > q) i++;
else if(r - p < q) return 1;
}
return 0;
}
Sorting does not work now, It was a bug it was fixed by Codility. Now, I am using this piece of code to get 93%
You can see the results below:
Codility test Results
0 <= P < Q < R < N
public static int solution(int[] unfilteredArray) {
int[] array = filterLessThanOneElements(unfilteredArray);
for(int i = 0; i <= (array.length - 3) ; i++) {
long p = array[i];
for(int j = i+1; j <= (array.length - 2); j++) {
long q = array[j];
for(int k = j+1; k <= (array.length - 1); k++) {
long r = array[k];
if((p + q > r) && (q + r > p) && (r + p > q)) {
return 1;
}
}
}
}
return 0;
}
// The mose efficient way to remove duplicates
// TIME COMPLEXITY : O(N)
private static int[] filterLessThanOneElements(int[] unfilteredArray) {
int k = 0;
for(int i = 0; i < unfilteredArray.length; i++) {
if(unfilteredArray[i] > 0) {
unfilteredArray[k++] = unfilteredArray[i];
}
}
return Arrays.copyOfRange(unfilteredArray, 0, k);
}
Simple change: First, you observe that negative integers cannot be part of a triangular triplet. That means you can cast all ints to unsigned int, and there can’t be any overflow anymore.
100/100 JavaScript solution
function solution(A) {
let l = A.length;
if (l < 3) {
return 0;
}
A.sort((a, b) => a - b);
for (let i = 0; i < l - 2; i++) {
let [p, q, r] = [A[i], A[i + 1], A[i + 2]];
if (p + q > r && q + r > p && r + p > q) {
return 1;
}
}
return 0;
}
If you don't want to use Array.sort, the following works with 100% correctness and 100% performance with a complexity that codility detects at O(N*log(N)).
class Solution {
public int solution(int[] A) {
int ans = 0;
int p1 = -1;
int p2 = -1;
int p1Pos = 0;
int p2Pos = 1;
int cur = -1;
if(A.length > 2){
p1 = A[0];
p2 = A[1];
for(int i = p2Pos + 1; i < A.length; i++){
if(p1 > p2){
p2 = A[p1Pos];
p1 = A[p2Pos];
A[p2Pos] = p2;
A[p1Pos] = p1;
}
cur = A[i];
//System.out.println(p1 + " " + p2 + " " + cur);
if(p1 > -1 && p2 > -1){
//the test for a triangle
if (cur > -1 &&
((p1 == p2 && p2 == cur) ||
((p1 + p2 > cur) && (p1 + cur > p2) && ( cur + p2 > p1)))){
return 1;
//bubble sort...sort of
}else if (p2 > cur){
A[p2Pos] = cur;
A[i] = p2;
if(p1 < cur){
p1 = cur;
p1Pos = p2Pos;
}
p2Pos = i;
} else if(cur > -1
&&(p1 + p2 <= cur) ){
p2Pos++;
p1Pos++;
p1=p2;
p2=cur;
}
}else{
//find the first two positive numbers
if((p2 < 0 || p1 < 0) && cur > -1){
if(p1 < 0){
p1 = cur;
p1Pos = i;
}else{
p2 = A[i];
p2Pos = i;
}
}
}
}
}
return ans;
}
}
When I was making this I thought that maybe I could solve this while doing a modified Bubble sort. I chose two pivots (p1 and p2), while making sure p2 > p1.
As I iterated through the array, I made sure that p2 would bubble up if p2 > cur and that p1 would additionally bubble up if p1 > cur. I Furthermore, I noticed that any combination of three points that have a negative number cannot be a triangle. So I ignored negatives. I also realized that if the array happened to hold three and only maximal integers that I would have an issue. To solve this I tested for p1 == p2 == cur. Admittingly, it might be better to use BigInteger to solve it.
My 100% JavaScript solution with O(N*log(N)) time complexity:
function solution(A) {
A.sort((a, b) => a - b);
for (let i = 0, len = A.length - 2; i < len; i++) {
const [P, Q, R] = [A[i], A[i + 1], A[i + 2]];
if (P + Q > R && Q + R > P && R + P > Q) {
return 1;
}
}
return 0;
}
One would think that sorting the array first will violate the condition 0<=P<Q<R. But the question is does such a triple exist. For the example we find [10,2,5,1,8,20]. After sorting we still find the values 10, 5, and 8 as the triple, but in a different order.
A Python 3 solution with 100% score at Codility:
def triangle(A):
n = len(A)
if n < 3:
return 0
a = list(A)
if 0 not in a:
a.append(0)
a.sort()
#print(a)
n = len(a)
p_a = a[a.index(0)+1:n]
#print(p_a)
n = len(p_a)
for i in range(n-2):
p = p_a[i]
q = p_a[i+1]
r = p_a[i+2]
if (p+q>r):
return (1)
return 0
Better solutions for C++ is to change a little algorithm. Make subtraction instead of adding, here is an example:
int solution(vector<int> &A) {
if (A.size() < 3)
return 0;
sort(A.begin(), A.end());
for (int i = 0; i < A.size() - 2; i++) {
if (A[i] > 0 && (A[i] > A[i + 2] - A[i + 1]))
return 1;
}
return 0;
}
It's because of integer overflow.
Try out this one:
int a1 = 1900000000;
int a2 = 1900000000;
int sum = a1+a2; // sum will be -494967296
Edit: Use long long int.
long long int sum01 = A[i] + A[i+1];
long long int sum12 = A[i+1] + A[i+2];
long lont int sum02 = A[i] + A[i+2];
if (sum01 > A[i+2] && sum12 > A[i] && sum02 > A[i+1])
return 1;
My java Solution 100/100 Instead of comparing the Addition we compare the subtraction as we can have an Integer.MAX_VALUE an we will be getting corrupted data.
public static int solution(int[] A) {
int isATriangle = 0;
Arrays.sort(A);
if (A.length >= 3) {
for (int i = 0; i < A.length - 2; i++) {
if (A[i] > A[i + 2] - A[i + 1]
&& A[i + 2] > A[i] - A[i + 1]
&& A[i + 2] > A[i + 1] - A[i])
isATriangle = 1;
}
}
return isATriangle;
}

c++ Decimal to binary, then use operation, then back to decimal

I have an array with x numbers: sets[ ](long numbers) and a char array operations[ ] with x-1 numbers. For each number from sets[ ], its binary form(in 64bits) would be the same as a set of numbers( these numbers being from 0 to 63 ), 1's and 0's representing whether it is inside a subset or not ( 1 2 4 would be 1 1 0 1, since 3 is missing)
ex: decimal 5 --->000...00101 , meaning that this subset will only have those 2 last numbers inside it(#63 and #61)
now,using the chars i get in operations[], i should work with them and the binaries of these numbers as if they were operations on subsets(i hope subset is the right word), these operations being :
U = reunion ---> 101 U 010 = 111
A = intersection ---> 101 A 001 = 001
\ = A - B ---> 1110 - 0011 = 1100
/ = B-A ---> like the previous one
so basically I'd have to read numbers, make them binary, use them as if they were sets and use operations accordingly, then return the result of all these operations on them.
my code :
include <iostream>
using namespace std;
void makeBinaryVector(int vec[64], long xx)
{
// put xx in binary form in array "vec[]"
int k = 63;
long x = xx;
if(xx == 0)
for(int i=0;i<64;i++)
vec[i] = 0;
while(x != 0)
{
vec[k] = x % 2;
x = x / 2;
k--;
}
}
void OperationInA(int A[64], char op, int B[64])
{
int i;
if(op == 'U') //reunion
for(i=0;i<64;i++)
if(B[i] == 1)
A[i] = 1;
if(op == 'A') //intersection
for(i=0;i<64;i++)
{
if((B[i] == 1) && (A[i] == 1))
A[i] = 1;
else
A[i] = 0;
}
if(op == '\\') //A-B
for(i=0;i<64;i++)
{
if( (A[i] == 0 && B[i] == 0) || (A[i] == 0 && B[i] == 1) )
A[i] = 0;
else
if((A[i] == 1) && (B[i] == 1))
A[i] = 0;
else
if((A[i] == 1) && (B[i] == 0))
A[i] = 1;
}
if(op == '/') //B-A
for(i=0;i<64;i++)
{
if(B[i] == 0)
A[i] = 0;
else
if((B[i] == 1) && (A[i] == 0))
A[i] = 1;
else
if((B[i] == 1) && (A[i] == 1))
A[i] = 0;
}
}
unsigned long setOperations(long sets[], char operations[], unsigned int x)
{
unsigned int i = 1; //not 0, since i'll be reading the 1st number separately
unsigned int j = 0;
unsigned int n = x;
int t;
long a = sets[0];
int A[64];
for(t=0;t<64;t++)
A[t] = 0;
makeBinaryVector(A, a); //hold in A the first number, binary, and the results of operations
long b;
int B[64];
for(t=0;t<64;t++) //Hold the next number in B[], in binary form
B[t] = 0;
char op;
while(i < x && j < (x-1) )
{
b = sets[i];
makeBinaryVector(B, b);
op = operations[j];
OperationInA(A, op, B);
i++; j++;
}
//make array A a decimal number
unsigned int base = 1;
long nr = 0;
for(t=63; t>=0; t--)
{
nr = nr + A[t] * base;
base = base * 2;
}
return nr;
}
long sets[100];
char operations[100];
long n,i;
int main()
{
cin>>n;
for(i=0;i<n;i++)
cin>>sets[i];
for(i=0;i<n-1;i++)
cin>>operations[i];
cout<<setOperations(sets,operations,n);
return 0;
}
So everything seems fine, except when im trying this :
sets = {5, 2, 1}
operations = {'U' , '\'}
5 U 2 is 7(111), and 7 \ 1 is 6 (111 - 001 = 110 --> 6)
the result should be 6, however when i Input them like that the result is 4 (??)
however, if i simply input {7,1} and { \ } the result is 6,as it should be. but if i input them like i first mentioned {5,2,1} and {U,} then its gonna output 4.
I can't seem to understand or see what im doing wrong...
You don't have to "convert to binary numbers".
There's no such thing as 'binary numbers'. You can just perform the operations on the variables.
For the reunion, you can use the bitwise OR operator '|', and for the intersection, you can use the bitwise AND operator '&'.
Something like this:
if (op == 'A')
result = a & b;
else if (op == 'U')
result = a | b;
else if (op == '\\')
result = a - b;
else if (op == '/')
result = b - a;
Use bitwise operators on integers as shown in #Hugal31's answer.
Note that integer size is usually 32bit, not 64bit. On a 64bit system you need long long for 64bit integer. Use sizeof operator to check. int is 4 bytes (32bit) and long long is 8 bytes (64bit).
For the purpose of homework etc., your conversion to vector cannot be right. You should test it to see if it outputs the correct result. Otherwise use this:
void makebinary(int vec[32], int x)
{
int bitmask = 1;
for (int i = 31; i >= 0; i--)
{
vec[i] = (x & bitmask) ? 1 : 0;
bitmask <<= 1;
}
}
Note the use of shift operators. To AND the numbers you can do something like the following:
int vx[32];
int vy[32];
makebinary(vx, x);
makebinary(vy, y);
int result = 0;
int j = 1;
for (int i = 31; i >= 0; i--)
{
int n = (vx[i] & vy[i]) ? 1 : 0;
result += n * j;
j <<= 1;
}
This is of course pointless because you can just say int result = X & Y;

Algorithm to calculate sum of LUCKY FACTOR in given range

Problem Statement :-
A number is given, N, which is given in binary notation, and it
contains atmost 1000000 bits. You have to calculate the sum of LUCKY
FACTOR in range from 1 to N (decimal notation).
Here, LUCKY FACTOR means, (after converting into binary representation) if
rightmost or leftmost 1's neighbour is either 0 or nothing(for
boundary bit).
EDITED :-
Means if rightmost one's left neighbour is 0, means it count as a
LUCKY FACTOR, simlarly in the left side also
Example,
5 == 101, LUCKY FACTOR = 2.
7 == 111, LUCKY FACTOR = 0.
13 == 1101, LUCKY FACTOR = 1.
16 == 1110, LUCKY FACTOR = 0.
0 == 0, LUCKY FACTOR = 0.
Answer must be in binary form
I am totally stuck, give me a hint.
My code
#include<stdio.h>
#include<string>
#include<string.h>
#include<vector>
//#include<iostream>
using namespace std;
vector<string> pp(10000001);
string add(string a, string b) {
if(b == "") return a;
string answer = "";
int c = 0;
int szeA = a.size() - 1;
int szeB = b.size() - 1;
while(szeA >= 0 || szeB >= 0) {
answer = (char)( ( ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) ^ ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) ) ^ (c) ) + 48 ) + answer;
c = ( ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) & ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) ) | ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) & (c) ) | ( ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) & (c) ) );
szeA--;
szeB--;
}
if(c) answer = '1' + answer;
return answer;
}
string subtract(string a, string b) {
int sze = a.size() - b.size();
while(sze--) b = '0' + b;
sze = a.size();
for(int i = 0; i < sze; i++) {
if(b[i] == '1') b[i] = '0';
else b[i] = '1';
}
if(b[sze-1] == '0') {
b[sze-1] = '1';
}
else {
int i = sze-1;
while(i >= 0 && b[i] == '1') {
b[i] = '0';
i--;
}
if(i >= 0) b[i] = '1';
else b = '1' + b;
}
b = add(a, b);
b.erase(b.begin() + 0);
//b[0] = '0';
while(b[0] == '0') b.erase(b.begin() + 0);
return b;
}
string power(int index) {
if(index < 0) return "";
string answer = "";
while(index--) {
answer = '0' + answer;
}
answer = '1' + answer;
return answer;
}
string convert(long long int val) {
int divisionStore=0;
int modStore=0;
string mainVector = "";
do {
modStore=val%2;
val=val/2;
mainVector = (char)(modStore+48) + mainVector;
}while(val!=0);
return mainVector;
}
string increment(string s) {
int sze = s.size()-1;
if(s[sze] == '0') {
s[sze] = '1';
return s;
}
while(sze >= 0 && s[sze] == '1') {
s[sze] = '0';
sze--;
}
if(sze >= 0) s[sze] = '1';
else s = '1' + s;
return s;
}
main() {
int T;
char s[1000001];
string answer;
scanf("%d", &T);
for(int t = 1; t <= T; t++) {
int num;
answer = "1";
int bitComeEver = 0;
int lastBit = 0;
scanf("%s", s);
int sze = strlen(s);
// I used below block because to avoid TLE.
if(sze > 3300) {
printf( "Case #%d\n", t);
for(int i = 0; i < sze; i++) printf("%c", '1');
printf("\n");
//continue;
}
else {
if(pp[sze-1] != "") answer = pp[sze-1];
else {
pp[sze-1] = power(sze-1);
answer = pp[sze-1];
}
answer = subtract(answer, convert(sze-1));
////////////////////////////
//cout << answer << endl;
for(int i = 1; i < sze; i++) {
if(s[i] == '1') {
if(s[1] == '0') {
num = sze-i-1;
if(num > 0) {
if( pp[num-1] == "") {
pp[num-1] = power(num-1);
}
if(pp[num+1] == "") {
pp[num+1] = power(num+1);
}
answer = add(answer, subtract(pp[num+1], pp[num-1]));
if(lastBit) answer = add(answer, "1");
//else answer = increment(answer);
//cout << "\t\t" << answer << endl;
}
else{
int inc;
if(lastBit) inc = 2; //answer = add(answer, "10");
else inc = 1; //answer = increment(answer);
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
if(lastBit) inc += 2;
else inc += 1;
if(inc == 2) answer = add(answer, "10");
else if(inc == 3) answer = add(answer, "11");
else answer = add(answer, "100");
}
}
else {
if(num > 0) {
if(pp[num-1] != "") pp[num-1] = power(num-1);
answer = add(answer, pp[num-1]);
}
else {
int inc = 0;
if(lastBit) inc = 1; //answer = increment(answer);
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
if(lastBit) inc += 1;
answer = add(answer, convert(inc));
}
}
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
}
}
if(s[sze-1] == '0') {
if(lastBit) {
if(s[1] == '0') {
answer = add(answer, "10");
}
else answer = increment(answer);
}
else if(s[1] == '0'){
answer = increment(answer);
}
}
printf( "Case #%d\n", t);
for(int i = 0; i < sze; i++) printf("%c", answer[i]);
printf("\n");
}
}
return 0;
}
If a number has k bits, then calculate the number of such numbers having a LUCKY FACTOR of 2:
10.............01
Hence in this the 1st two and last two digits are fixed, the remaining k-4 digits can have any value. The number of such numbers = 2^(k-4).
So you can easily calculate the sum of lucky factors of such numbers = lucky_factor x 2^(k-4)
(ofcourse this is assuming k >= 4)
What's more, you do not need to calculate this number since it will be of the form 10000000.
If the number n is 11010010. Then 8 bit numbers less than n shall be of form:
10........ or 1100...... or 1101000_. If you see a pattern, then we have divided the calculation in terms of the number of 1s in the number n
.
I leave the rest for you.

Coin Change Bottom Up Dynamic Programming

http://uva.onlinejudge.org/external/6/674.html I'm trying to solve that problem. Note, though, that it's not the minimum coin change problem, it asks me for the different number of ways to make N cents using 50, 25, 15, 10, 5 and 1 cent coins. It's fairly straightforward, so I made this function:
int count(int n, int m) // n is the N of the problem, m is the number of coin types and s[] is {1, 5, 10, 25, 50}
{
if (n == 0)
{
return 1;
}
if (n < 0)
{
return 0;
}
if (m < 0 && n >= 1)
{
return 0;
}
return DP[n][m - 1] + DP[n - s[m]][m];
}
Fairly straightforward too is adding Dynamic Programming with memoization:
int count(int n, int m)
{
if (n == 0)
{
return 1;
}
if (n < 0)
{
return 0;
}
if (m < 0 && n >= 1)
{
return 0;
}
if (DP[n][m - 1] == -1 || DP[n - s[m]][m] == -1)
{
return count(n, m - 1) + count(n - s[m], m);
}
else
{
return DP[n][m - 1] + DP[n - s[m]][m];
}
}
However, none of these is fast enough - I need bottom up Dynamic Programming, but I am having difficulties coding it, even with some help from Algorithmist - http://www.algorithmist.com/index.php/Coin_Change.
void generate()
{
for (i = 0; i < MAX; i++)
{
for (u = 0; u < m; u++)
{
if (i == 0)
{
DP[i][u] = 1;
}
else if (u == 0)
{
DP[i][u] = 0;
}
else if (s[u] > i)
{
DP[i][u] = DP[i][u - 1];
}
else
{
DP[i][u] = DP[i][u - 1] + DP[i - s[u]][u];
}
}
}
}
I get 0 for every result for some reason, here's my full code:
#include <stdio.h>
#include <string.h>
using namespace std;
#define MAX 7490
int s[] = {1, 5, 10, 25, 50}, m = 5, input, DP[MAX][5], i, u;
int count(int n, int m)
{
if (n == 0)
{
return 1;
}
if (n < 0)
{
return 0;
}
if (m < 0 && n >= 1)
{
return 0;
}
if (DP[n][m - 1] == -1 || DP[n - s[m]][m] == -1)
{
return count(n, m - 1) + count(n - s[m], m);
}
else
{
return DP[n][m - 1] + DP[n - s[m]][m];
}
}
void generate()
{
for (i = 0; i < MAX; i++)
{
for (u = 0; u < m; u++)
{
if (i == 0)
{
DP[i][u] = 1;
}
else if (u == 0)
{
DP[i][u] = 0;
}
else if (s[u] > i)
{
DP[i][u] = DP[i][u - 1];
}
else
{
DP[i][u] = DP[i][u - 1] + DP[i - s[u]][u];
}
}
}
}
int main()
{
memset(DP, -1, sizeof DP);
generate();
while (scanf("%d", &input) != EOF)
{
//printf("%d\n", count(input, 4));
printf("%d\n", DP[input][4]);
}
return 0;
}
You did the mistake here:
else if (u == 0)
{
DP[i][u] = 0;
}
It should be DP[i][u]=1 because you can produce any value i using 1 cent coin in 1 possible way. i.e. to take 5 cent you will take 5 one cent coins which is one way to make 5-cent in total.
-----
Btw, in you 1st approach in count method did you have this:
if (DP[n][m - 1] == -1 || DP[n - s[m]][m] == -1)
{
return count(n, m - 1) + count(n - s[m], m);
}
Or this:
if (DP[n][m - 1] == -1 || DP[n - s[m]][m] == -1)
{
return DP[n][m] = count(n, m - 1) + count(n - s[m], m);
}
If you did not memoize an already calculated result then this memoization check if (DP[n][m - 1] == -1 || DP[n - s[m]][m] == -1) will never work, which might be the cause of your 1st approach to be too slow :-?

Smallest number that is evenly divisible by all of the numbers from 1 to 20?

I did this problem [Project Euler problem 5], but very bad manner of programming, see the code in c++,
#include<iostream>
using namespace std;
// to find lowest divisble number till 20
int main()
{
int num = 20, flag = 0;
while(flag == 0)
{
if ((num%2) == 0 && (num%3) == 0 && (num%4) == 0 && (num%5) == 0 && (num%6) == 0
&& (num%7) == 0 && (num%8) == 0 && (num%9) == 0 && (num%10) == 0 && (num%11) == 0 && (num%12) ==0
&& (num%13) == 0 && (num%14) == 0 && (num%15) == 0 && (num%16) == 0 && (num%17) == 0 && (num%18)==0
&& (num%19) == 0 && (num%20) == 0)
{
flag = 1;
cout<< " lowest divisible number upto 20 is "<< num<<endl;
}
num++;
}
}
i was solving this in c++ and stuck in a loop, how would one solve this step......
consider num = 20 and divide it by numbers from 1 to 20
check whether all remainders are zero,
if yes, quit and show output num
or else num++
i din't know how to use control structures, so did this step
if ((num%2) == 0 && (num%3) == 0 && (num%4) == 0 && (num%5) == 0 && (num%6) == 0
&& (num%7) == 0 && (num%8) == 0 && (num%9) == 0 && (num%10) == 0 && (num%11) == 0 && (num%12) ==0
&& (num%13) == 0 && (num%14) == 0 && (num%15) == 0 && (num%16) == 0 && (num%17) == 0 && (num%18)==0
&& (num%19) == 0 && (num%20) == 0) `
how to code this in proper manner?
answer for this problem is:
abhilash#abhilash:~$ ./a.out
lowest divisible number upto 20 is 232792560
The smallest number that is divisible by two numbers is the LCM of those two numbers. Actually, the smallest number divisible by a set of N numbers x1..xN is the LCM of those numbers. It is easy to compute the LCM of two numbers (see the wikipedia article), and you can extend to N numbers by exploiting the fact that
LCM(x0,x1,x2) = LCM(x0,LCM(x1,x2))
Note: Beware of overflows.
Code (in Python):
def gcd(a,b):
return gcd(b,a%b) if b else a
def lcm(a,b):
return a/gcd(a,b)*b
print reduce(lcm,range(2,21))
Factor all the integers from 1 to 20 into their prime factorizations. For example, factor 18 as 18 = 3^2 * 2. Now, for each prime number p that appears in the prime factorization of some integer in the range 1 to 20, find the maximum exponent that it has among all those prime factorizations. For example, the prime 3 will have exponent 2 because it appears in the factorization of 18 as 3^2 and if it appeared in any prime factorization with an exponent of 3 (i.e., 3^3), that number would have to be at least as large as 3^3 = 27 which it outside of the range 1 to 20. Now collect all of these primes with their corresponding exponent and you have the answer.
So, as example, let's find the smallest number evenly divisible by all the numbers from 1 to 4.
2 = 2^1
3 = 3^1
4 = 2^2
The primes that appear are 2 and 3. We note that the maximum exponent of 2 is 2 and the maximum exponent of 3 is 1. Thus, the smallest number that is evenly divisible by all the numbers from 1 to 4 is 2^2 * 3 = 12.
Here's a relatively straightforward implementation.
#include <iostream>
#include <vector>
std::vector<int> GetPrimes(int);
std::vector<int> Factor(int, const std::vector<int> &);
int main() {
int n;
std::cout << "Enter an integer: ";
std::cin >> n;
std::vector<int> primes = GetPrimes(n);
std::vector<int> exponents(primes.size(), 0);
for(int i = 2; i <= n; i++) {
std::vector<int> factors = Factor(i, primes);
for(int i = 0; i < exponents.size(); i++) {
if(factors[i] > exponents[i]) exponents[i] = factors[i];
}
}
int p = 1;
for(int i = 0; i < primes.size(); i++) {
for(int j = 0; j < exponents[i]; j++) {
p *= primes[i];
}
}
std::cout << "Answer: " << p << std::endl;
}
std::vector<int> GetPrimes(int max) {
bool *isPrime = new bool[max + 1];
for(int i = 0; i <= max; i++) {
isPrime[i] = true;
}
isPrime[0] = isPrime[1] = false;
int p = 2;
while(p <= max) {
if(isPrime[p]) {
for(int j = 2; p * j <= max; j++) {
isPrime[p * j] = false;
}
}
p++;
}
std::vector<int> primes;
for(int i = 0; i <= max; i++) {
if(isPrime[i]) primes.push_back(i);
}
delete []isPrime;
return primes;
}
std::vector<int> Factor(int n, const std::vector<int> &primes) {
std::vector<int> exponents(primes.size(), 0);
while(n > 1) {
for(int i = 0; i < primes.size(); i++) {
if(n % primes[i] == 0) {
exponents[i]++;
n /= primes[i];
break;
}
}
}
return exponents;
}
Sample output:
Enter an integer: 20
Answer: 232792560
There is a faster way to answer the problem, using number theory. Other answers contain indications how to do this. This answer is only about a better way to write the if condition in your original code.
If you only want to replace the long condition, you can express it more nicely in a for loop:
if ((num%2) == 0 && (num%3) == 0 && (num%4) == 0 && (num%5) == 0 && (num%6) == 0
&& (num%7) == 0 && (num%8) == 0 && (num%9) == 0 && (num%10) == 0 && (num%11) == 0 && (num%12) ==0
&& (num%13) == 0 && (num%14) == 0 && (num%15) == 0 && (num%16) == 0 && (num%17) == 0 && (num%18)==0
&& (num%19) == 0 && (num%20) == 0)
{ ... }
becomes:
{
int divisor;
for (divisor=2; divisor<=20; divisor++)
if (num%divisor != 0)
break;
if (divisor != 21)
{ ...}
}
The style is not great but I think this is what you were looking for.
See http://en.wikipedia.org/wiki/Greatest_common_divisor
Given two numbers a and b you can compute gcd(a, b) and the smallest number divisible by both is a * b / gcd(a, b). The obvious thing then to do is to keep a sort of running total of this and add in the numbers you care about one by one: you have an answer so far A and you add in the next number X_i to consider by putting
A' = A * X_i / (gcd(A, X_i))
You can see that this actually works by considering what you get if you factorise everything and write them out as products of primes. This should pretty much allow you to work out the answer by hand.
Hint:
instead of incrementing num by 1 at each step you could increment it by 20 (will work alot faster). Of course there may be other improvements too, ill think about it later if i have time. Hope i helped you a little bit.
The number in question is the least common multiple of the numbers 1 through 20.
Because I'm lazy, let ** represent exponentiation. Let kapow(x,y) represent the integer part of the log to the base x of y. (For example, kapow(2,8) = 3, kapow(2,9) = 3, kapow(3,9) = 2.
The primes less than or equal to 20 are 2, 3, 5, 7, 11, 13, and 17. The LCM is,
Because sqrt(20) < 5, we know that kapow(i,20) for i >= 5 is 1. By inspection, the LCM is
LCM = 2kapow(2,20) * 3kapow(3,20)
* 5 * 7 * 11 * 13 * 17 * 19
which is
LCM = 24 * 32 * 5 * 7 * 11 * 13 *
17 * 19
or
LCM = 16 * 9 * 5 * 7 * 11 * 13 * 17 *
19
Here is a C# version of #MAK's answer, there might be List reduce method in C#, I found something online but no quick examples so I just used a for loop in place of Python's reduce:
static void Main(string[] args)
{
const int min = 2;
const int max = 20;
var accum = min;
for (var i = min; i <= max; i++)
{
accum = lcm(accum, i);
}
Console.WriteLine(accum);
Console.ReadLine();
}
private static int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a % b);
}
private static int lcm(int a, int b)
{
return a/gcd(a, b)*b;
}
Code in JavaScript:
var i=1,j=1;
for (i = 1; ; i++) {
for (j = 1; j <= 20; j++) {
if (i % j != 0) {
break;
}
if (i % j == 0 && j == 20) {
console.log('printval' + i)
break;
}
}
}
This can help you
http://www.mathwarehouse.com/arithmetic/numbers/prime-number/prime-factorization.php?number=232792560
The prime factorization of 232,792,560
2^4 • 3^2 • 5 • 7 • 11 • 13 • 17 • 19
Ruby Cheat:
require 'rational'
def lcmFinder(a = 1, b=2)
if b <=20
lcm = a.lcm b
lcmFinder(lcm, b+1)
end
puts a
end
lcmFinder()
this is written in c
#include<stdio.h>
#include<conio.h>
void main()
{
int a,b,flag=0;
for(a=1; ; a++)
{
for(b=1; b<=20; b++)
{
if (a%b==0)
{
flag++;
}
}
if (flag==20)
{
printf("The least num divisible by 1 to 20 is = %d",a);
break;
}
flag=0;
}
getch();
}
#include<vector>
using std::vector;
unsigned int Pow(unsigned int base, unsigned int index);
unsigned int minDiv(unsigned int n)
{
vector<unsigned int> index(n,0);
for(unsigned int i = 2; i <= n; ++i)
{
unsigned int test = i;
for(unsigned int j = 2; j <= i; ++j)
{
unsigned int tempNum = 0;
while( test%j == 0)
{
test /= j;
tempNum++;
}
if(index[j-1] < tempNum)
index[j-1] = tempNum;
}
}
unsigned int res =1;
for(unsigned int i = 2; i <= n; ++i)
{
res *= Pow( i, index[i-1]);
}
return res;
}
unsigned int Pow(unsigned int base, unsigned int index)
{
if(base == 0)
return 0;
if(index == 0)
return 1;
unsigned int res = 1;
while(index)
{
res *= base;
index--;
}
return res;
}
The vector is used for storing the factors of the smallest number.
This is why you would benefit from writing a function like this:
long long getSmallestDivNum(long long n)
{
long long ans = 1;
if( n == 0)
{
return 0;
}
for (long long i = 1; i <= n; i++)
ans = (ans * i)/(__gcd(ans, i));
return ans;
}
Given the maximum n, you want to return the smallest number that is dividable by 1 through 20.
Let's look at the set of 1 to 20. First off, it contains a number of prime numbers, namely:
2
3
5
7
11
13
17
19
So, because it's has to be dividable by 19, you can only check multiples of 19, because 19 is a prime number. After that, you check if it can be divided by the one below that, etc. If the number can be divided by all the prime numbers successfully, it can be divided by the numbers 1 through 20.
float primenumbers[] = { 19, 17, 13, 11, 7, 5, 3, 2; };
float num = 20;
while (1)
{
bool dividable = true;
for (int i = 0; i < 8; i++)
{
if (num % primenumbers[i] != 0)
{
dividable = false;
break;
}
}
if (dividable) { break; }
num += 1;
}
std::cout << "The smallest number dividable by 1 through 20 is " << num << std::endl;