ค้นหาการดำเนินงานสูงสุด


12

ความท้าทายคือการหาจำนวนสูงสุดที่คุณจะได้รับจากรายการจำนวนเต็มโดยใช้ตัวดำเนินการทางคณิตศาสตร์พื้นฐาน

อินพุต

รายการจำนวนเต็ม

เอาท์พุต

ผลลัพธ์สูงสุดโดยใช้จำนวนเต็มทุกตัวในการป้อนข้อมูล

ลำดับการป้อนข้อมูลไม่สำคัญผลลัพธ์ควรเหมือนกัน

คุณไม่จำเป็นต้องแสดงผลการดำเนินการเต็มรูปแบบเพียงผลลัพธ์

ตัวอย่าง

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))

กฎระเบียบ

  • รหัสที่สั้นที่สุดชนะ

  • มาตรฐาน "ช่องโหว่"นำไปใช้

  • คุณสามารถใช้ + * - โอเปอเรเตอร์เท่านั้น (การเพิ่ม, การคูณ, การลบ, การปฏิเสธคู่กัน)

  • รหัสควรทำงานได้ตราบใดที่ผลลัพธ์สามารถจัดเก็บใน 32 บิตเป็นจำนวนเต็ม

  • พฤติกรรมล้นใด ๆ ขึ้นอยู่กับคุณ

ฉันหวังว่านี่ชัดเจนเพียงพอนี่คือคำแนะนำการท้าทายรหัสกอล์ฟครั้งแรก


หนึ่งในตัวอย่างของคุณกำลังใช้การดำเนินการที่ไม่ได้รับอนุญาต: หากการปฏิเสธแบบเอกสิทธิ์มีวัตถุประสงค์เพื่อให้อยู่ในรายการที่อนุญาตของคุณการลบไม่จำเป็นจริงๆ
ปีเตอร์เทย์เลอร์

แก้ไขและเพิ่มการปฏิเสธเอกภาพ การลบจะถูกเก็บไว้ในรายการที่อนุญาต
CNicolas

1
ต้องเป็นโปรแกรมเต็มหรือฟังก์ชั่นเพียงพอหรือไม่?
ThreeFx

โปรแกรมเต็มรูปแบบ ยิ่งไปกว่านั้นถ้ามันสามารถทำงานออนไลน์ได้ แต่เห็นได้ชัดว่าไม่ได้บังคับ
CNicolas

@INSeed ฉันควรเพิ่มวิธีเรียกใช้ออนไลน์หรือไม่
ภูมิใจ Haskeller

คำตอบ:


9

C - 224 ไบต์ - เวลาทำงาน 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);}

มันสนุกมากที่ได้เห็นเพียงวิธีแก้ปัญหาแบบเอ็กซ์โปเนนเชียลไทม์สำหรับปัญหาเชิงเส้นเวลา แต่ฉันคิดว่ามันเป็นวิธีที่มีเหตุผลในการดำเนินการเนื่องจากไม่มีคะแนนโบนัสสำหรับการมีอัลกอริทึมซึ่งเป็นแอนนาแกรมของลอการิทึม

หลังจากแปลงจำนวนลบเป็นศูนย์บวกและยกเลิกเราเห็นได้ชัดว่าเราสนใจในการคูณ เราต้องการเพิ่มลอการิทึมของจำนวนสุดท้าย

log (a + b) <log (a) + log (b) ยกเว้นเมื่อ a = 1 หรือ b = 1 ดังนั้นกรณีนี้เป็นกรณีเดียวที่เราสนใจที่จะเพิ่มอะไรเข้าด้วยกัน โดยทั่วไปแล้วจะเป็นการดีกว่าถ้าเพิ่ม 1 ลงในจำนวนที่น้อยลงเพราะนั่นทำให้ลอการิทึมเพิ่มขึ้นนั่นคือการเพิ่มขึ้นของเปอร์เซ็นต์ที่ใหญ่กว่าการเพิ่ม 1 ลงในจำนวนมาก มีสี่สถานการณ์ที่เป็นไปได้สั่งมากที่สุดไปหาน้อยที่สุดสำหรับการใช้งาน:

  1. เพิ่มหนึ่งถึง 2 ให้ + บันทึก. 405 [log (3) - log (2)]
  2. การรวมสิ่งต่างๆเข้ากับ threes จะให้ + log .366 ต่อหนึ่ง [log (3) / 3]
  3. การทำ 2 จากทั้งหมดให้ + log .347 ต่อหนึ่ง [log (2) / 2]
  4. การเพิ่มหนึ่งรายการในหมายเลข 3 หรือสูงกว่าจะให้ + log .288 หรือน้อยกว่า [log (4) - log (3)]

โปรแกรมจะติดตามจำนวนของคนจำนวน twos และจำนวนขั้นต่ำที่มากกว่า 2 และไปลงรายการของวิธีที่ดีที่สุดไปหาน้อยที่สุดของการใช้คน ในที่สุดมันก็จะคูณจำนวนที่เหลือทั้งหมด


6

Haskell, 126 ตัวอักษร

นี่เป็นเพียงการบังคับให้สัตว์เดรัจฉานยกเว้นการเพิกเฉยต่อสัญญาณของอินพุตและเพิกเฉยต่อการลบและการปฏิเสธแบบเอกนารี

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

รหัสนี้ช้ามาก รหัสซ้ำคำนวณฉบน subsequence แต่ละอินพุตสี่ครั้ง (ยกเว้น [] และใส่เอง) แต่เดี๋ยวก่อนมันเป็นรหัสกอล์ฟ


5

SWI-Prolog - 250

โอ้เจ้าหนูใช้เวลานี้นานเกินไป

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.

เรียกได้จากบรรทัดคำสั่ง (เช่น):

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

(โดยไม่มีเหตุผลเรื่องอนุภาคฉันพบว่ามันยอดเยี่ยมมากที่ชื่อฟังก์ชันสนามกอล์ฟของฉันสะกด "หม้อมะเขือเทศ")

เวอร์ชันที่ไม่ถูกปรับแต่ง:

% 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.

คำอธิบาย:

  1. ใช้เวลาในอาร์เรย์เป็นอาร์กิวเมนต์
  2. รับพีชคณิตทั้งหมดของอาร์เรย์
  3. ค้นหาการจัดเรียงของโอเปอเรเตอร์เพื่อเพิ่มในอาร์เรย์ (สิ่งนี้ทำได้ผ่านการเขียนโปรแกรมแบบไดนามิกโดยดูว่าดีกว่าหรือไม่ถ้าเรารวมสององค์ประกอบแรกเข้าด้วยกันหรือไม่)
  4. ตรวจสอบกับค่าสูงสุดปัจจุบันของเรา หากดีกว่าให้แทนที่
  5. บอกโปรแกรมที่เราล้มเหลวเพื่อให้มันตรวจสอบอยู่ แต่ก็ปฏิเสธว่า (ใช้ignoreหรือ\+) เพื่อให้ผลสรุปโดยรวมtrueแล้วดำเนินการต่อ
  6. เราได้รับสตริงของเพรดิเคตแทนที่จะเป็นตัวเลขดังนั้นกำหนดโดยใช้isแล้วเขียน

4

สกาลา, 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 & แสดงความคิดเห็น:

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
)

วิธีการที่แตกต่างกันเล็กน้อยจากการตระหนักว่าคำตอบที่ใหญ่ที่สุดสามารถแสดงเป็นผลบวกได้

ใกล้มาก แต่ความโง่เขลาของห้องสมุด (การเรียงสับเปลี่ยนส่งกลับค่า Iterator แทนที่จะเป็น Seq การอนุมานประเภทที่น่ากลัวในลำดับว่างเปล่า Array.update คืนหน่วย) ทำให้ฉันเข้า


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

คำอธิบาย

  1. ควรใช้ Unary Negate อย่างรอบคอบเพื่อแปลงจำนวนลบทั้งหมดให้เป็นบวก
  2. ค้นหาการเรียงสับเปลี่ยนที่เป็นไปได้ทั้งหมดของตัวเลข
  3. การใช้พาร์ติชัน Integer เพื่อค้นหาชุดพลังงานทั้งหมดของการเปลี่ยนแปลงที่กำหนด
  4. ค้นหาผลคูณของจำนวนเงิน
  5. คืนค่าสูงสุดของผลรวมของผลรวม

3

Haskell - 295 290 265 246 203 189 182 ไบต์


ในที่สุดก็ใช้งานได้! นอกจากนี้ตอนนี้มันเป็นกำลังดุร้ายมากกว่าโซลูชันแบบไดนามิก


ขอบคุณสำหรับความภาคภูมิใจขอให้เคล็ดลับการเล่นกอล์ฟ

นี่อาจไม่ใช่วิธีแก้ปัญหากอล์ฟอย่างสมบูรณ์เพราะจริง ๆ แล้วฉันชอบเล่นกอล์ฟ แต่มันเป็นสิ่งที่ดีที่สุดที่ฉันสามารถทำได้

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

กรณีทดสอบใหม่:

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

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

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

คำอธิบายโซลูชัน:

mainฟังก์ชั่นเพิ่งได้รับการป้อนข้อมูลและทำงานgกับมัน

g รับค่าอินพุทและส่งกลับค่าสูงสุดของการรวมกันที่เป็นไปได้ทั้งหมดของผลรวมและรายการคำสั่ง

# เป็นฟังก์ชันที่คำนวณผลรวมในรายการดังนี้:

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

ดูเหมือนว่าจะเป็นโซลูชันที่ขับเคลื่อนด้วยประสิทธิภาพ
ภูมิใจ haskeller

คุณช่วยกรุณาเขียนบรรทัดใหม่แทน;เมื่อเป็นไปได้? มันไม่เปลี่ยนจำนวนไบต์ แต่ช่วยให้อ่านง่ายอย่างแท้จริง
ภูมิใจ Haskeller

@proudhaskeller ฉันไม่รู้ว่าจะดุร้ายอย่างไรฉันจึงต้องหาวิธีอื่นมาก่อน: D
ThreeFx

คำแนะนำของฉันสำหรับการเล่นกอล์ฟ - 1) อินไลน์ทุกฟังก์ชั่นที่ใช้เพียงครั้งเดียว (เว้นแต่จะใช้การจับคู่รูปแบบหรือการ์ด) 2) คุณสามารถใช้ d เป็นหรือd n=[0,2,1]!!n d n=mod(3-n)33) สร้างoและgรับความยาวของรายการแทนที่จะจดรายการเองเนื่องจากมันขึ้นอยู่กับความยาวเท่านั้น (เห็นได้ชัดว่านี่จะยืนได้นานตราบเท่าที่ไม่ได้อยู่ในบรรทัด) 4) แทนที่ด้วยotherwise 0<15) ให้ความหมายสุดท้ายของ R r$o x:yBE 6) ลบและแทนที่ด้วยa@ x:yขอให้โชคดีกับการเล่นกอล์ฟของคุณ!
ภูมิใจ haskeller

อัลกอริทึมของคุณให้คำตอบที่ผิดสำหรับ [3,3,3,2,2,2,2,1,1] ฉันรันโค้ดของคุณและส่งคืน 216 (ผลลัพธ์ที่ใหญ่ที่สุดที่ฉันสามารถทำได้คือ 729)
Brilliand

1

GolfScript (52 ตัวอักษร)

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

การสาธิตออนไลน์

การวิเคราะห์ของ feersumนั้นค่อนข้างดี แต่ก็สามารถนำไปต่อไปได้หากเป้าหมายคือการเล่นกอล์ฟมากกว่ามีประสิทธิภาพ ในรหัสปลอม:

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.