Tìm hoạt động tối đa


12

Thách thức là tìm ra số lượng tối đa bạn có thể nhận được từ một danh sách các số nguyên bằng cách sử dụng các toán tử số học cơ bản (cộng, cộng, nhân, phủ định đơn phương)

Đầu vào

Danh sách các số nguyên

Đầu ra

Kết quả tối đa sử dụng mọi số nguyên trong phần tử.

Thứ tự đầu vào không quan trọng, kết quả sẽ giống nhau.

Bạn không cần phải xuất toàn bộ hoạt động, chỉ cần kết quả.

Ví dụ

Input : 3 0 1
Output : 4 (3 + 1 + 0)

Input : 3 1 1 2 2
Output : 27 ((2+1)*(2+1)*3))

Input : -1 5 0 6
Output : 36 (6 * (5 - (-1)) +0)

Input : -10 -10 -10
Output : 1000 -((-10) * (-10) * (-10))

Input : 1 1 1 1 1
Output : 6 ((1+1+1)*(1+1))

Quy tắc

  • Mã ngắn nhất sẽ thắng

  • "Lỗ hổng" tiêu chuẩn được áp dụng

  • Bạn chỉ có thể sử dụng các toán tử + * - (phép cộng, phép nhân, phép con, phủ định đơn phương)

  • Mã phải hoạt động miễn là kết quả có thể được lưu trữ trên Số nguyên 32 bit.

  • Bất kỳ hành vi tràn là tùy thuộc vào bạn.

Tôi hy vọng điều này là đủ rõ ràng, đây là gợi ý thử thách Code Golf đầu tiên của tôi.


Một trong những ví dụ của bạn là sử dụng một thao tác không được phép: nếu phủ định đơn phương được dự định nằm trong danh sách trắng của bạn thì phép trừ không thực sự cần thiết.
Peter Taylor

Chỉnh sửa và thêm phủ định unary. Substraction được giữ trong danh sách trắng.
CNicolas

1
Nó phải là một chương trình đầy đủ hay là một chức năng đủ?
ThreeFx

Chương trình đầy đủ. Thậm chí tốt hơn nếu nó có thể được chạy trực tuyến, nhưng rõ ràng là không bắt buộc
CNicolas

@INSeed Tôi có nên thêm một cách để chạy trực tuyến?
tự hào

Câu trả lời:


9

C - 224 byte - Thời gian chạy O (n)

o=0,w=0,n[55],t,*m=n,*p=n;main(r){for(;scanf("%d",++p);t<3?--p,w+=t/2,o+=t&1:t<*m|m==n?m=p:9)t=*p=abs(*p);t=o<w?o:w;o-=t;w-=t;t+=o/3;for(o%3?o%3-2?t?t--,w+=2:++*m:w++:9;t--;)r*=3;for(r<<=w;--p>n;)r*=*p;printf("%d",r>1?r:o);}

Thật buồn cười khi chỉ thấy các giải pháp theo thời gian theo cấp số nhân cho một vấn đề thời gian tuyến tính, nhưng tôi cho rằng đó là cách hợp lý để tiến hành vì không có điểm thưởng nào cho việc thực sự có thuật toán, đó là đảo chữ logarit.

Sau khi chuyển đổi số âm thành số dương và loại bỏ các số 0, rõ ràng chúng ta chủ yếu quan tâm đến phép nhân. Chúng tôi muốn tối đa hóa logarit của số cuối cùng.

log (a + b) <log (a) + log (b) trừ khi a = 1 hoặc b = 1, vì vậy những trường hợp này là trường hợp duy nhất mà chúng ta quan tâm đến việc thêm bất cứ thứ gì vào nhau. Nói chung, tốt hơn là thêm 1 vào một số nhỏ hơn, bởi vì điều đó gây ra sự gia tăng logarit lớn hơn, tức là tăng phần trăm lớn hơn, hơn là thêm 1 vào một số lớn. Có bốn kịch bản có thể, được sắp xếp theo thứ tự ít nhất là thích hợp nhất, để sử dụng các kịch bản:

  1. Thêm một vào 2 sẽ cho + log .405 [log (3) - log (2)]
  2. Kết hợp những cái thành ba cho ra + log .366 mỗi một [log (3) / 3]
  3. Tạo 2 trong số đó cho + log .347 mỗi một [log (2) / 2]
  4. Thêm một vào số 3 hoặc cao hơn sẽ cho + log .288 trở xuống [log (4) - log (3)]

Chương trình theo dõi số lượng cái, số lượng twos và số lượng tối thiểu lớn hơn 2, và đi xuống danh sách các cách sử dụng những cách ít thích hợp nhất. Cuối cùng, nó nhân tất cả các số còn lại.


6

Haskell, 126 ký tự

đây chỉ là vũ phu, ngoại trừ việc bỏ qua dấu hiệu của đầu vào và bỏ qua phép trừ và phủ định đơn phương.

import Data.List
f[x]=abs x::Int
f l=maximum$subsequences l\\[[],l]>>= \p->[f p+f(l\\p),f p*f(l\\p)]
main=interact$show.f.read

mã này cực kỳ chậm. mã tính toán đệ quy f trên mỗi lần tiếp theo của đầu vào bốn lần (ngoại trừ [] và chính đầu vào) . nhưng này, đó là mã golf.


5

SWI-Prolog - 250

Oh boy, tôi đã dành quá nhiều thời gian cho việc này.

o(A,B,A+B).
o(A,B,A-B).
o(A,B,A*B).
t([],0).
t([A,B|T],D):-t(T,Q),o(A,B,C),o(C,Q,D).
t([A|T],C):-t(T,Q),o(A,Q,C).
a(A):-t(A,B),n(C),B>C,retract(n(C)),assert(n(B)).
m(A):-assert(n(0)),\+p(A),n(R),R2 is R,write(R2).
p(A):-permutation([0|A],B),a(B),0=1.

Được gọi từ dòng lệnh (ví dụ):

> swipl -s filename.pl -g "m([1, 1, 1, 1, 1])" -t halt
6

(Không có lý do cụ thể, tôi thấy thật tuyệt vời khi tên hàm golf của tôi đánh vần là "nồi cà chua.")

Phiên bản bị đánh cắp:

% Possible operations
operation(Left, Right, Left + Right).
operation(Left, Right, Left - Right).
operation(Left, Right, Left * Right).

% Possible ways to transform
transform([], 0).
transform([A, B|T], D) :- transform(T, Q), operation(A, B, C), operation(C, Q, D).
transform([A|T], C) :- transform(T, Q), operation(A, Q, C).

% Throw the given array through every possible transformation and update the max
all_transforms(A) :- transform(A, B), n(C), B>C, retract(n(C)), assert(n(B)).

% Find all the permutations and transformations, then fail and continue execution.
prog(A) :- assert(n(0)), !, permutation([0|A], B), all_transforms(B), fail.

% End the program
finished :- n(R), write(R), nl, R2 is R, write(R2), nl.

% Run the program
main(A) :- ignore(prog(A)), finished.

Giải trình:

  1. Lấy một mảng làm đối số.
  2. Nhận tất cả các hoán vị của mảng.
  3. Tìm một số sắp xếp của các toán tử để thêm vào mảng. (Điều này được thực hiện thông qua lập trình động, xem liệu có tốt hơn không nếu chúng ta kết hợp hai yếu tố đầu tiên hay không.)
  4. Kiểm tra này so với giá trị tối đa hiện tại của chúng tôi. Nếu nó tốt hơn, thay thế nó.
  5. Nói với chương trình chúng ta đã thất bại để nó tiếp tục kiểm tra, nhưng sau đó phủ nhận rằng (sử dụng ignorehoặc \+) để cho phép vị ngữ quay trở lại tổng thểtrue và tiếp tục.
  6. Chúng tôi được cung cấp một chuỗi các vị từ, thay vì một số, vì vậy hãy gán nó bằng cách sử dụng isvà sau đó viết nó.

4

Scala, 134

print(args.map(Math abs _.toInt)./:(Seq(Array(0)))((l,a)=>l.map(a+:_)++l.flatMap(_.permutations.map{r=>r(0)+=a;r}))map(_.product)max)

Ungolfed & bình luận:

print(
  args
    .map(Math abs _.toInt)                     // to int, ignoring -
    .foldLeft(Seq(Array(0))){ (list,num) =>    // build up a list of sums of numbers
      list.map(num+:_) ++                      // either add the new number to the list
      list.flatMap(_.permutations.map{ copy =>
        copy(0)+=num                           // or add it to one of the elements
        copy
      })
    }
    .map(_.product) // take the maximum of the the products-of-sums
    .max
)

Một cách tiếp cận hơi khác nhau, từ nhận ra rằng câu trả lời lớn nhất luôn có thể được thể hiện như một sản phẩm của tổng.

Rất gần, nhưng một loạt sự ngu ngốc của thư viện (hoán vị trả về một Iterator thay vì Seq, kiểu suy luận khủng khiếp về các chuỗi trống, Đơn vị trả về Array.update) đã đưa tôi vào.


3

Python 278 (O (n!))

from itertools import*
def f(n):
 f,n,m=lambda n:[(n,)]+[(x,)+y for x in range(1,n)for y in f(n-x)],map(abs,map(int,n.split())),0
 for p,j in product(permutations(n),f(len(n))):
  i=iter(p)
  m=max(m,reduce(lambda e,p:e*p,(sum(zip(*zip([0]*e,i))[1])for e in j)))
 return m

Giải trình

  1. Unary Negate nên được sử dụng một cách thận trọng để chuyển đổi tất cả các số âm thành dương
  2. Tìm tất cả các hoán vị có thể có của các số
  3. Sử dụng phân vùng Integer để tìm tất cả các tập hợp sức mạnh của một hoán vị đã cho
  4. Tìm sản phẩm của các khoản tiền
  5. Trả lại số tiền tối đa của sản phẩm

3

Haskell - 295 290 265 246 203 189 182 byte


Cuối cùng cũng hoạt động! Ngoài ra bây giờ nó là một lực lượng vũ phu hơn là một giải pháp năng động.


Cảm ơn kiêu hãnh cho một số lời khuyên chơi golf.

Đây có lẽ không phải là một giải pháp chơi golf hoàn toàn bởi vì tôi thực sự say mê chơi golf, nhưng đó là cách tốt nhất tôi có thể nghĩ ra (và nó có vẻ phức tạp, vì vậy tôi đã làm điều đó cho tôi):

import Data.List
main=interact$show.g.read
g x=maximum[product$a#b|a<-sequence$replicate(length x-1)[0,1],b<-permutations x]
(a:b)#(c:d:e)|a>0=b#(c+d:e)|0<1=c:b#(d:e)
_#x=x

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

[1,1,1,2,2]
12

[1,1,3,3,3]
54

[1,1,1,1,1,1,1,1,5,3]
270

Giải thích về giải pháp:

Các mainchức năng chỉ nhận được một đầu vào và chạyg với nó.

g nhận đầu vào và trả về mức tối đa của tất cả các kết hợp có thể có của tổng và danh sách đơn hàng.

# là hàm tính tổng trong một danh sách như thế này:

a = [1,0,0,1]
b = [1,1,1,2,2]
a#b = [2,1,4]

điều này có vẻ như là một giải pháp dựa trên hiệu suất.
tự hào

bạn có thể vui lòng viết những dòng mới thay vì ;khi có thể không? nó không thay đổi số byte nhưng giúp khả năng đọc dễ dàng hơn
tự hào

@proudhaskeller Tôi không biết làm thế nào để vũ phu điều này vì vậy tôi đã phải nghĩ ra một thứ khác: D
ThreeFx

lời khuyên của tôi cho việc chơi golf này - 1) nội tuyến mọi chức năng được sử dụng chỉ một lần (trừ khi nó sử dụng khớp mẫu hoặc bộ bảo vệ). 2) bạn có thể thực hiện d như d n=[0,2,1]!!nhoặc d n=mod(3-n)3. 3) tạo oglấy độ dài của danh sách thay vì tự lấy danh sách, vì chúng chỉ phụ thuộc vào độ dài (rõ ràng điều này chỉ đứng miễn là chúng không được nội tuyến). 4) thay thế otherwisebằng 0<1. 5) làm cho định nghĩa cuối cùng của r được r$o x:y. 6) loại bỏ a@và thay thế bằng x:y. chúc may mắn với việc chơi golf của bạn
tự hào

Thuật toán của bạn đưa ra câu trả lời sai cho [3,3,3,2,2,2,1,1,1]. Tôi đã chạy mã của bạn và nó trả về 216 (kết quả lớn nhất tôi có thể đạt được là 729).
Brilliand

1

GolfScript (52 ký tự)

~]0-{abs}%.1-.1,or@,@,-,-1%{!\$.0=3<@+{()}1if+}/{*}*

Bản demo trực tuyến

phân tích của feerum là khá tốt nhưng nó có thể được thực hiện xa hơn nếu mục tiêu là chơi gôn hơn là hiệu quả. Trong mã giả:

filter zeros from input and replace negatives with their absolute value
filter ones to get A[]
count the ones removed to get C
while (C > 0) {
    sort A
    if (A[0] < 3 || C == 1) A[0]++
    else A.append(1)
    C--
}
fold a multiply over A
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.