ผลิตภัณฑ์ที่ตัดแบ่งสูงสุด


11

เราจะได้รับรายการจำนวนเต็ม p1, ... , pk (ไม่จำเป็นต้องชัดเจน) โดยที่แต่ละค่ามีค่าระหว่าง 1 ถึง 9 การใช้แต่ละ p1, ... , pk เพียงครั้งเดียวเราสามารถสร้างการเรียงตัวของตัวเลขเพื่อให้ได้รายการตัวเลขใหม่ จากนั้นเราจะส่งออกผลิตภัณฑ์ของรายการใหม่นี้ เป้าหมายคือเพื่อเพิ่มผลิตภัณฑ์นี้โดยการเลือกการต่อข้อมูลที่ดีที่สุดของตัวเลข

ตัวอย่างเช่นเราได้รับรายการ: 2 3 2 (คั่นด้วยช่องว่าง) เราสามารถสร้างการเรียงต่อกันดังต่อไปนี้:

  • 2 3 2(ผลิตภัณฑ์ของการต่อข้อมูลเหล่านี้คือ12)
  • 23 2(ผลิตภัณฑ์คือ46)
  • 32 2(ผลิตภัณฑ์คือ64)
  • 22 3(ผลิตภัณฑ์คือ66)

เนื่องจากผลิตภัณฑ์ที่ใหญ่ที่สุดที่เราสามารถทำการต่อกันได้คือ 66 เราจึงส่งออก

กฎ:

  • ต้องมีการคูณอย่างน้อยหนึ่งรายการ (เช่นคุณไม่สามารถต่อตัวเลขและเอาท์พุททั้งหมดเข้าด้วยกันได้)
  • คุณไม่สามารถใช้โอเปอเรเตอร์อื่นนอกเหนือจากการคูณหรือใส่วงเล็บเป็นต้น
  • สมมติว่ารายการจำนวนเต็มที่กำหนดถูกคั่นด้วยช่องว่างและจำนวนเต็มทั้งหมดมีค่าระหว่าง 1 ถึง 9

รหัสที่สั้นที่สุด (เป็นไบต์) ชนะ!

กรณีทดสอบ:

อินพุต: 1 2 3; ผลลัพธ์: 63(เช่น, 21*3)

อินพุต: 2 5 9; ผลลัพธ์: 468( 52*9)

อินพุต: 1 2 3 4; ผลลัพธ์: 1312( 41*32)


เราควรเขียนโปรแกรมทั้งหมดหรือฟังก์ชั่นที่รับพารามิเตอร์อินพุตและการคืนค่าผลลัพธ์นั้นก็ใช้ได้เช่นกัน?
randomra

@randomra ใช่มันไม่เป็นไร
Ryan

สำหรับตัวเลขแต่ละคู่ a, b ผลิตภัณฑ์ a * b. น้อยกว่าการต่อข้อมูลอย่างง่าย ab (= a * 10 ^ (ตัวเลขของ b) + b) ดังนั้นเพียง 1 ผลิตภัณฑ์ (ตามที่ได้รับคำสั่ง) เพิ่มสิ่งนี้: codegolf.stackexchange.com/q/49854/21348
edc65

คำตอบ:


8

CJam, 32 28 23 12 ไบต์

0le!f{~*}:e>

ลองใช้ออนไลน์ในล่าม CJam

ขอบคุณ @ user23013 ที่ช่วยฉันประหยัดทั้ง 16 ไบต์!

ความคิด

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

รหัส

 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 ไบต์

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

ตรงไปตรงมาสวย ทำซ้ำชุดค่าผสมที่เป็นไปได้ทั้งหมดและเรียงลำดับตามผลิตภัณฑ์ จากนั้นให้ผลลัพธ์ที่ใหญ่ที่สุด ทั้งหมดนี้จำไว้ว่าควรมีการคูณอย่างน้อย 1 ตัว

จะเพิ่มคำอธิบายในไม่ช้า

ลองออนไลน์ได้ที่นี่


1

JavaScript (ES6) 125

แก้ไขฉันคิดว่า @oberon ทำให้ถูกต้อง: "แต่ละหลักใหม่ต้องต่อกันกับตัวเลขที่เล็กที่สุด"

ฉันจะไม่เปลี่ยนคำตอบนี้เพื่อขโมยความคิดของเขา การใช้งานใน ES6 จะเป็น 70 ไบต์ (เครื่องหมายถูกเปลี่ยนเมื่อเปรียบเทียบเพื่อเปรียบเทียบเป็นตัวเลขและไม่ใช่สตริง)

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

ทางออกของฉัน

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

ดังที่ฉันพูดในความคิดเห็นสำหรับแต่ละคู่ของตัวเลข a, b ผลิตภัณฑ์ a * b นั้นน้อยกว่าการต่อข้อมูลอย่างง่าย ab (= a * 10 ^ (ตัวเลขของ b) + b) ดังนั้นจึงเป็นการดีกว่าที่จะหลีกเลี่ยงผลิตภัณฑ์และต้องการเรียงต่อกัน แต่เมื่อมีการร้องขออย่างน้อย 1 ผลิตภัณฑ์เราจะต้องสร้างตัวเลข 2 ตัวและคูณพวกเขา

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

ตัวอย่างเช่นด้วยรายการหมายเลข 4 [1 2 3 4] - ลอง:

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

ค่าสูงสุดเหล่านี้คือผลลัพธ์ที่เราต้องการ

การจัดกลุ่มสามารถระบุลูปบนบิตแมปเป็น 4 บิตโดยมีค่าต่ำสุด 0001 และค่าสูงสุด 0111 (นั่นคือ 1 << (4 -1) - 1)

ไม่ค่อยเล่นกอล์ฟ

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
}

ทดสอบโดยใช้ตัวอย่างด้านล่างใน 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 ไบต์

มันน่าเล่นกอล์ฟได้มากกว่า ฉันชอบเวลาที่ใช้ (แม้ว่า (O ( n log n )) ใช่ไหม?

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

ไม่พอใจกับคำอธิบาย

# 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

Pyth, 25 ไบต์

eSsmm*ss<dkss>dkr1ld.pcz)

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


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='')))}

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

กระบวนการทั่วไปคือ:

  • เรียงลำดับรายการจากมากไปน้อย
  • สลับคู่คี่ / คู่แรกที่แตกต่างกัน
  • เชื่อมต่อรายการคู่และคี่ของรายการ
  • ประเมินผลิตภัณฑ์ของผลลัพธ์ทั้งสอง

ขยายออกด้วยความคิดเห็นบางส่วน

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=''))) 
}

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