Các sản phẩm bằng một tổng và ngược lại


22

Một cặp tương đương thú vị là 1 + 5 = 2 · 31 · 5 = 2 + 3 . Có nhiều cái như thế này, một cái khác là 1 + 1 + 8 = 1 · 2 · 51 · 1 · 8 = 1 + 2 + 5 . Nói chung, tích của n số nguyên dương bằng tổng n số nguyên dương và ngược lại.

Trong thử thách này, bạn phải tạo ra tất cả các kết hợp số nguyên dương như vậy cho đầu vào n> 1 , không bao gồm hoán vị. Bạn có thể xuất chúng trong bất kỳ định dạng hợp lý. Ví dụ: tất cả các giải pháp có thể cho n = 3 là:

(2, 2, 2) (1, 1, 6)
(1, 2, 3) (1, 2, 3)
(1, 3, 3) (1, 1, 7)
(1, 2, 5) (1, 1, 8)

Chương trình có thể tạo ra nhiều kết hợp nhất cho n cao nhất trong một phút trên RAM 2GB của tôi , máy tính xách tay Intel Ubuntu 64 bit sẽ thắng. Nếu câu trả lời của bạn sử dụng hơn 2GB RAM hoặc được viết bằng ngôn ngữ mà tôi không thể kiểm tra bằng phần mềm có sẵn miễn phí, tôi sẽ không chấm điểm câu trả lời của bạn. Tôi sẽ kiểm tra câu trả lời sau hai tuần nữa và chọn người chiến thắng. Tất nhiên sau đó câu trả lời không cạnh tranh vẫn có thể được đăng.

Vì không biết bộ giải pháp đầy đủ cho tất cả n là gì, bạn được phép đăng câu trả lời tạo ra giải pháp không đầy đủ. Tuy nhiên, nếu câu trả lời khác tạo ra một giải pháp hoàn chỉnh (nhiều hơn), ngay cả khi n tối đa của chúng nhỏ hơn , câu trả lời đó sẽ thắng.


Để làm rõ, đây là quá trình tính điểm để quyết định người chiến thắng:

  1. Tôi sẽ kiểm tra chương trình của bạn với n = 2, n = 3, v.v ... Tôi lưu trữ tất cả các đầu ra của bạn và dừng lại khi chương trình của bạn mất hơn một phút hoặc hơn 2GB RAM. Mỗi lần chương trình được chạy cho một đầu vào n cho trước, nó sẽ bị chấm dứt nếu mất hơn 1 phút.

  2. Tôi xem xét tất cả các kết quả cho tất cả các chương trình cho n = 2. Nếu một chương trình tạo ra các giải pháp ít hợp lệ hơn một chương trình khác, chương trình đó sẽ bị loại bỏ.

  3. Lặp lại bước 2 cho n = 3, n = 4, v.v ... Chương trình cuối cùng đứng thắng.


1
Vì vậy, không có câu trả lời trong các ngôn ngữ độc quyền windows?
Conor O'Brien

3
Cá nhân, tôi không thích các tiêu chí chấm điểm. Không thể biết liệu các giải pháp của chúng tôi có hoạt động hay không và đặt ngưỡng ở đâu cho đến khi chúng tôi có kết quả từ các thử nghiệm trên máy tính của bạn. Tôi nghĩ rằng một mã golf đơn giản sẽ làm cho một câu hỏi tốt hơn.
sĩ523

2
Tôi cho rằng mã hóa cứng không được phép. Nhưng sau đó, hạn chế đó gần như không thể quan sát được
Luis Mendo

1
@ user202729 Tôi không, tôi phải thử từng chương trình cho từng n để xem chương trình nào tạo ra nhiều giải pháp hơn.
orlp

2
"Hai tuần thời gian kể từ bây giờ" là 3 ngày trước.
GB

Câu trả lời:


4

C (gcc) , n = 50000000 với 6499 kết quả trong 59 giây

Để tránh sản xuất trên một terabyte đầu ra bao gồm gần như hoàn toàn 1 giây, một chuỗi (giả sử) 49999995 1s được viết tắt là 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;
}

Hãy thử trực tuyến!


3

Toán học, n = 293 với 12 nghiệm

OP đã thay đổi thử thách và yêu cầu đầu vào
Đây là mã mới lấy bất kỳ n nào làm đầu vào
Với n = 293, bạn nhận được 12 giải pháp

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]]]]]]]]&


đầu vào

[n]

Bạn có thể kiểm tra thuật toán này trên Wolfram Sandbox , một phần mềm có sẵn miễn phí trực tuyến
Chỉ cần theo liên kết, dán mã (ctrl + v), dán đầu vào ở cuối mã và nhấn shift + enter để chạy.
Bạn sẽ nhận được tất cả các giải pháp của tôi trong vài giây

Đây cũng là thử trực tuyến! trong C ++ (gcc)
(Rất cám ơn @ThePirateBay đã hỗ trợ và dịch mã của tôi sang ngôn ngữ miễn phí)

chương trình này chỉ tạo ra các giải pháp có dạng {a, b, c} {a, b, c}
có nghĩa là a + b + c = a * b * c

Phải mất 1 giây để tính toán

mười hai giải pháp là:

{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}


1
"Nếu câu trả lời của bạn [...] được viết bằng ngôn ngữ mà tôi không thể kiểm tra bằng phần mềm có sẵn miễn phí, tôi sẽ không chấm điểm câu trả lời của bạn."
Nữ tu bị rò rỉ

4
@GB "bạn được phép đăng câu trả lời tạo ra giải pháp chưa hoàn chỉnh"
user202729

1
chương trình của tôi ".. tạo ra nhiều kết hợp nhất cho n cao nhất trong một phút". Nó không bị mã hóa. Nó chỉ tìm thấy 12 giải pháp "dễ nhất" đầu tiên trong vòng một phút
J42161217

1
Có thể rõ ràng hơn rằng n được cho là một đầu vào. Tôi đã làm rõ điều đó ngay bây giờ. Nó không xuất hiện chương trình của bạn mất một đầu vào n .
orlp

2
@orlp Đã sửa! Chương trình của tôi lấy bất kỳ n làm đầu vào. Với n = 293 bạn nhận được 12 giải pháp. vui lòng bỏ xuống nếu mọi thứ hoạt động!
J42161217

2

Python 2 , n = 175, 28 kết quả sau 59 giây

Làm cho nó chậm hơn một chút bằng cách sử dụng hệ số khử 2, nhưng nhận được nhiều giải pháp hơn bắt đầu với n = 83

Tôi nhận được kết quả cho n lên tới 92 trên TIO trong một lần chạy.

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

Hãy thử trực tuyến!


1
"giữ 5 yếu tố [1..2] và giới hạn 3n ..." Tôi rất vui vì bạn thích thuật toán của tôi ;-)
J42161217

Tôi đã làm một cái gì đó tương tự trong phiên bản Ruby, và bây giờ tôi đang cố gắng loại bỏ giới hạn đó.
GB

Với một n cho trước, có bao nhiêu giải pháp được mã hóa cứng trong thuật toán của bạn?
J42161217

Không thực sự được mã hóa cứng: 2 giải pháp tiêu chuẩn có thể được tạo bằng cách sử dụng phím tắt (ngoại trừ n = 2 trong đó chúng là cùng một kết hợp) và bằng cách bỏ qua chúng, tôi có thể giới hạn phạm vi trong 2n thay vì 3n. Nếu điều này được coi là mã hóa cứng, tôi sẽ thay đổi nó.
GB

1
Đối với 61 kết quả của tôi sẽ là 28, tôi nhớ là 27 ... Có thể tôi đã mắc một số lỗi
RosLuP

1

Ruby , n = 12 được 6 giải pháp

Ít nhất là trên TIO, kết quả thông thường cho 1 đến 11

->n{
  arr=[*1..n*3].product(*(0..n-2).map{|x|
    [*1..[n/3**x,2].max]|[1]
  }).select{|a|
    a.count(1) >= n-4
  }.map(&:sort).uniq
  arr.product(arr).map(&:sort).uniq.select{|r|
    r[0].reduce(&:+) == r[1].reduce(&:*) &&
    r[0].reduce(&:*) == r[1].reduce(&:+)
  }
}

Hãy thử trực tuyến!

Nhận 10 kết quả dưới một phút cho n = 13 trên máy tính xách tay của tôi.


1

Toán học, n = 19 với 11 giải pháp

đây là câu trả lời mới của tôi theo tiêu chí mới của OP

(SOL = {};
For[a = 1, a < 3, a++, 
For[b = a, b < 3, b++, 
For[c = b, c < 5, c++, 
 For[d = c, d < 6, d++, 
  For[e = d, e < 3#, e++, 
   For[k = 1, k < 3, k++, 
    For[l = k, l < 3, l++, 
     For[m = l, m < 5, m++, 
      For[n = m, n < 6, n++, For[o = n, o < 3#, o++,
        s = Join[Table[1, # - 5], {a, b, c, d, e}];
        t = Join[Table[1, # - 5], {k, l, m, n, o}];            
        If[Tr[s[[-# ;;]]] == Times @@ t[[-# ;;]] && 
          Tr[t[[-# ;;]]] == Times @@ s[[-# ;;]], 
         AppendTo[SOL,{s[[-#;;]],t[[-#;;]]}]]]]]]]]]]]];
Union[SortBy[#,Last]&/@SOL])&

nếu bạn đưa ra một đầu vào [n] ở cuối, chương trình sẽ hiển thị các giải pháp

đây là kết quả của tôi (trên máy tính xách tay cũ 64-bit 2.4GHz)

n-> giải pháp
2 -> 2
3 -> 4
4 -> 3
5 -> 5
6 -> 4
7 -> 6
8 -> 5
9 -> 7
10 -> 7
11 -> 8
12 -> 6 (trong 17 giây)
13 -> 10 (trong 20 giây)
14 -> 7 (trong 25 giây)
15 -> 7 (trong 29 giây)
16 -> 9 (trong 34 giây)
17 -> 10 (trong 39 giây)
18 - > 9 (trong 45 giây)
19 -> 11 (trong 51 giây)
20 -> 7 (trong 58 giây)


1

Haskell, rất nhiều giải pháp nhanh chóng

import System.Environment

pr n v = prh n v v

prh 1 v l = [ [v] | v<=l ]
prh n 1 _ = [ take n $ repeat 1 ]
prh _ _ 1 = []
prh n v l = [ d:r | d <-[2..l], v `mod` d == 0, r <- prh (n-1) (v`div`d) d ]

wo n v = [ (c,k) | c <- pr n v, let s = sum c, s>=v,
                   k <- pr n s, sum k == v, s>v || c>=k ]

f n = concatMap (wo n) [n+1..3*n]

main = do [ inp ] <- getArgs
          let results = zip [1..] $ f (read inp)
          mapM_ (\(n,s) -> putStrLn $ (show n) ++ ": " ++ (show s)) results

ftính toán các giải pháp, mainhàm thêm nhận đầu vào từ dòng lệnh và một số định dạng và đếm.


Biên dịch như thế này: ghc -O3 -o prodsum prodsum.hsvà chạy với đối số dòng lệnh:./prodsum 6
Christian Sievers

0

Haskell , n = 10 với 2 giải pháp


import           Data.List

removeDups = foldl' (\seen x -> if x `elem` seen then seen else x : seen) []
removeDups' = foldl' (\seen x -> if x `elem` seen then seen else x : seen) []

f n= removeDups $ map sort filterSums
  where maxNumber = 4
        func x y = if (((fst x) == (fst.snd$y)) && ((fst y) == (fst.snd$x)))
                     then [(snd.snd$x),(snd.snd$y)]
                     else [[],[]]
        pOf = removeDups' $ (map sort (mapM (const [1..maxNumber]) [1..n]))
        sumOf = map (\x->((sum x),((product x), x))) pOf
        filterSums = filter (\x-> not$(x == [[],[]])) (funcsumOfsumOf)

Điều này thực hiện như tào lao, nhưng ít nhất tôi đã sửa nó vì vậy tôi thực sự đang giải quyết thách thức bây giờ!

Hãy thử trực tuyến!


với n = 2 bạn nhận được ["[3,3] [2,3]", "[2,2] [2,2]", "[1,3] [2,2]", "[1, 2] [1,3] "," [1,1] [1,2] "] sai
J42161217

Tất cả các giải pháp dường như đều thực sự sai
GB

@Jenny_mathy Làm thế nào là sai? 3 + 3 là 6 và 2 * 3 là 6. Tôi có hiểu nhầm câu hỏi không.
maple_shaft

bạn đang thiếu "ngược lại"
J42161217

@Jenny_mathy Lỗi ngu ngốc về phía tôi! Tôi đã sửa nó, nên làm việc bây giờ.
maple_shaft

0

Tiên đề, n = 83 trong 59 giây ở đây

-- copy the below text in the file name "thisfile.input" 
-- and give something as the command below in the Axiom window:
-- )read C:\Users\thisuser\thisdirectory\thisfile

)cl all
)time on

-- controlla che l'array a e' formato da elementi  a.i<=a.(i+1)
tv(a:List PI):Boolean==(for i in 1..#a-1 repeat if a.i> a.(i+1) then return false;true)

-- funzione incremento: incrementa a, con #a=n=b/3,sotto la regola di "reduce(+,a)+#a-1>=reduce(*,a)"
-- e che n<reduce(*,a)<3*n ed reduce(+,a)<3*n 
inc3(a:List PI):INT==
   i:=1; n:=#a; b:=3*n
   repeat
      if i>n  then return 0
      x:=reduce(*,a)
      if x>=b then a.i:=1
      else
          y:=reduce(+,a)
          if y>b then a.i=1
          else if y+n-1>=x then
                      x:=x quo a.i
                      a.i:=a.i+1
                      x:=x*a.i
                      if tv(a) then break
                      else a.i:=1
          else a.i:=1
      i:=i+1
   if x<=n then return inc3(a) -- x<=n non va
   x

-- ritorna una lista di liste di 4 divisori di n
-- tali che il loro prodotto e' n
g4(n:PI):List List PI==
  a:=divisors(n)
  r:List List PI:=[]
  for i in 1..#a repeat
     for j in i..#a repeat
        x:=a.i*a.j
        if x*a.j>n then break
        for k in j..#a repeat
            y:=x*a.k
            if y*a.k>n then break
            for h in k..#a repeat
                z:=y*a.h
                if z=n  then r:=cons([a.h,a.k,a.j,a.i],r)
                if z>=n then break 
  r

-- ritorna una lista di liste di 3 divisori di n
-- tali che il loro prodotto e' n
g(n:PI):List List PI==
  a:=divisors(n)
  r:List List PI:=[]
  for i in 1..#a repeat
     for j in i..#a repeat
        x:=a.i*a.j
        if x*a.j>n then break
        for k in j..#a repeat
            y:=x*a.k
            if y=n  then r:=cons([a.k,a.j,a.i],r)
            if y>=n then break
  r

-- cerca che [a,b] nn si trovi gia' in r
searchr(r:List List List PI,a:List PI,b:List PI):Boolean==
  aa:=sort(a); bb:=sort(b)
  for i in 1..#r repeat
      x:=sort(r.i.1);y:=sort(r.i.2)
      if x=aa and y=bb then return false
      if x=bb and y=aa then return false
  true

-- input n:PI
-- ritorna r, tale che se [a,b] in r
-- allora #a=#b=n
--        ed reduce(+,a)=reduce(*,b) ed reduce(+,b)=reduce(*,a)
f(n:PI):List List List PI==
  n>100000 or n<=1 =>[]
  a:List PI:=[]; b:List PI:=[]; r:List List List PI:=[]
  for i in 1..n repeat(a:=cons(1,a);b:=cons(1,b))
  if n~=72 and n<86 then  m:=min(3,n)
  else                    m:=min(4,n) 
  q:=reduce(*,a) 
  repeat
    w:=reduce(+,a)
    if n~=72 and n<86 then x:= g(w)
    else                   x:=g4(w)
    if q=w then r:=cons([copy a, copy a],r)
    for i in 1..#x repeat
           for j in 1..m repeat
                  b.j:=(x.i).j
           -- per costruzione abbiamo che reduce(+,a)= prodotto dei b.i=reduce(*,b)
           -- manca solo di controllare che reduce(+,b)=reduce(*,a)=q
           if reduce(+,b)=q and searchr(r,a,b) then r:=cons([copy a, copy b],r)
    q:=inc3(a)
    if q=0 then break
  r

các kết quả:

 for i in 2..83 repeat output [i, # f(i)]
   [2,2][3,4][4,3][5,5][6,4][7,6][8,5][9,7][10,7][11,8][12,6][13,10][14,7][15,7]
   [16,10][17,10][18,9][19,12][20,7][21,13][22,9][23,14][24,7][25,13][26,11]
   [27,10][28,11][29,15][30,9][31,16][32,11][33,17][34,9][35,9][36,13][37,19]
   [38,11][39,14][40,12][41,17][42,11][43,20][44,12][45,16][46,14][47,14][48,13]
   [49,16][50,14][51,17][52,11][53,20][54,15][55,17]
   [56,14][57,20][58,17][59,16][60,15][61,28][62,15][63,16][64,17][65,18]
   [66,14][67,23][68,20][69,19][70,13][71,18][72,15][73,30][74,15][75,17][76,18]
   [77,25][78,16][79,27][80,9][81,23][82,17][83,26]


 f 3
    [[[1,2,5],[8,1,1]],[[1,3,3],[7,1,1]],[[1,2,3],[1,2,3]],[[2,2,2],[6,1,1]]]
                                     Type: List List List PositiveInteger
                                   Time: 0.07 (IN) + 0.05 (OT) = 0.12 sec

Cách để chạy văn bản trên Axiom, sẽ là, sao chép tất cả văn bản đó trong một tệp, lưu tệp có tên: Name.input, trong cửa sổ Axiom sử dụng ") đọc tuyệt đối / Tên".
kết quả: (# f (i) tìm độ dài của mảng f (i), đó là số lượng giải pháp)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.