Related
Question:
Given 2 integers N and M. Convert a number N to M using minimum number of given operations.
The operations are:
Square N (N = N^2)
Divide N by a prime integer P if N is divisible by P (N = N / P and N % P == 0)
Contrants:
N, M <= 10^9
Example:
N = 12, M = 18
The minimum operations are:
N /= 2 -> N = 6
N = N^2 -> N = 36
N /= 2 -> N = 18
My take:
I'm trying to use BFS to solve this problem. For each number, the available edges to other numberers are the operations. But it got Time Limit Exceeded. Is there any better way to solve this?
Here is my BFS code:
queue<pair<int,int> > q;
vector<long long> pr;
ll m,n;
bool prime[MAXN+1];
void solve()
{
while (!q.empty())
{
pii x=q.front();
q.pop();
if (x.first==m)
{
cout << x.second;
return;
}
if (x.first==1) continue;
for(ll k:pr)
{
if (k>x.first) break;
if (x.first%k==0) q.push({x.first/k,x.second+1});
}
q.push({x.first*x.first,x.second+1});
}
}
The algorithm uses the decomposition on N and M in prime factors, keeping trace of the corresponding exponents.
If M has a prime factor that N does not have, there is no solution (the code returns -1).
If N has some prime factors that M doesn't have, then the first step is to divide N by these primes.
The corresponding number of operations is the sum of the corresponding exponents.
At this stage, we get two arrays A and B corresponding to the exponents of the common prime factors, for N and M.
It is worth noting that at this stage, the values of the primes involved is not relevant anymore, only the exponents matter.
Then one must determine the minimum number of squares (= multiplications by 2 of the exponents).
The is the smallest k such that A[i] >= 2^k B[i] for all indices i.
The number of multiplications is added to the number of operations only once, as all exponents are multiplied by 2 at the same time.
Last step is to determine, for each pair (a, b) = (A[i], B[i]), the number of subtractions needed to go from a to b, while implementing exactly k multiplications by 2. This is performed with the following rules:
- if (k == 0) f(a, b, k) = a-b
- Else:
- if ((a-1)*2^k >= b: f(a, b, k) = 1 + f(a-1, b, k)
- else: f(a, b, k) = f(2*a, b, k-1)
The complexity is dominated by the decomposition in primes factors: O(sqrt(n))
Code:
This code is rather long, but a great part consists if helper routines needed for debugging and analysis.
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
void print (const std::vector<int> &v, const std::string s = "") {
std::cout << s;
for (auto &x: v) {
std::cout << x << " ";
}
std::cout << std::endl;
}
void print_decomp (int n, const std::vector<int> &primes, const std::vector<int> &mult) {
std::cout << n << " = ";
int k = primes.size();
for (int i = 0; i < k; ++i) {
std::cout << primes[i];
if (mult[i] > 1) std::cout << "^" << mult[i];
std::cout << " ";
}
std::cout << "\n";
}
void prime_decomp (int nn, std::vector<int> &primes, std::vector<int> &mult) {
int n = nn;
if (n <= 1) return;
if (n % 2 == 0) {
primes.push_back(2);
int cpt = 1;
n/= 2;
while (n%2 == 0) {n /= 2; cpt++;}
mult.push_back (cpt);
}
int max_prime = sqrt(n);
int p = 3;
while (p <= max_prime) {
if (n % p == 0) {
primes.push_back(p);
int cpt = 1;
n/= p;
while (n%p == 0) {n /= p; cpt++;}
mult.push_back (cpt);
max_prime = sqrt(n);
}
p += 2;
}
if (n != 1) {
primes.push_back(n);
mult.push_back (1);
}
print_decomp (nn, primes, mult);
}
// Determine the number of subtractions to go from a to b, with exactly k multiplications by 2
int n_sub (int a, int b, int k, int power2) {
if (k == 0){
if (b > a) exit(1);
return a - b;
}
//if (a == 1) return n_sub (2*a, b, k-1, power2/2);
if ((a-1)*power2 >= b) {
return 1 + n_sub(a-1, b, k, power2);
} else {
return n_sub (2*a, b, k-1, power2/2);
}
return 0;
}
// A return of -1 means no possibility
int n_operations (int N, int M) {
int count = 0;
if (N == M) return 0;
if (N == 1) return -1;
std::vector<int> primes_N, primes_M, expon_N, expon_M;
// Prime decomposition
prime_decomp(N, primes_N, expon_N);
prime_decomp (M, primes_M, expon_M);
// Compare decomposition, check if a solution can exist, set up two exponent arrays
std::vector<int> A, B;
int index_A = 0, index_B = 0;
int nA = primes_N.size();
int nB = primes_M.size();
while (true) {
if ((index_A == nA) && (index_B == nB)) {
break;
}
if ((index_A < nA) && (index_B < nB)) {
if (primes_N[index_A] == primes_M[index_B]) {
A.push_back(expon_N[index_A]);
B.push_back(expon_M[index_B]);
index_A++; index_B++;
continue;
}
if (primes_N[index_A] < primes_M[index_B]) {
count += expon_N[index_A];
index_A++;
continue;
}
return -1; // M has a prime that N doesn't have: impossibility to go to M
}
if (index_B != nB) { // impossibility
return -1;
}
for (int i = index_A; i < nA; ++i) {
count += expon_N[i]; // suppression of primes in N not in M
}
break;
}
std::cout << "1st step, count = " << count << "\n";
print (A, "exponents of N: ");
print (B, "exponents of M: ");
// Determination of the number of multiplications by two of the exponents (= number of squares)
int n = A.size();
int n_mult2 = 0;
int power2 = 1;
for (int i = 0; i < n; ++i) {
while (power2*A[i] < B[i]) {
power2 *= 2;
n_mult2++;
}
}
count += n_mult2;
std::cout << "number of squares = " << n_mult2 << " -> " << power2 << "\n";
// For each pair of exponent, determine the number of subtractions,
// with a fixed number of multiplication by 2
for (int i = 0; i < n; ++i) {
count += n_sub (A[i], B[i], n_mult2, power2);
}
return count;
}
int main() {
int N, M;
std::cin >> N >> M;
auto ans = n_operations (N, M);
std::cout << ans << "\n";
return 0;
}
I search everywhere on the internet for the best case time complexity of selection sort that is o(n^2). But i write and tested this below code of selection sort that can work in O(n) for best case (that is array is already sorted). Please find the mistake in this program
This is my code:
#include <bits/stdc++.h>
using namespace std;
/* Function to print an array */
void printArray(int arr[], int size)
{
int i;
for (i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
void selectionSort(int arr[], int n)
{
int i, j, max_idx;
// One by one move boundary of unsorted subarray
for (i = 0; i < n - 1; i++)
{
cout << endl;
printArray(arr, n);
// Find the minimum element in unsorted array
max_idx = 0;
int count = 0;
for (j = 1; j < n - i; j++)
{
if (arr[j] >= arr[max_idx])
{
max_idx = j;
count++;
}
}
if (count != n - i - 1)
{ //swap only if not already sorted
// Swap the found minimum element with the first element
swap(&arr[max_idx], &arr[n - i - 1]);
}
else //already Sorted so returning
{
return;
}
//cout << "Sorted array: \n";
printArray(arr, n);
}
}
// Driver program to test above functions
int main()
{
int arr[] = {2, 1, 4, 3, 6, 5, 8, 7};
int n = sizeof(arr) / sizeof(arr[0]);
selectionSort(arr, n);
cout << "Sorted array: \n";
printArray(arr, n);
return 0;
}
// This is code is contributed by www.bhattiacademy.com
Yes, your algorithm has a best case running time of Θ(n), because if the array is already in ascending order then count will equal n - 1 on the first iteration of the outer loop, so the algorithm will terminate early.
Your algorithm is different to the standard selection sort algorithm, which looks like this:
for(int i = 0; i < n - 1; i++) {
int min_idx = i;
for(int j = i + 1; j < n; j++) {
if(arr[j] < arr[min_idx]) {
min_idx = j;
}
}
swap(&arr[i], &arr[min_idx]);
}
The selection sort algorithm iteratively searches for the minimum remaining element and swaps it into place. This doesn't create an opportunity to detect that the array is already in increasing order, so there's no opportunity to terminate early, and selection sort's best case running time is therefore Θ(n2).
Selection Sort: Idea Given an array of n items
1.Find the largest item x, in the range of [0…n−1]
2.Swap x with the (n−1)th item
3.Reduce n by 1 and go to Step 1
Selection sort function you can use following algorithm has hint to write the code:
competitive programming noob here. I've been trying to solve this question:
http://www.usaco.org/index.php?page=viewproblem2&cpid=646
The code I wrote only works with the first test case, and gives a Memory Limit Exceed error -- or ('!') for the rest of the test cases.
This is my code (accidently mixed up M and N):
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
using std::vector;
vector<int> check;
vector< vector<int> > A;
void dfs(int node)
{
check[node] = 1;
int siz = A[node].size();
for (int i = 0; i < siz; i++)
{
int y = A[node][i];
if (check[y] == 0)
{
dfs(y);
}
}
}
bool connected(vector<int> C)
{
for (int i = 1; i <= C.size() - 1; i++)
{
if (C[i] == 0)
{
return false;
}
}
return true;
}
int main()
{
freopen("closing.in", "r", stdin);
freopen("closing.out", "w", stdout);
ios_base::sync_with_stdio(false);
int M, N;
cin >> M >> N;
check.resize(M + 1);
A.resize(M + 1);
for (int i = 0; i < N; i++)
{
int u, v;
cin >> u >> v;
A[u].push_back(v); A[v].push_back(u);
}
dfs(1);
if (!connected(check)) {
cout << "NO" << "\n";
}
else {
cout << "YES" << "\n";
}
fill(check.begin(), check.end(), 0);
for (int j = 1; j < M; j++)
{
int node;
bool con = true;
cin >> node;
check[node] = -1;
for (int x = 1; x <= N; x++)
{
if (check[x] == 0)
{
dfs(x);
break;
}
}
if (!connected(check)) {
cout << "NO" << "\n";
}
else {
cout << "YES" << "\n";
}
for (int g = 1; g <= M; g++)
{
if (check[g] == 1)
{
check[g] = 0;
}
}
}
return 0;
}
basically,
void dfs(int node) searches through the bidirectional graph starting from node until it reaches a dead end, and for each node that is visited, check[node] will become 1.
(if visited -> 1, not visited -> 0, turned off -> -1).
bool connected(vector C) will take the check vector and see if there are any nodes that weren't visited. if this function returns true, it means that the graph is connected, and false if otherwise.
In the main function,
1) I save the bidirectional graph given in the task as an Adjacency list.
2) dfs through it first to see if the graph is initially connected (then print "Yes" or "NO") then reset check
3) from 1 to M, I take the input value of which barn would be closed, check[the input value] = -1, and dfs through it. After that, I reset the check vector, but keeping the -1 values so that those barns would be unavailable for the next loops of dfs.
I guess my algorithm makes sense, but why would this give an MLE, and how could I improve my solution? I really can't figure out why my code is giving MLEs.
Thanks so much!
Your DFS is taking huge load of stacks and thus causing MLE
Try to implement it with BFS which uses queue. Try to keep the queue as global rather than local.
Your approach will give you Time Limit Exceeded verdict. Try to solve it more efficiently. Say O(n).
Given an integer x and a sorted array a of N distinct integers, design a linear-time algorithm to determine if there exists two distinct indices i and j such that a[i] + a[j] == x
This is type of Subset sum problem
Here is my solution. I don't know if it was known earlier or not. Imagine 3D plot of function of two variables i and j:
sum(i,j) = a[i]+a[j]
For every i there is such j that a[i]+a[j] is closest to x. All these (i,j) pairs form closest-to-x line. We just need to walk along this line and look for a[i]+a[j] == x:
int i = 0;
int j = lower_bound(a.begin(), a.end(), x) - a.begin();
while (j >= 0 && j < a.size() && i < a.size()) {
int sum = a[i]+a[j];
if (sum == x) {
cout << "found: " << i << " " << j << endl;
return;
}
if (sum > x) j--;
else i++;
if (i > j) break;
}
cout << " not found\n";
Complexity: O(n)
think in terms of complements.
iterate over the list, figure out for each item what the number needed to get to X for that number is. stick number and complement into hash. while iterating check to see if number or its complement is in hash. if so, found.
edit: and as I have some time, some pseudo'ish code.
boolean find(int[] array, int x) {
HashSet<Integer> s = new HashSet<Integer>();
for(int i = 0; i < array.length; i++) {
if (s.contains(array[i]) || s.contains(x-array[i])) {
return true;
}
s.add(array[i]);
s.add(x-array[i]);
}
return false;
}
Given that the array is sorted (WLOG in descending order), we can do the following:
Algorithm A_1:
We are given (a_1,...,a_n,m), a_1<...,<a_n.
Put a pointer at the top of the list and one at the bottom.
Compute the sum where both pointers are.
If the sum is greater than m, move the above pointer down.
If the sum is less than m, move the lower pointer up.
If a pointer is on the other (here we assume each number can be employed only once), report unsat.
Otherwise, (an equivalent sum will be found), report sat.
It is clear that this is O(n) since the maximum number of sums computed is exactly n. The proof of correctness is left as an exercise.
This is merely a subroutine of the Horowitz and Sahni (1974) algorithm for SUBSET-SUM. (However, note that almost all general purpose SS algorithms contain such a routine, Schroeppel, Shamir (1981), Howgrave-Graham_Joux (2010), Becker-Joux (2011).)
If we were given an unordered list, implementing this algorithm would be O(nlogn) since we could sort the list using Mergesort, then apply A_1.
First pass search for the first value that is > ceil(x/2). Lets call this value L.
From index of L, search backwards till you find the other operand that matches the sum.
It is 2*n ~ O(n)
This we can extend to binary search.
Search for an element using binary search such that we find L, such that L is min(elements in a > ceil(x/2)).
Do the same for R, but now with L as the max size of searchable elements in the array.
This approach is 2*log(n).
Here's a python version using Dictionary data structure and number complement. This has linear running time(Order of N: O(N)):
def twoSum(N, x):
dict = {}
for i in range(len(N)):
complement = x - N[i]
if complement in dict:
return True
dict[N[i]] = i
return False
# Test
print twoSum([2, 7, 11, 15], 9) # True
print twoSum([2, 7, 11, 15], 3) # False
Iterate over the array and save the qualified numbers and their indices into the map. The time complexity of this algorithm is O(n).
vector<int> twoSum(vector<int> &numbers, int target) {
map<int, int> summap;
vector<int> result;
for (int i = 0; i < numbers.size(); i++) {
summap[numbers[i]] = i;
}
for (int i = 0; i < numbers.size(); i++) {
int searched = target - numbers[i];
if (summap.find(searched) != summap.end()) {
result.push_back(i + 1);
result.push_back(summap[searched] + 1);
break;
}
}
return result;
}
I would just add the difference to a HashSet<T> like this:
public static bool Find(int[] array, int toReach)
{
HashSet<int> hashSet = new HashSet<int>();
foreach (int current in array)
{
if (hashSet.Contains(current))
{
return true;
}
hashSet.Add(toReach - current);
}
return false;
}
Note: The code is mine but the test file was not. Also, this idea for the hash function comes from various readings on the net.
An implementation in Scala. It uses a hashMap and a custom (yet simple) mapping for the values. I agree that it does not makes use of the sorted nature of the initial array.
The hash function
I fix the bucket size by dividing each value by 10000. That number could vary, depending on the size you want for the buckets, which can be made optimal depending on the input range.
So for example, key 1 is responsible for all the integers from 1 to 9.
Impact on search scope
What that means, is that for a current value n, for which you're looking to find a complement c such as n + c = x (x being the element you're trying ton find a 2-SUM of), there is only 3 possibles buckets in which the complement can be:
-key
-key + 1
-key - 1
Let's say that your numbers are in a file of the following form:
0
1
10
10
-10
10000
-10000
10001
9999
-10001
-9999
10000
5000
5000
-5000
-1
1000
2000
-1000
-2000
Here's the implementation in Scala
import scala.collection.mutable
import scala.io.Source
object TwoSumRed {
val usage = """
Usage: scala TwoSumRed.scala [filename]
"""
def main(args: Array[String]) {
val carte = createMap(args) match {
case None => return
case Some(m) => m
}
var t: Int = 1
carte.foreach {
case (bucket, values) => {
var toCheck: Array[Long] = Array[Long]()
if (carte.contains(-bucket)) {
toCheck = toCheck ++: carte(-bucket)
}
if (carte.contains(-bucket - 1)) {
toCheck = toCheck ++: carte(-bucket - 1)
}
if (carte.contains(-bucket + 1)) {
toCheck = toCheck ++: carte(-bucket + 1)
}
values.foreach { v =>
toCheck.foreach { c =>
if ((c + v) == t) {
println(s"$c and $v forms a 2-sum for $t")
return
}
}
}
}
}
}
def createMap(args: Array[String]): Option[mutable.HashMap[Int, Array[Long]]] = {
var carte: mutable.HashMap[Int,Array[Long]] = mutable.HashMap[Int,Array[Long]]()
if (args.length == 1) {
val filename = args.toList(0)
val lines: List[Long] = Source.fromFile(filename).getLines().map(_.toLong).toList
lines.foreach { l =>
val idx: Int = math.floor(l / 10000).toInt
if (carte.contains(idx)) {
carte(idx) = carte(idx) :+ l
} else {
carte += (idx -> Array[Long](l))
}
}
Some(carte)
} else {
println(usage)
None
}
}
}
int[] b = new int[N];
for (int i = 0; i < N; i++)
{
b[i] = x - a[N -1 - i];
}
for (int i = 0, j = 0; i < N && j < N;)
if(a[i] == b[j])
{
cout << "found";
return;
} else if(a[i] < b[j])
i++;
else
j++;
cout << "not found";
Here is a linear time complexity solution O(n) time O(1) space
public void twoSum(int[] arr){
if(arr.length < 2) return;
int max = arr[0] + arr[1];
int bigger = Math.max(arr[0], arr[1]);
int smaller = Math.min(arr[0], arr[1]);
int biggerIndex = 0;
int smallerIndex = 0;
for(int i = 2 ; i < arr.length ; i++){
if(arr[i] + bigger <= max){ continue;}
else{
if(arr[i] > bigger){
smaller = bigger;
bigger = arr[i];
biggerIndex = i;
}else if(arr[i] > smaller)
{
smaller = arr[i];
smallerIndex = i;
}
max = bigger + smaller;
}
}
System.out.println("Biggest sum is: " + max + "with indices ["+biggerIndex+","+smallerIndex+"]");
}
Solution
We need array to store the indices
Check if the array is empty or contains less than 2 elements
Define the start and the end point of the array
Iterate till condition is met
Check if the sum is equal to the target. If yes get the indices.
If condition is not met then traverse left or right based on the sum value
Traverse to the right
Traverse to the left
For more info :[http://www.prathapkudupublog.com/2017/05/two-sum-ii-input-array-is-sorted.html
Credit to leonid
His solution in java, if you want to give it a shot
I removed the return, so if the array is sorted, but DOES allow duplicates, it still gives pairs
static boolean cpp(int[] a, int x) {
int i = 0;
int j = a.length - 1;
while (j >= 0 && j < a.length && i < a.length) {
int sum = a[i] + a[j];
if (sum == x) {
System.out.printf("found %s, %s \n", i, j);
// return true;
}
if (sum > x) j--;
else i++;
if (i > j) break;
}
System.out.println("not found");
return false;
}
The classic linear time two-pointer solution does not require hashing so can solve related problems such as approximate sum (find closest pair sum to target).
First, a simple n log n solution: walk through array elements a[i], and use binary search to find the best a[j].
To get rid of the log factor, use the following observation: as the list is sorted, iterating through indices i gives a[i] is increasing, so any corresponding a[j] is decreasing in value and in index j. This gives the two-pointer solution: start with indices lo = 0, hi = N-1 (pointing to a[0] and a[N-1]). For a[0], find the best a[hi] by decreasing hi. Then increment lo and for each a[lo], decrease hi until a[lo] + a[hi] is the best. The algorithm can stop when it reaches lo == hi.
I am looking for solution for :
Given a array and a number P , find two numbers in array whose product equals P.
Looking for solution better than O(n*2) . I am okay with using extra space or other datastructure .Any help is appreciated ?
Make a pass through the array, and add the elements to a Hashtable. For each element x added, check whether P/x already exists in the Hashtable - if it does then x and P/x is one of your solutions. This'd be about as optimal as you'll get.
You can try a sliding window approach. First sort all the numbers increasingly, and then use two integers begin and end to index the current pair of numbers. Initialize begin to 0 and end to the last position. Then compare the product of v[begin] and v[end] with P:
If it is equal, you found the answer.
If it is lower, you must find a bigger product, move begin forward.
If it is higher, you must find a smaller product, move end backward.
Here is a C++ code with this idea implemented. This solution is O(n*log(n)) because of the sorting, if you can assume the data is sorted then you can skip the sorting for an O(n) solution.
pair<int, int> GetProductPair(vector<int>& v, int P) {
sort(v.begin(), v.end());
int begin = 0, end = static_cast<int>(v.size()) - 1;
while (begin < end) {
const int prod = v[begin] * v[end];
if (prod == P) return make_pair(begin, end);
if (prod < P) ++begin;
else --end;
}
return make_pair(-1, -1);
}
This one would work only for integers:
Decompose P as product of prime numbers. By dividing these in two groups you can obtain the pairs that gives P as product. Now you just have to check both of them are present in the array, this is where a hash table would be very useful. Also, while creating the hash table, you could also filter the array of repeating values, values that are greater than P, or even values that have prime factors not contained in P.
Create a hash that will be populated in the steps below.
Iterate over the elements of the array one by one. Say current element is n
If the number P is exactly divisible by n
check if n is one of the values of the hash. If yes then that key, value are the two numbers that we are looking for and we can break.
if n is not in the values of the hash then add n,x in a hash where n*x = P
If the number P is not exactly divisible by n then continue with next element of array
If we reach end of the array then there are no such two numbers in the array whose product is P
This algo is of O(n)
1.sort the numbers into an array A, removing any zeroes, in O(nlogn) time
2.create an array B such that B[i] = P/A[I] in O(n) time
3.for every B[k] in B, do a binary search in A for that element, takes O(nlogn) time in the worst case
if the element B[k] exists in the array A at position m, then A[k] * A[m] = P
otherwise no such pair exists
the total running time is O(nlogn)
Of course this may run into difficulties on a real machine due to floating point error
public boolean factors_Of_Product_In_Array(int a[],int product,int factorsLimit)
{
int i = 0,count = 0;
boolean flag = false;
if(factorsLimit==0)
flag = false;
//If product value is zero - only verify if there is any '0' value in array
else if(product==0)
{
for(i=0;i<a.length;i++)
{
if(a[i]==0)
flag = true;
}
}
//If product value is 1 - Verify at least factorsLimit number of 1's should be present in array
else if(product==1)
{
for(i=0;i<a.length;i++)
{
if(a[i]==0)
count=count+1;
}
if(count==factorsLimit)//Verifying if the number of 1's is equal to number of factors required
flag = true;
}
else
{
for(i=0; i<a.length && count!=factorsLimit ;i++)
{
if(product%a[i]==0)
{
product = product/a[i];
count = count+1;
System.out.println(" "+a[i]+" ");
}
}
if(count==factorsLimit)
flag = true;
}
return flag;
}
Updated to provide the implementation.
O(n+P) solution, ignoring the case of P equal to 0.
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
int main(){
auto arr = new vector<int>();
int P, numOfEle, ele;
cout << "The number of elements to be entered: " << endl;
cin >> numOfEle;
cout << "Please enter the elements: " << endl;
for (int i = 0; i < numOfEle; i++){
cin >> ele;
arr->push_back(ele);
}
cout << "Please enter P: " << endl;
cin >> P;
//O(n+P) solution, ignoring the case of P equal to 0
bool* factorsInNeed = new bool[P];
for (int i = 0; i < P; i++)
factorsInNeed[i] = false;
for (auto i : *arr){
if (i != 0 && P/(double)i == P/i){ //if divisble
if (factorsInNeed[i]){
cout << "A solution: " << i << " & " << P/i << endl;
break;
}
factorsInNeed[P/i] = true;
}
}
}
Here's my shot, it only compares any factors with each other once
P <- The Number
theArray <- new array[theData]
factors <- new array[]
isFactor <- new map(init: false)
factorCount <- 0
i <- 0
while i is in theArray
num <- theArray[i]
if (isFactor[num])
skip
if num modulo P == 0
isFactor[num] <- true
j <- 0
while j is in factors
if factors[j] * num == P
return (num, factors[j])
j++
factors.push(num)
factorCount++
i++
Not sure if this is the best solution but it works. you can try and optimize it.
public class CombInput
{
public int ID;
public string Value;
}
public List<string> GetCombinations(List<string> values)
{
List<CombInput> input = new List<CombInput>();
List<string> outputvalues = new List<string>();
int counter = 1;
foreach (String c in values)
{
input.Add(new CombInput { ID = counter, Value = c });
counter++;
}
var Output = from i in input
select i;
string Final = Output.Select(query => query.Value).Aggregate((a, b) => a + "|" + b);
while (!Output.ToList().Exists(s=>s.Value.ToString()==Final))
{
var store = Output;
var Output1=
(from o in Output
from v in input
where (v.ID < o.ID && !(store.Any(a=>a.Value==v.Value + "|" + o.Value)))
select new CombInput { ID = v.ID, Value = v.Value + "|" + o.Value });
var Outputx = (from s in store select s)
.Concat
(from s in Output1.ToList() select s);
Output = Outputx;
}
foreach (var v in Output)
outputvalues.Add(v.Value);
return outputvalues.ToList();
}
public List<string> GetProductCombinations(List<int> nums, int productCriteria)
{
List<string> input = (from i in nums
select i.ToString()).ToList();
input = GetCombinations(input);
var O = from i in input
where i.Split('|').ToList().Select(x => Convert.ToInt32(x)).ToList().Aggregate((a, b) => a * b) == productCriteria
select i;
List<string> output=new List<string>();
foreach (string o in O)
{
output.Add(o);
}
return output;
}
private void button1_Click(object sender, EventArgs e)
{
List<string> output = new List<string>();
List<int> nums = new List<int>();
int[] numsarr ={1,2,3,4,6,7,8,12};
nums = numsarr.ToList();
output = GetProductCombinations(nums, 12);
}
void PrintPairOfProduct(int arr[],int size,int k)
{
int i,temp[MAX];
memset(temp,1,MAX);
for(i=0;i<size;++i)
{
if(k % arr[i] == 0 && temp[arr[i]] != -1 && temp[k/arr[i]] != -1)
{
if((temp[k/arr[i]] * arr[i]) == k)
{
printf("Product of %d * %d = %d",k/arr[i],arr[i],k);``
temp[k/arr[i]] = -1;
temp[arr[i]] = -1;
}
temp[arr[i]] = arr[i];
}}
#include<stdio.h>
int main()
{
int arr[]={2,15,4,5,6,7};
const int c = 30;
int i = 0,j=1;
int num =0;
while ( i<= 6 )
{
num = arr[i] * arr[j];
if ( num == 30)
{
printf("Pairs[%d,%d]\t",arr[i],arr[j]);
}
if (j == 5 )
{
i = i+1;
j = i + 1;
if (j==6)
{
break;
}
else
{
continue;
}
}
j= j+1;
}
return 0;
}