นักเก็ตแห่งรหัส


18

นักเก็ตแห่งรหัส

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

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

ขนาดก้อนนักเก็ตไก่อยู่ทั่วทุกที่และขึ้นอยู่กับว่าคุณอาศัยอยู่ที่ไหนในโลกขนาดมาตรฐานก็เปลี่ยนไปเช่นกัน อย่างไรก็ตาม[สถานที่ที่ให้บริการนักเก็ต]ที่ใกล้เคียงที่สุดจะมีขนาดของก้อนนักเก็ตต่อไปนี้:

4, 6, 9, 10, 20, 40

ตอนนี้คุณอาจสังเกตเห็นว่าคุณไม่สามารถสั่งชุดนักเก็ตได้ ยกตัวอย่างเช่น11นักเก็ตเป็นไปไม่ได้เนื่องจากมีการรวมกันที่เท่ากับไม่มี11ตรง แต่คุณสามารถทำให้43โดยได้รับ 1 แพ็คของ201 แพ็คของ101 แพ็คของ9และ 1 แพ็คของ4,

20 + 10 + 9 + 4 = 43 (597)

ที่597อยู่ในแต่ละระยะยืดและรวมเข้าด้วยกัน(คำใบ้: ทางออกที่ดีที่สุดมีนี้เป็นค่าสูงสุด) แน่นอนว่ามีวิธีอื่นในการทำ43แต่เท่าที่คุณรู้นักเก็ตต่อแพ็คยิ่งมีราคาถูกลงเท่าใดนักต่อนักเก็ต ดังนั้นคุณต้องการซื้อแพ็คจำนวนน้อยที่สุดและในปริมาณมากที่สุดเพื่อลดต้นทุนของคุณ

งาน

คุณควรสร้างโปรแกรมหรือฟังก์ชั่นที่รับรายการจำนวนเต็มที่สอดคล้องกับข้อกำหนดของแต่ละคน จากนั้นคุณควรคำนวณและพิมพ์คำสั่งαที่คุ้มค่าที่สุดเพื่อซื้อนักเก็ตไก่ คำสั่งαที่คุ้มค่าที่สุดคือการรวมกันโดยผลรวมของกำลังสองของแต่ละปริมาณนั้นสูงที่สุด ถ้ามีอย่างวิธีที่จะซื้อนักเก็ตได้อย่างสมบูรณ์แบบไม่มีคุณต้องพิมพ์ค่า falsy เช่น0, False, Impossible!หรือสิ่งที่มีให้บริการในภาษาของคุณ

ตัวอย่าง I / O:

[2 7 12 4 15 3] => [20 10 9 4]
     1, 1, 2, 1 => False
  6 5 5 5 5 5 9 => 40
      [6, 4, 9] => 9 10
              1 => 0
            199 => 40, 40, 40, 40, 20, 10, 9
              2 => Impossible!

นี่คือรายการของโซลูชั่นที่เหมาะสำหรับ 400 ก่อนหมายเหตุเหล่านี้ไม่ได้จัดรูปแบบวิธีการที่ผมจะคาดหวังของคุณจะเป็นแต่ละอยู่ในรูปแบบtuple(N lots of M)

กฎระเบียบ

  1. ไม่มีช่องโหว่มาตรฐาน
  2. ไม่ใช้ฟังก์ชันในตัวที่ทำหน้าที่ส่วนใหญ่หรือทั้งหมดเช่นFrobeniusSolveใน Mathematica

α - หากต้องการอธิบายให้ชัดเจนด้วยตัวอย่างคุณสามารถทำ 43 ด้วยการทำเช่น4 + 6 + 6 + 9 + 9 + 9 = 43 (319)นี้ แต่มันจะไม่เหมาะสมและทำให้เอาต์พุตไม่ถูกต้องเนื่องจากผลรวมของสี่เหลี่ยมน้อยกว่าชุดที่ฉันสังเกตไว้ในบทนำ โดยพื้นฐานแล้วผลรวมของสี่เหลี่ยมที่สูงขึ้น = ต้นทุนที่ต่ำกว่า = ต้นทุนที่มีประสิทธิภาพมากที่สุด


มีการ จำกัด เวลา / หน่วยความจำหรือไม่?
Dennis

@Dennis ไม่มีเวลาหรือ จำกัด หน่วยความจำ
Kade

4
เป็นจริงวันพฤหัสบดี
mbomb007

4
@ mbomb007 การสังเกตอย่างชาญฉลาด: P ฉันได้ปรับอินโทร
Kade

2
ฉันจำเป็นต้องใช้ทฤษฎีไก่ mcnuggetอย่างใด ...
Stretch Maniac

คำตอบ:


7

Pyth, 26 25 ไบต์

e+Zo.aNf!-TCM"  
("./sQ

สังเกตว่ามีตัวอักษรที่ไม่สามารถพิมพ์ได้ ลองมันออนไลน์: สาธิต มันค่อนข้างช้า (แต่ไม่ช้าเท่ากับโซลูชัน 26 ไบต์ของฉัน)

คำอธิบาย:

                          implicit: Q = input list
                     sQ   sum(Q)
                   ./     generate all integer partitions
       f                  filter for partitions T, which satisfy:
             "   ("          string containing chars with the ASCII-values of 4,6,9,10,20,40
           CM                convert each char to the ASCII-value
         -T                  remove this numbers from T
        !                    and check, if the resulting list is empty
    o                      order the remaining subsets N by:
     .aN                      the vector length of N (sqrt of sum of squares)
  +Z                       insert 0 at the beginning
 e                         print the last element

Pyth, 32 ไบต์

e+Zo.aNfqsTsQysm*]d/sQdCM"  
(

สังเกตว่ามีตัวอักษรที่ไม่สามารถพิมพ์ได้ ลองออนไลน์: การสาธิต เวอร์ชั่นนี้เร็วขึ้น ค้นหาโซลูชันสำหรับอินพุต[6,7,8]ในประมาณหนึ่งวินาทีและโซลูชันสำหรับอินพุต[30]ในเวลาประมาณ 90 วินาที

คำอธิบาย:

                                 implicit: Q = input list
                          "...(  the string containing chars with the ASCII-values of 4,6,9,10,20,40
                        CM       convert each char to the ASCII-value
                m                map each number d to:
                  ]d                create the list [d]
                 *  /sQd            and repeat it sum(Q)/d times
               s                 unfold
              y                  generate all subsets
        f                        filter for subsets T, which satisfy:
         qsTsQ                      sum(Q) == sum(T)
    o                            order the remaining subsets N by:
     .aN                            the vector length of N (sqrt of sum of squares)
  +Z                             insert 0 at the beginning
 e                               print the last element

ทำไมถึงเป็นผลรวมของกำลังสองของสี่เหลี่ยมจัตุรัสแทนที่จะเป็นแค่ผลรวม?
mbomb007

1
@ mbomb007 เพราะมันไม่สำคัญ ถ้า a> b, sqrt (a)> sqrt (b) และในทางกลับกัน และใช้.aวิธีนี้สั้นกว่ากำลังสองและการs^R2หาผลรวม
Jakube

5

Perl, 175 153

sub f{my$n=$_[0];if(!$n){return 1;}foreach$o(40,20,9,10,6,4){if($n>=$o&&f($n-$o)){print"$o ";return 1;}}return 0;}$n+=$_ for@ARGV;if(!f($n)){print":(";}

รับอินพุตจากข้อโต้แย้งของโปรแกรม พิมพ์ a :(หากไม่พบโซลูชันที่สมบูรณ์แบบ

รหัส Ungolfed:

sub f
{
    my $n = $_[0];
    if(!$n)
    {
        return 1;
    }
    foreach $o(40,20,9,10,6,4)
    {
        if($n>=$o&&f($n-$o))
        {
            print "$o ";
            return 1;
        }
    }
    return 0;
}

$n += $_ for @ARGV;
if(!f($n))
{
    print ":(";
}

PS: นี่อาจเป็นรายการแรกที่ใช้เวลาไม่ถึง 10 นาที1 2;)

ตรวจสอบที่นี่


ขอแสดงความยินดีกับสิ่งที่ดูเหมือนจะเป็นโปรแกรมที่เร็วที่สุดจนถึงตอนนี้! อาจเร็วกว่าโปรแกรมอ้างอิงของฉันด้วย: P ฉันได้เพิ่มลิงค์ ideone ที่ด้านล่างของโพสต์ของคุณเพื่อให้ผู้คนสามารถเห็นผลลัพธ์
Kade

รหัสของคุณสามารถสร้างผลลัพธ์ที่ไม่ถูกต้อง การป้อนข้อมูล18ควรพิมพ์ไม่9 9 4 4 10
Dennis

มีเอาต์พุตที่ไม่ถูกต้องอื่น ๆ เช่นกัน ถ้าฉันไม่ผิดที่คุณสามารถแก้ไขทั้งหมดของพวกเขาโดยการเปลี่ยนคำสั่งของและ9 10
Dennis

@Dennis ขอขอบคุณแก้ไขมันได้!
โทมัส Oltmann

3

CJam, 45 29 28 bytes

q~:+_[40K9A6Z)U]m*_::+@#=0-p

โปรดทราบว่าวิธีนี้ช้ามากและใช้หน่วยความจำมาก

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

สามารถเร่งความเร็วได้อย่างมีนัยสำคัญในราคา 5 ไบต์:

q~:+_40/4+[40K9A6Z)U]m*_::+@#=0-p

ความซับซ้อนยังคงเป็นเลขชี้กำลังในผลรวมของการป้อนข้อมูล แต่สิ่งนี้ควรจัดการกรณีทดสอบได้ถึง 159 ด้วยล่ามออนไลน์และมากถึง 199 กับล่าม Java ในไม่กี่วินาที

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

ความคิด

การซื้อที่ดีที่สุด (ผลรวมสูงสุดของสี่เหลี่ยม) เป็นซื้อที่ถูกต้อง (จำนวนที่ถูกต้องของนักเก็ต) ที่มีเป็นจำนวนมาก40 's ที่สุดแล้วเป็นจำนวนมาก20 ' s ที่สุดแล้วเป็นจำนวนมาก9 's เป็นไปได้ (เช่น9 9เป็น กว่าดีกว่า10 4 4) และอื่น ๆ สำหรับ10 's, 6 ' และ4 's

ในวิธีการนี้เราสร้างผลิตภัณฑ์คาร์ทีเซียนของสำเนาNของอาร์เรย์[40 20 9 10 6 4 0]โดยที่Nคือจำนวนนักเก็ตที่ต้องการ Nคือขอบเขตสูงสุด (ไม่ดี) สำหรับจำนวนการซื้อที่เราต้องทำ ในโค้ดเร่งความเร็วเราใช้N / 40 + 4แทน

เพราะวิธีการอาร์เรย์จะสั่งซื้อผลิตภัณฑ์คาร์ทีเซียนจะเริ่มต้นด้วยเวกเตอร์[40 ... 40]และจบลงด้วยเวกเตอร์[0 ... 0] เราคำนวณดัชนีของเวกเตอร์แรกที่มีผลรวมที่ถูกต้อง (ซึ่งจะมีผลรวมของกำลังสองที่เหมาะสมที่สุด) ดึงองค์ประกอบอาร์เรย์ที่สอดคล้องกันลบศูนย์ที่ทำหน้าที่เป็นตัวแทนและพิมพ์ผลลัพธ์

หากไม่พบเวกเตอร์ดัชนีจะเป็น-1ดังนั้นเราจึงดึงข้อมูล[0 ... 0]ซึ่งจะพิมพ์อาร์เรย์ว่างแทน

รหัส

q~                            e# Read from STDIN and evaluate the input.
  :+                          e# Push N, the sum of all elements of the resulting array.
     [40K9A6Z)U]              e# Push B := [40 20 9 10 6 4 0].
    _           m*            e# Push B**N, the array of all vectors of dimension N
                              e# and coordinates in B.
                  _::+        e# Copy and replace each vector by its sum.
                      @#      e# Get the first index of N.
                        =     e# Retrieve the corresponding element.
                         0-p  e# Remove 0's and print.

นี้อาจจะเป็นหนึ่งในไม่กี่สถานการณ์ที่ทำงานออกมาแก้ปัญหาด้วยมือจะเร็วกว่าการปล่อยให้จบรหัส .. งานที่ดีโดยไม่คำนึงถึง :)
Kade

2

จูเลีย, 126 ไบต์

r->(t=filter(i->all(j->j[4,6,9,10,20,40],i),partitions(sum(r)));show(!isempty(t)&&collect(t)[indmax(map(k->sum(k.^2),t))]))

สิ่งนี้จะสร้างฟังก์ชั่นที่ไม่มีชื่อที่ยอมรับอาร์เรย์เป็นอินพุตและพิมพ์อาร์เรย์หรือบูลีนไปยัง STDOUT ขึ้นอยู่กับว่าโซลูชันนั้นมีอยู่หรือไม่ f=n->...เรียกว่าให้มันชื่อเช่น

คำอธิบาย Ungolfed +:

function f(r)
    # Nugget pack sizes
    packs = [4, 6, 9, 10, 20, 40]

    # Filter the set of arrays which sum to the required number of nuggets
    # to those for which each element is a nugget pack
    t = filter(i -> all(j -> jpacks, i), partitions(sum(r)))

    # Print the boolean false if t is empty, otherwise print the array of
    # necessary nugget packs for which the sum of squares is maximal
    show(!isempty(t) && collect(t)[indmax(map(k -> sum(k.^2), t))])
end

ตัวอย่าง:

julia> f([1])
false

julia> f([2,7,12,4,15,3])
[20,10,9,4]

1

Python 3 - 265 ตัวอักษร

import itertools as i
n=list(map(int,input().split(',')));m=[]
for f in range(1,9):
 for j in range(6*f):
  for x in i.combinations((4,6,9,10,20,40,)*f,j+1):
   if sum(n)==sum(x):m.append(x)
if m!=[]:v=[sum(l**2for l in q)for q in m];print(m[v.index(max(v))])
else:print(0)

กำลังแสดงระยะห่าง:

import itertools as i
n=list(map(int,input().split(',')));m=[]
for f in range(1,5):
 for j in range(6*f):
\tfor x in i.combinations((4,6,9,10,20,40,)*f,j+1):
\t if sum(n)==sum(x):m.append(x)
\t\tif m!=[]:v=[sum(l**2for l in q)for q in m];print(m[v.index(max(v))])
else:print(0)

ผ่านทุกกรณีทดสอบ

หมายเหตุ:ฉันไม่รู้ว่ามันจะผ่านทุกกรณีหรือไม่เพราะมันช้ามาก ... แต่ควร ...


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

@ Vioz- ยอดเยี่ยม! : D
เบต้าสลายตัว

ดูเหมือนว่าฉันอาจจะผิดหลังจากทดสอบ 36 จะได้รับประมาณ 40 ล้านชุด (40,007,602 เป็นที่แน่นอน) ก่อนที่จะใช้ MemoryError นี่อาจเป็นข้อ จำกัด ของเครื่องทำงานของฉันเนื่องจากมีหน่วยความจำ 4GB เท่านั้น
Kade

@ Vioz- อืม ... ฉันหวังว่าจะทดสอบโทรศัพท์ของฉันต่อไป ...
Beta Decay

1
@undergroundmonorail หากคุณใช้เพียงครั้งเดียวสำหรับ <= 4 ตัวอักษรการนำเข้าแบบตรงจะดีกว่า (พัก 5 ครั้ง) แต่ถ้าคุณใช้มันมากกว่าหนึ่งครั้งfrom blah import*ที่สุดเสมอ ข้อยกเว้นเดียวที่ฉันสามารถนึกได้ข้างต้นคือถ้าคุณมีหลายimports ซึ่งเป็นเวลาเดียวที่อยู่ในใจที่asมีประโยชน์จริง ๆ
Sp3000

1

JavaScript, 261 256 261

d="length";function g(a){for(z=y=0;y<a[d];z+=+a[y++]);return z}x=[40,20,10,9,6,4];l=prompt().split(",");o=g(l);p=[];for(i=0;i<x[d];i++)r=g(p),s=r+x[i],(s<o-3||s==o)&&p.push(x[i]),(i==x[d]-1||40<o-r)&&r+x[i]<o-3&&(i=-1,0==i||o-r<p[p[d]-1]&&p.pop());g(p)==o&&p||0

ฉันไม่แน่ใจว่านี่เป็นไรดูเหมือนว่าจะทำงาน แต่ฉันขาดสิ่งต่าง ๆ อย่างแน่นอน

ดูเหมือนว่าจะไม่ช้าแม้ว่าจะถึง123456ผลลัพธ์[40 x 3086, 10, 6]เกือบจะทันที

คำอธิบาย:

วนซ้ำขนาดนักเก็ต (ใหญ่ที่สุดก่อน)

  • หากผลรวมของสแต็กบวกขนาดนักเก็ตน้อยกว่าเป้าหมาย - 3 -> ดันลงบนสแต็ก
  • หากมีเหลือมากกว่า 40 -> รีเซ็ตตัวนับลูป
  • หากผลรวมของสแต็กมากกว่าเป้าหมายเมื่อถึงขนาดนักเก็ตสุดท้าย -> ป๊อปองค์ประกอบสุดท้ายให้รีเซ็ตตัวนับลูป
  • ถ้าผลรวมของสแต็กเพิ่มขึ้นให้ส่งคืนมิฉะนั้นส่งคืน 0

สำหรับ 199 | 1 การสร้างสแต็กมีลักษณะเช่นนี้

i | stack
0   [40]
0   [40, 40]
0   [40, 40, 40]
0   [40, 40, 40, 40]
0   [40, 40, 40, 40]
1   [40, 40, 40, 40, 20]
2   [40, 40, 40, 40, 20, 10]
3   [40, 40, 40, 40, 20, 10, 9]
4   [40, 40, 40, 40, 20, 10, 9]
5   [40, 40, 40, 40, 20, 10, 9]
==> [40, 40, 40, 40, 20, 10, 9]

สำหรับ 1

i | stack
0   []
1   []
2   []
3   []
4   []
5   []
==> 0

1
แนวทางของคุณดูเหมือนจะไม่ตรวจสอบว่าสามารถบรรลุเป้าหมายได้หรือไม่ 11พิมพ์[6]และการพิมพ์18 [10, 4]
Dennis

@Dennis เฮ้มีขอบคุณที่ชี้ให้เห็น เมื่อวานนี้มันดึกแล้ว แก้ไขเป็นเวลา 5 ตัวอักษร 18 พิมพ์[10,4]เพราะฉันขาดคำอุปมาคู่หนึ่ง การตรวจสอบนั้นผิดฉันแค่ตรวจสอบว่ามีองค์ประกอบอย่างน้อยหนึ่งรายการในชุดผลลัพธ์ไม่ใช่ถ้าผลรวมถูกต้อง ฉันไม่รู้ว่าฉันคิดอะไรอยู่ที่นั่น
C5H8NNaO4
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.