Dividing an array into the greatest amount of parts with equal sums - c++

The array can hold negative numbers. I've written this code using recursion. First I'm summing the first i elements and then I'm checking for each such sum if the rest of the array (starting from i + 1) can be divided with this sum.
It works for some cases but not for others. I've noticed that it doesn't work if there's a prime somewhere.
It works if I sort the array in descending order beforehand but I don't understand why.
In this case the output is 2, while it should be 0.
#include <iostream>
const int N = 5;
int tab[N] = {1, 2, 3, 3, 4};
// returns the number of partitions with a given sum (or 0 if it can't be partitioned)
int divisions(int tab[N], int p, int sum) {
if (N < 2) return 0;
if (p == N) {
return 1;
}
int s_sum = tab[p++];
while (s_sum != sum && p < N) {
s_sum += tab[p++];
}
if (s_sum == sum) {
return divisions(tab, p, sum) + 1;
} else {
return 0;
}
}
// creates all the possible sums and returns the greatest number of partitions where each partition sums up to some sum
int compareAllDivisions(int tab[N]) {
int maxResult = 0;
for (int i = 0; i < N; ++i) {
int sum = 0;
for (int j = 0; j <= i; ++j) {
sum += tab[j];
}
int result = divisions(tab, i + 1, sum);
if (maxResult < result) {
maxResult = result;
}
}
if (maxResult >= 2) {
return maxResult;
} else {
return 0;
}
}
int main() {
std::cout << compareAllDivisions(tab) << std::endl;
return 0;
}

It is because of return value of if (s_sum == sum) part.
It should be changed like below
if (s_sum == sum) {
int ret = divisions(tab, p, sum);
if(ret == 0) return 0;
else return ret + 1;
} else {
return 0;
}
Your return value of divisions is 0 when can't make and pos number when can make.
So, let's consider when 0 returns in there. It can't make at the back, but it will return pos number!

Related

Are my if-conditions correct to sum up the even fibonacci numbers up to 4 million?

Starting from 1 and 2, compute the sum of all even fibonacci numbers (while these numbers are smaller or equal to 4 million)
I am trying to sum all even fibonacci numbers up to 4e6, but it doesn't give me anywhere the right result, and I don't understand where I've messed up. In my mind, the conditions for the if are correct.
My fibonacci() function, and my function to sum the even numbers up, is below.
int fibonacci(int k) //compute the k-th fibonacci number (with EulerProject formula)
{
if (k == 1 || k == 2)
{
return k;
}
{
return (fibonacci(k-1)+ fibonacci(k-2));
}
}
int evenfibonacci()
{
int result = 0;
for (int k = 1; fibonacci(k)<=4e6;) {
if (fibonacci(k)%2 == 0 ) {
result += fibonacci(k);
k++;
} else {
k++;
}
}
}
evenfibonacci() is declared as returning an int value, but does not actually return anything, which is undefined behavior. Thus, the return value is always indeterminate, it ends up returning random garbage, which is why you never get a good result.
You need to add a return statement, eg:
int evenfibonacci()
{
int result = 0;
for (int k = 1; fibonacci(k) <= 4e6; ++k) {
if (fibonacci(k) % 2 == 0) {
result += fibonacci(k);
}
}
return result; // <-- ADD THIS
}
Online Demo
That being said, calling fibonacci(k) 3 times per loop iteration is very inefficient, calculating the same values over and over, especially for higher values of k. You should call it only 1 time per loop, eg:
int evenfibonacci()
{
int result = 0;
for (int k = 1; k <= 33; ++k) {
int value = fibonacci(k);
if (value % 2 == 0) {
result += value;
}
}
return result;
}
Online Demo
Of course, a better solution would be to get rid of fibonacci() altogether, and instead use an iterative approach to calculating only new values per iteration, eg:
int evenfibonacci()
{
int result = 2;
int last[2] = {1, 2};
for (int k = 3; k <= 33; ++k) {
int value = last[0] + last[1];
if (value % 2 == 0) {
result += value;
}
last[0] = last[1];
last[1] = value;
}
return result;
}
Online Demo

How can I find minimum and unique element of array in c++?

I have array(of numbers) with size N. I need to find minimum element which is unique,so if arr[5] ={1,2,3,1,2}, answer is 3.
I tried that with following code:
Int n = sizeof(arr)/sizeof(arr[0]);
sort(arr,arr + n);
for(int i = 0;i<N;i++){
for(int j = 0;j<N;j++){
if(arr[i] == arr[j]){
remove(arr,arr+n,i);
remove(arr,arr+n,j);
}
}
}
But problem is that this only work if I have 2 identical elements of arr.I could create if conditions for number of identical, but I can have 3 or 4 or 1000,so it will be pretty odd. So what is more elagant way to do this? Thank you in advance.
try this code, this uses an unordered map
int m = 2147483647;
int int_array[] = { 1,2,3,3,1,6,7,7,9 };
unordered_map<int, int> map;
for (int i = 0; i < sizeof(int_array) / sizeof(int_array[0]); i++) {
map[int_array[i]] = map[int_array[i]] + 1;
}
unordered_map<int, int>::iterator itr;
for (itr = map.begin(); itr != map.end(); itr++)
{
if (itr->second == 1) {
if (itr->first < m) {
m = itr->first;
}
}
}
printf("minimum unique is %d", m);
after sorting the array you can count the number of the dublicated members , if the member is unique then its count equals zero :
int main()
{
int arr[] = { 1, 2, 1, 3, 4, 1, 2 };
int n = sizeof(arr) / sizeof(int);
sort(arr, arr + n);
int count = 0;
int unique = -1;
for (int i = 0; unique == -1 && i < n - 1; ++i) {
if (arr[i] != arr[i + 1]) {
if (count==0)
unique = arr[i];
else
count = 0;
}
else {
count++;
}
}
if (count == 0 && unique ==-1)
unique = arr[n-1];
cout << unique;
return 0;
}
I propose the following code:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int arr[5] = { 1,2,3,2,1 };
int N = sizeof(arr) / sizeof(arr[0]);
sort(arr, arr + N);
int index = -1;
// Check first element is different comparing with second one.
// If the array is only one element, then first element is unique
if (N == 1 || arr[0] != arr[1]) {
index = 0;
}
else {
int i = 1;
while (i < N - 1 && index == -1) {
// Check number is different to previous and different to next value
if (arr[i - 1] != arr[i] && arr[i] != arr[i + 1]) {
index = i;
}
else
{
i++;
}
}
if (index == -1) {
// No found, check last element comparing with previous
if (arr[i - 1] != arr[i]) {
index = i;
}
}
}
if (index != -1) {
// Have found min value
cout << "Min not repeated value is " << arr[index] << endl;
}
else {
// All elements are repeated
cout << "No min value" << endl;
}
}
Once the array is sorted, I compare each value with previous and next value to check it is unique. But for first and last element are a special case.
Using what I said in the comments, with an extra bool.
int arr[] = { 1, 2, 1, 3, 4, 1, 2 };
int n = sizeof( arr ) / sizeof( int );
std::sort( arr, arr + n );
bool match = false;
for ( int i = 0; i < n; ++i ) {
if ( i == n - 1 || arr[i] != arr[i + 1] ) {
if ( match )
match = false;
else
return arr[i];
} else {
match = true;
}
}
return -1; // made up number in case all duplicates
If the two values are equal, then we know that we can't use that value again, so I set match to true. If they are not equal, then if it was already disqualified, I ignore it and set match back to false, otherwise, return that value.
There are more elegant ways to do this; this is just the simplest.

Check whether all the pairs in an array are divisible by k

Given an array of integers and a number k, write a function that returns true if given array can be divided into pairs such that sum of every pair is divisible by k.
This code is producing correct results for all test cases except one I cannot find the glitch in it.
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
int k;
cin >> k;
int flag[n] = {0};
int p = 0;
int q = 0;
if (n % 2 != 0) {
cout << "False" << endl;
} else {
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if ((arr[i] + arr[j]) % k == 0 && flag[j] == 0) {
p = 1;
flag[j] = 1;
}
}
if (p == 0) {
q = 1;
cout << "False" << endl;
break;
}
}
if (q == 0) {
cout << "True" << endl;
}
}
}
return 0;
}
One of the big sources of bugs in code is messy code. So how do we clean up code? We modularize it. This means breaking up the code so that each portion of the code does one job well. Let's see what that looks like.
Function to check if something is divisible by k:
bool isDivisible(int number, int divisor) {
return number % divisor == 0;
}
Function to check all pairs:
The logic is as follows:
Take the first number in the list; call in n0.
For every remaining number n1, check if that plus the first number is divisible by k
When we find n1 such that n0 + n1 is divisible by k,
a. If the remaining numbers left over can also be split into divisible pairs, return true
b. Otherwise, continue searching
4.If we've searched through all the numbers, return false.
bool pairsDivisible(int* nums, int count, int k) {
if(count == 0) return true;
if(count % 2 != 0) return false; // count must be even
// 1.
int n0 = nums[0];
// 2.
for(int i = 1; i < count; i++) {
int n1 = nums[i];
// 3.
if(isDivisible(n0 + n1, k)) {
// Move the ith number so it's now nums[1]
std::swap(nums[1], nums[i]);
if(pairsDivisible(nums + 2, count - 2, k)) {
return true; // 3.a
} else {
// Reset the array
std::swap(nums[1], nums[i]);
}
}
}
return false;
}

Generate numbers from 2 to 10,000. The numbers printed can only be a multiple of 2 prime numbers

Homework: I'm just stumped as hell. I have algorithms set up, but I have no idea how to code this
Just to be clear you do not need arrays or to pass variables by reference.
The purpose of the project is to take a problem apart and using Top-Down_Design or scratch pad method develop the algorithm.
Problem:
Examine the numbers from 2 to 10000. Output the number if it is a Dual_Prime.
I will call a DualPrime a number that is the product of two primes. Ad where the two primes are not equal . So 9 is not a dual prime. 15 is ( 3 * 5 ) .
The output has 10 numbers on each line.
My Algorithm set-up
Step 1: find prime numbers.:
bool Prime_Number(int number)
{
for (int i = 2; i <= sqrt(number); i++)
{
if (number % 1 == 0)
return false;
}
return true;
}
Step 2: store prime numbers in a array
Step 3: Multiply each array to each other
void Multiply_Prime_Numbers(int Array[], int Size)
{
for (int j = 0; j < Size- 1; j++)
{
Dual_Prime[] = Arr[j] * Arr[j + 1]
}
}
Step 4: Bubble sort
void Bubble_Sort(int Array[], int Size) // Sends largest number to the right
{
for (int i = Size - 1; i > 0; i--)
for (int j = 0; j < i; j++)
if (Array[j] > Array[j + 1])
{
int Temp = Array[j + 1];
Array[j + 1] = Array[j];
Array[j] = Temp;
}
}
Step 5: Display New Array by rows of 10
void Print_Array(int Array[], int Size)
{
for (int i = 0; i < Size; i++)
{
cout << Dual_Prime[i] << (((j % 10) == 9) ? '\n' : '\t');
}
cout << endl;
}
I haven't learned dynamic arrays yet,
Although dynamic arrays and the sieve of Eratosthenes are more preferable, I tried to write minimally fixed version of your code.
First, we define following global variables which are used in your original implementation of Multiply_Prime_Numbers.
(Please check this post.)
constexpr int DP_Size_Max = 10000;
int DP_Size = 0;
int Dual_Prime[DP_Size_Max];
Next we fix Prime_Number as follows.
The condition number%1==0 in the original code is not appropriate:
bool Prime_Number(int number)
{
if(number<=1){
return false;
}
for (int i = 2; i*i <= number; i++)
{
if (number % i == 0)
return false;
}
return true;
}
In addition, Multiply_Prime_Numbers should be implemented by double for-loops as follows:
void Multiply_Prime_Numbers(int Array[], int Size)
{
for (int i = 0; i < Size; ++i)
{
for (int j = i+1; j < Size; ++j)
{
Dual_Prime[DP_Size] = Array[i]*Array[j];
if(Dual_Prime[DP_Size] >= DP_Size_Max){
return;
}
++DP_Size;
}
}
}
Then these functions work as follows.
Here's a DEMO of this minimally fixed version.
int main()
{
int prime_numbers[DP_Size_Max];
int size = 0;
for(int j=2; j<DP_Size_Max; ++j)
{
if(Prime_Number(j)){
prime_numbers[size]=j;
++size;
}
}
Multiply_Prime_Numbers(prime_numbers, size);
Bubble_Sort(Dual_Prime, DP_Size);
for(int i=0; i<DP_Size;++i){
std::cout << Dual_Prime[i] << (((i % 10) == 9) ? '\n' : '\t');;
}
std::cout << std::endl;
return 0;
}
The Sieve of Eratosthenes is a known algorithm which speeds up the search of all the primes up to a certain number.
The OP can use it to implement the first steps of their implementation, but they can also adapt it to avoid the sorting step.
Given the list of all primes (up to half the maximum number to examine):
Create an array of bool as big as the range of numbers to be examined.
Multiply each distinct couple of primes, using two nested loops.
If the product is less than 10000 (the maximum) set the corrisponding element of the array to true. Otherwise break out the inner loop.
Once finished, traverse the array and if the value is true, print the corresponding index.
Here there's a proof of concept (implemented without the OP's assignment restrictions).
// Ex10_TwoPrimes.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include "pch.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void Homework_Header(string Title);
void Do_Exercise();
void Sieve_Of_Eratosthenes(int n);
void Generate_Semi_Prime();
bool Semi_Prime(int candidate);
bool prime[5000 + 1];
int main()
{
Do_Exercise();
cin.get();
return 0;
}
void Do_Exercise()
{
int n = 5000;
Sieve_Of_Eratosthenes(n);
cout << endl;
Generate_Semi_Prime();
}
void Sieve_Of_Eratosthenes(int n)
{
// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
memset(prime, true, sizeof(prime));
for (int p = 2; p*p <= n; p++)
{
// If prime[p] is not changed, then it is a prime
if (prime[p] == true)
{
// Update all multiples of p
for (int i = p * p; i <= n; i += p)
prime[i] = false;
}
}
}
bool Semi_Prime(int candidate)
{
for (int index = 2; index <= candidate / 2; index++)
{
if (prime[index])
{
if (candidate % index == 0)
{
int q = candidate / index;
if (prime[q] && q != index)
return true;
}
}
}
return false;
}
void Generate_Semi_Prime()
{
for (int i = 2; i <= 10000; i++)
if (Semi_Prime(i)) cout << i << "\t";
}

Digit-increasing number test

A number is called digit-increasing if it is equal n + nn + nnn + ... for some digit n between 1 and 9. For example 24 is digit-increasing because it equals 2 + 22 (here n = 2).
Actually, a friend of mine asked me this question and i am stuck thinking about it but couldn't find the exact solution so far. Can anyone help ? I needed the function that returns true if it is digit-increasing else false.
There are only relatively few numbers with this property: Within the range of unsigned long long (64 bits), there are only 172 digit-increasing numbers.
Therefore, in terms of a practical solution, it makes sense to pre-compute them all and put them in a hash. Here is Python code for that:
# Auxiliary function that generates
# one of the 'nnnn' elements
def digits(digit,times):
result = 0
for i in range(times):
result += digit*(10**i)
return result
# Pre-computing a hash of digit-increasing
# numbers:
IncDig = {}
for i in range(1,30):
for j in range(1,10):
number = reduce(lambda x,y:x+y,[digits(j,k) for k in range(1,i+1)])
IncDig[number] = None
Then the actual checking function is just a look-up in the hash:
def IncDigCheck(number):
return (number in IncDig)
This is virtually O(1), and the time and space taken for the pre-calculation is minimal, because there are only 9 distinct digits (zero doesn't count), hence only K*9 combinations of type n + nn + ... for a sum of length K.
General representation is:
n + (n*10 + n) + (n*100+n)...
If number look like sum of same digits then any digit can be represented as
(1+111+...) * base_digit
. Assuming this we can use simple algorithm:
bool isDigitIncreasing(const int num)
{
int n = 1;
int sum = 1; //value to increase n
while (n <= num) {
//if num is (111...) * base_digit and base_digit is < 10
if (num % n == 0 && n * 10 > num) return true;
sum = sum * 10 + 1; //N*10+N where n is 1 as was assumed
n += sum; //next step
}
return false;
}
Simple exhaustive search will work.
def is_digit_increasing_number(x):
# n = 1, 1+11, 1+11+111, ...
n = 1
i = 1
while n <= x:
if x % n == 0 and n * 10 > x:
return True
i += 1
n = n * 10 + i
return False
Simplest possible way is do the addition (bottom-up), I'll use simple for loop:
List<int> numbersSum = new List<int>{1,2,3,4,5,6,7,8,9};
List<int> lastNumber = new List<int>{1,2,3,4,5,6,7,8,9};
for(int i=0;i<= lg n + 1;i++)
{
for(int j=0;j<9;j++)
{
if(list[j] < n)
{
var lastNumberJ = lastNumber[j]*10+j+1;
list[j] += lastNumberJ; // add numbers to see will be same as n.
if (list[j] == n)
return j+1;
lastNumber[j] = lastNumberJ;
}
}
}
return -1;
The important part is you just need at most log n iteration and also you can return sooner if all numbers are bigger than given number, this is O(log n) algorithm.
Here is a python code.The basic logic here is that a digit increasing number if divided by a specific number between 1-9 gives a digit increasing number made of only ones.All the digit increasing numbers of 1 follow a specific pattern ie 12345678...
import sys
for n in range(1,10):
a=1
if k%n!=0:
a=0
else:
g=str(k/n)
j=int(g[0])
for i in range(1,len(g)):
if int(g[i])==j+1:
j=int(g[i])
else:
a=0
break
if a==1:
print "Yes,it is a digit increasing number"
sys.exit(0)
print "No,it is not a digit increasing number"
I have done in this way. Check out once.
int sum = 0, count =0;
bool flag = false;
public bool isDigitIncreasing(int input_number)
{
int n= get_number_of_digit(input_number); // Gets number of digits
int sum = 0;
for(int i=0;i<n;i++)
{
sum = sum*10+1;
count = count + sum;
}
for(int i=1; i<=9;i++)
{
if((input_number)==count*i)
{
flag = true;
break;
}
else
flag = false;
}
return flag;
}
public int get_number_of_digit(int num)
{
int size = 0;
do
{
num = num/10;
size++;
}while(num>0);
return size;
}
Here is the shortest solution
public static int isDigitIncreasing (int n)
{
if(n<10)
{
return 1;
}
for(int i=1;i<=9;i++)
{
int tempsum=i;
int previous=i;
while(tempsum<=n)
{
previous=previous*10 + i;
tempsum=tempsum + previous;
if(tempsum==n)
{
return 1;
}
}
}
return 0;
}
Ambiguitiy: Are the values 1-9 repeating for themselves? (too lazy to google this myself)
If 1-9 are repeating then following should work. If not, and you want the code to work only on values > 10 then you can initialize mult with 10.
int i, mult = 1, result, flag;
for( i=1; i<9; i++ )
{
flag = 0;
while( result < TARGET )
{
result = result+(i*mult);
mult = mult*10;
if( result == TARGET )
{
flag = 1;
break;
}
}
if( flag == 1 )
break;
}
After execution, i must contain the values for which RESULT is a repeating number IF the flag is 1. If flag is zero after execution then the TARGET isn't a repeating number.
I wonder if its possible that a number could be repeating for multiple values, just curious.
Here num is the number and n is the digit
#include<stdio.h>
int f(int num,int n)
{
int d=n;
while(num>0)
{
num-=n;
n=d+n*10;
}
if(num==0)
return 1;
else
return 0;
}
int main()
{
int num;
int n;
int flag;
printf("Enter the number :");
scanf("%d",&num);
printf("Enter the digit :");
scanf("%d",&n);
flag = f(num,n);
if(flag == 1)
printf("It's in n+nn+nnn+...\n");
if(flag ==0)
printf("It's not\n");
return 0;
}
Let d(k) be 1+11+111+...+(11...11) where the last number has k digits. Then d(1)=1, and d(k+1)=10d(k)+k+1.
We want to test if d(k)*i = n, for some k, and for some i=1..9.
If we've computed d(k), then i (if it exists) must be n/d(k). We can check if n/d(k) is correct, by comparing n with ((n/d(k))%10)*d(k). The %10 makes the test fail if i is larger than 9.
This gives us a relatively terse solution: compute subsequent d(k) until they are bigger than n, and at each point check to see if n is a digit-multiple of d(k).
Here's a very lightly code-golfed implementation of that idea:
#include <stdio.h>
int is_digit_increasing(int n) {
for(int d=1,k=1;d<=n;d=d*10+ ++k)if(n==(n/d)%10*d)return 1;
return 0;
}
int main(int argc, char**argv) {
for (int i=0; i<10000; i++) {
if (is_digit_increasing(i)) {
printf("%d\n", i);
}
}
return 0;
}
// Example program
#include <iostream>
#include <string>
int isDigitIncreasingNo(int n) {
if(n<=0)
return 0;
int len = std::to_string(n).length();
int vector1 = 0;
int vector2 = 0;
for(int i=1;i<=len;i++)
vector2 = (vector2*10)+i;
vector1 = vector2/10;
if(n % vector2 == 0 && (n / vector2)<=9 )
return 1;
if(n % vector1 == 0 && (n / vector1)<=9 )
return 1;
return 0;
}
int main()
{
for (int i=0; i<10000000; i++) {
if (isDigitIncreasingNo(i)) {
printf("%d\n", i);
}
}
return 0;
}
public boolean isDigitIncreasing(int number)
{
int sum;
int size=calculateNumberOfDigits(number);
for(int i=1;i<=9;i++)
{
sum=0;
int temp=size;
while(temp>=1)
{
for(int j=temp;j<=1;j--)
{
sum=sum+i*(int)Math.pow(10,j-1);
}
temp--;
}
if(sum==number)
{
return true;//Its a digit increasing
}
}
return false;
}
public int calculateNumberOfDigits(int number)
{
int size=0;
do
{
number=number/10;
size++;
}while(size>0);
return size;
}