Sản phẩm kết hợp tối đa


11

Chúng tôi được cung cấp một danh sách các số nguyên p1, ..., pk (không nhất thiết phải khác biệt) trong đó mỗi số có giá trị từ 1 đến 9, bao gồm. Sử dụng mỗi p1, ..., pk chính xác một lần, chúng ta có thể tạo các cách ghép các chữ số, để đạt được một danh sách số mới; sau đó chúng tôi đầu ra sản phẩm của danh sách mới này. Mục tiêu là để tối đa hóa sản phẩm này bằng cách chọn các chữ số ghép tốt nhất.

Ví dụ: chúng tôi được cung cấp danh sách: 2 3 2 (cách nhau bởi khoảng trắng). Chúng ta có thể hình thành các kết nối sau:

  • 2 3 2(sản phẩm của những kết nối này là 12)
  • 23 2(sản phẩm là 46)
  • 32 2(sản phẩm là 64)
  • 22 3(sản phẩm là 66)

Vì sản phẩm lớn nhất mà chúng ta có thể tạo thành các phép nối là 66, nên chúng ta xuất ra sản phẩm đó.

Quy tắc:

  • Phải có ít nhất một phép nhân (nghĩa là bạn không thể ghép tất cả các chữ số và đầu ra đó).
  • Bạn không thể sử dụng bất kỳ toán tử nào khác ngoài phép nhân hoặc chèn dấu ngoặc đơn, v.v.
  • Giả sử rằng danh sách các số nguyên đã cho được phân tách bằng dấu cách và tất cả các số nguyên có giá trị từ 1 đến 9.

Mã ngắn nhất (tính bằng byte) sẽ thắng!

Các trường hợp thử nghiệm:

Đầu vào : 1 2 3; Đầu ra: 63(tức là 21*3)

Đầu vào : 2 5 9; Đầu ra: 468( 52*9)

Đầu vào : 1 2 3 4; Đầu ra: 1312( 41*32)


Chúng ta có nên viết toàn bộ chương trình hoặc một hàm lấy tham số đầu vào và trả về kết quả cũng tốt không?
ngẫu nhiên

@randomra Vâng, điều đó tốt.
Ryan

Với mỗi cặp số a, b, sản phẩm a * b.is nhỏ hơn phép ghép đơn giản ab (= a * 10 ^ (chữ số của b) + b). Vì vậy, chỉ cần 1 sản phẩm (như là bắt buộc). Thêm cái này: codegolf.stackexchange.com/q/49854/21348
edc65

Câu trả lời:


8

CJam, 32 28 23 12 byte

0le!f{~*}:e>

Hãy thử trực tuyến trong trình thông dịch CJam .

Cảm ơn @ user23013 đã giúp tôi tiết kiệm 16 byte toàn bộ!

Ý tưởng

Cho phép các ký tự trong chuỗi đầu vào chia nó thành các số nguyên (nhóm các chữ số liên tiếp) cách nhau bởi khoảng trắng. Bằng cách đẩy số 0 và sau đó đánh giá chuỗi đầu vào được hoán vị, chúng tôi đẩy hai hoặc nhiều số nguyên. Nhân hai số trên cùng sẽ dẫn đến kết quả là sản phẩm của đầu vào được chia thành chính xác hai số nguyên hoặc một số giá trị dưới mức tối ưu.

 le!         e# Push all possible character permutations of the input.
0   f{  }    e# For each permutation:
             e#   Push 0, then the permuted string.
      ~      e#   Evaluate the string. Pushes one or more integers.
       *     e#   Multiply the two topmost integers.
         :e> e# Retrieve the greatest integer in the array.

1
l2%_,,1>\e!m*{~S+m<~*}%$W=.
jimmy23013

2
l2%S+e!{0\~*}%$W=.
jimmy23013

2

CJam, 36 35 byte

q~]_,([SL]m*{s},\e!\m*{z[s~]:*}%$W=

Khá thẳng về phía trước. Lặp lại tất cả các kết hợp có thể và sắp xếp chúng theo sản phẩm. Sau đó đầu ra lớn nhất. Tất cả điều này, hãy nhớ rằng ít nhất 1 phép nhân phải có mặt.

Sẽ thêm lời giải thích sớm.

Dùng thử trực tuyến tại đây


1

JavaScript (ES6) 125

Chỉnh sửa Tôi nghĩ rằng @oberon đã hiểu đúng: "mỗi chữ số mới phải được nối với số nhỏ nhất"

Tôi sẽ không thay đổi câu trả lời này ăn cắp ý tưởng của mình. Việc thực hiện trong ES6 sẽ là 70 byte (thay đổi dấu hiệu so với số lượng và không phải chuỗi)

f=l=>l.split(' ').sort().reverse().map(d=>-a>-b?a+=d:b+=d,a=b='')||a*b

Giải pháp của tôi

f=l=>(i=>{for(r=0;a=b='',k=--i;r<a*b?r=a*b:0)for(v of l)k&1?a+=v:b+=v,k/=2})(1<<~-(l=l.split(' ').sort().reverse()).length)|r

Như tôi đã nói trong các nhận xét, với mỗi cặp số a, b, sản phẩm a * b nhỏ hơn phép ghép đơn giản ab (= a * 10 ^ (chữ số của b) + b). Vì vậy, tốt hơn hết là tránh các sản phẩm và thích ghép nối, nhưng vì ít nhất 1 sản phẩm được yêu cầu, chúng tôi phải xây dựng 2 số và nhân chúng.

Tôi thử tất cả các nhóm chữ số có thể, xây dựng một cặp số để nhân. Mỗi số được xây dựng một cách khó hiểu lấy các chữ số theo thứ tự giảm dần.

Chẳng hạn, với danh sách gồm 4 số, [1 2 3 4] - thử:

  • 4 * 321
  • 43 * 21
  • 42 * 31
  • 41 * 32
  • 432 * 1
  • 431 * 2
  • 421 * 3

Tối đa của các giá trị này là kết quả chúng ta cần.

Các nhóm có thể được liệt kê vòng lặp trên một bitmap gồm 4 bit, với giá trị tối thiểu 0001 và giá trị tối đa 0111 (đó là 1 << (4 -1) - 1)

Không chơi gôn

f=l=>{
  l = l.split(' '); // string to array
  l.sort().reverse(); // decreasing order 
  m = 1 << (l.length-1); starting value fro loop
  r = 0 
  // loop from m-1 down to 1
  for(i=m; --i; )
  {
    a = b = '';
    k = i;
    for(v of l) // divide the digits base on bits of i
    {
      k & 1 ? a+=v : b+=v;
      k /= 2;
    }
    if (r < a*b) r = a*b; // remember max value in r
  }
  return r
}

Kiểm tra bằng đoạn mã dưới đây trong Firefox.

f=l=>(i=>{for(r=0;a=b='',k=--i;r<a*b?r=a*b:0)for(v of l)k&1?a+=v:b+=v,k/=2})(1<<~-(l=l.split(' ').sort().reverse()).length)|r

t=l=>(i=>{for(x=r='';a=b='',k=--i;r<a*b?(r=a*b,x=' = '+a+'x'+b):0)for(v of l)k&1?a+=v:b+=v,k/=2})
(1<<~-(l=l.split(' ').sort().reverse()).length)|| x

function go()
{
  R.value = f(I.value) // TEST AS IS
   + t(I.value) // Some more info
}

test=['1 2 3 4','1 2 3','2 5 9','8 9 8']

test.forEach(t => O.innerHTML = O.innerHTML + (t + ' -> ' + f(t)) + '\n')
Type your list: <input id=I><button onclick='go()'>-></button><input readonly id=R><br>
<pre id=O></pre>


1

Python 3, 111 byte

Có lẽ nó dễ chơi hơn nhiều. Tôi thích thời gian chạy của nó, mặc dù (O ( n log n ), phải không?).

l=sorted(map(int,input().split()),reverse=1);m=[0,0]
for x in l:i=m[0]>m[1];m[i]=m[i]*10+x
print(m[0]*m[1])

Ung dung với lời giải thích.

# edc65 has already explained that the optimal solution can be found applying a single
# multiplication. thus, given that
#     (10x + d)y > (10y + d)x
# where x, y are the two numbers and d is the next digit to insert, it follows that
#     y > x
# and thus each new digit must be concatenated to the smallest number. obviously, digits
# should be added in descending order.
l = sorted(map(int, input().split()), reverse=1)
m = [0,0]
for x in l:
    i = m[0] > m[1]
    m[i] = m[i]*10 + x
print(m[0] * m[1])

0

Bình thường, 25 byte

eSsmm*ss<dkss>dkr1ld.pcz)

Tôi lặp qua mọi hoán vị của đầu vào. Sau đó, vì mọi kết hợp tối ưu bao gồm hai số nguyên, tôi chỉ phân tách nó ở mọi vị trí có thể và nhân các phần tách được nối. Sau đó tôi sắp xếp và lấy phần tử cuối cùng.


0

R, 164

function(n){l=length(n);a=sort(n,T);i=1;while(a[i]==a[i+1]&&i<l-2)i=i+2;a[c(i,i+1)]=a[c(i+1,i)];eval(parse(t=paste0(c(a[1:l%%2==1],"*",a[1:l%%2==0]),collapse='')))}

Là một phương pháp tôi không chắc chắn nếu điều này là mạnh mẽ. Với các trường hợp mà tôi đã thử nghiệm, nó dường như hoạt động mỗi lần. Tôi đã thử kiểm tra nó với giải pháp tối ưu hóa và nó cũng có vẻ ổn với điều đó. Tôi đã chuẩn bị nhiều hơn để được chứng minh là sai :) Có chỗ để chơi gôn, nhưng tôi đã hy vọng nhận được một số phản hồi về phương pháp này trước tiên.

Quy trình chung là:

  • Sắp xếp danh sách theo thứ tự giảm dần
  • Hoán đổi cặp lẻ / chẵn đầu tiên khác nhau
  • Nối các mục chẵn và lẻ của danh sách
  • Đánh giá sản phẩm của hai kết quả

Mở rộng ra với một số ý kiến

function(n){
    l=length(n);
    a=sort(n,T);    # sort descending order
    # Determine which pair to swap
    i=1;
    while(a[i]==a[i+1]&&i<l-2)i=i+2;
    a[c(i,i+1)]=a[c(i+1,i)];  # swap pair   
    # concatenate the even and odd indices items around a * and evaluate    
    eval(parse(t=paste0(c(a[1:l%%2==1],"*",a[1:l%%2==0]),collapse=''))) 
}

Và một số chạy thử nghiệm (được thực hiện như một hàm gọi là g)

> g(c(1,2,3))
[1] 63
> g(c(2,5,9))
[1] 468
> g(c(1,2,3,4))
[1] 1312
> g(c(1,2,3,5,5,5))
[1] 293132
> g(c(1,5,7,7,9,9))
[1] 946725
> g(c(1,7,8,9,9,9))
[1] 978117
> g(c(7,8,9,9,9))  #Test case provided edc65 to randomra
[1] 97713
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.