Products that equal a sum and vice versa
C (gcc), n = 50000000 with 6499 results in 59 s
To avoid producing over a terabyte of output consisting almost entirely of 1s, a sequence of (say) 49999995 1s is abbreviated as 1x49999995
.
#include <stdio.h>
#include <stdlib.h>
static int n, *a1, k1 = 0, *a2, k2 = 0, s1, p1, *factor;
static void out() {
if (s1 == p1) {
for (int i = 0; i < k1 && i < k2; i++) {
if (a1[i] < a2[i])
return;
else if (a1[i] > a2[i])
break;
}
}
for (int i = 0; i < k1; i++)
printf("%d ", a1[i]);
printf("1x%d | ", n - k1);
for (int i = 0; i < k2; i++)
printf("%d ", a2[i]);
printf("1x%d\n", n - k2);
}
static void gen2(int p, int s, int m);
static void gen3(int p, int s, int m, int x, int q) {
int r = s - n + k2 + 2;
int d = factor[q];
do {
if (x * d <= m)
x *= d;
q /= d;
} while (q % d == 0);
do {
if (q == 1) {
a2[k2++] = x;
gen2(p / x, s - x, x);
k2--;
} else {
gen3(p, s, m, x, q);
}
if (x % d != 0)
break;
x /= d;
} while (p / (x * q) >= r - x * q);
}
static void gen2(int p, int s, int m) {
int n2 = n - k2;
if (p == 1) {
if (s == n2)
out();
} else if (n2 >= 1 && m > 1) {
int r = s - n2 + 1;
if (r < 2 || p < r)
return;
if (m > r)
m = r;
if (factor[p] <= m)
gen3(p, s, m, 1, p);
}
}
static void gen1(int p, int s, int m) {
int n1 = n - k1;
p1 = p;
s1 = s + n1;
gen2(s1, p1, s + n1 + 1 - n);
if (n1 != 0) {
int *p1 = &a1[k1++];
for (int x = 2; x <= m && p * x <= s + x + n1 - 1; x++) {
*p1 = x;
gen1(p * x, s + x, x);
}
k1--;
}
}
int main(int argc, char **argv) {
if (argc < 2)
return 1;
n = atoi(argv[1]);
if (n < 2)
return 1;
a1 = malloc(n * sizeof(int));
a2 = malloc(n * sizeof(int));
factor = calloc(4 * n - 1, sizeof(int));
for (int p = 2; p < 4 * n - 1; p++)
if (factor[p] == 0) {
factor[p] = p;
for (int i = p; i <= (4 * n - 2) / p; i++)
factor[p * i] = p;
} else if (factor[p] < factor[p / factor[p]]) {
factor[p] = factor[p / factor[p]];
}
gen1(1, 0, 3 * n - 1);
return 0;
}
Try it online!
Mathematica, n=293 with 12 solutions
OP changed the challenge and asks for input
Here is the new code that takes any n as input
For n=293 you get the 12 solutions
If[#<5,Union[Sort/@Select[Tuples[{1,2,3,4,5,6,7,8,9},{#}],Tr@#==Times@@#&]],For[a=1,a<3,a++,For[b=a,b<3,b++,For[c=b,c<5,c++,For[d=c,d<10,d++,For[e=d,e<300,e++,If[Tr[s=Join[Table[1,#-5],{a,b,c,d,e}]]==Times@@s,Print[s]]]]]]]]&
input
[n]
You can test this algorithm on Wolfram Sandbox which is an online freely available software
Just follow the link, paste the code (ctrl+v),paste input at the end of the code and press shift+enter to run.
You will get all my solutions in seconds
Here is also Try it online! in C++(gcc)
(Many thanks to @ThePirateBay for supporting and translating my code to a free language)
this program generates only solutions of the form {a,b,c}{a,b,c}
which means a+b+c=a*b*c
It takes 1 sec to compute
the twelve solutions are:
{1,1...,1,1,1,2,293} {1,1...,1,1,1,2,293}
{1,1...,1,1,1,3,147} {1,1...,1,1,1,3,147}
{1,1...,1,1,1,5,74} {1,1...,1,1,1,5,74}
{1,1...,1,1,2,2,98} {1,1...,1,1,2,2,98}
{1,1...,1,1,2,3,59} {1,1...,1,1,2,3,59}
{1,1...,1,1,2,5,33} {1,1...,1,1,2,5,33}
{1,1...,1,1,2,7,23} {1,1...,1,1,2,7,23}
{1,1...,1,1,2,8,20} {1,1...,1,1,2,8,20}
{1,1...,1,1,3,3,37} {1,1...,1,1,3,3,37}
{1,1...,1,1,3,4,27} {1,1...,1,1,3,4,27}
{1,1...,1,1,3,7,15} {1,1...,1,1,3,7,15}
{1,1...,1,2,2,6,13} {1,1...,1,2,2,6,13}
Python 2, n=175, 28 results in 59s
Made it a little slower using a reduction factor 2, but gets more solutions starting with n=83
I get results for n up to 92 on TIO in a single run.
def submats(n, r):
if n == r:
return [[]]
elif r > 6:
base = 1
else:
base = 2
mx = max(base, int(n*2**(1-r)))
mats = []
subs = submats(n, r+1)
for m in subs:
if m:
mn = m[-1]
else:
mn = 1
for i in range(mn, mx + 1):
if i * mn < 3*n:
mats += [m + [i]]
return mats
def mats(n):
subs = []
for sub in submats(n, 0):
sum = 0
prod = 1
for m in sub:
sum += m
prod *= m
if prod > n and prod < n*3:
subs += [[sub, sum, prod]]
return subs
def sols(n):
mat = mats(n)
sol = [
[[1]*(n-1)+[3*n-1],[1]*(n-2)+[2,2*n-1]],
]
if n > 2:
sol += [[[1]*(n-1)+[2*n+1],[1]*(n-2)+[3,n]]]
for first in mat:
for second in mat:
if first[2] == second[1] and first[1] == second[2] and [second[0], first[0]] not in sol:
sol += [[first[0], second[0]]];
return sol
Try it online!