Mất bao lâu để ông già Noel giao quà?


12

Tôi đã đăng thử thách này cách đây một thời gian, trong đó liên quan đến việc có bao nhiêu yêu tinh ông già Noel cần giao quà.

Do sự gia tăng dân số, ông già Noel hơi bị ép trong năm nay. Mặc dù trong quá khứ chúng tôi hoạt động rất không đồng bộ, chúng tôi bắt đầu thử nghiệm để ngày càng đồng bộ hơn. Vì vậy, ông già Noel cần biết ông sẽ mất bao lâu để chuyển quà đến từng vùng với một số lượng yêu tinh nhất định.

Trọng lượng than không thay đổi trong hai năm qua - nó vẫn nặng hơn quà tặng, vì vậy ông già Noel cần ba yêu tinh cho một người nghịch ngợm trong nhà và hai yêu tinh mỗi người tốt bụng trong nhà.

Yêu tinh dành cả năm để đào tạo cho Giáng sinh, vì vậy họ không cần nghỉ ngơi giữa các lần giao hàng. Họ chỉ có thể giao quà cho một ngôi nhà tại một thời điểm và phải quay trở lại xe trượt tuyết của ông già Noel và thu thập món quà tiếp theo trước khi đến nhà kế tiếp. Vì những lý do mà tôi không được tự do chia sẻ, yêu tinh không dành thời gian đi lại giữa xe trượt tuyết và nhà của ông già Noel (nhưng chỉ có thể đi du lịch khi xe trượt tuyết của ông già Noel trên mái nhà), cũng như chiếc xe trượt tuyết của ông không dành thời gian di chuyển từ nhà này sang nhà khác. (Ông già Noel trượt tuyết không cần phải di chuyển từ nhà này sang nhà để nhiên liệu thu thập, nhưng tôi đã nói quá nhiều).

Yêu tinh đang giao quà cần phải dành bốn giây * mỗi lần giao quà và Yêu tinh đang giao than cần phải dành năm giây * mỗi lần giao quà (theo quy định của Cục Hàng không Santa, găng tay có bụi than phải được đốt ngay lập tức lên xe trượt tuyết, mất một thời gian). Ngoài ra, các ngôi nhà phải được truy cập theo thứ tự trên bản đồ, từ trái sang phải và yêu tinh không thể bắt đầu giao quà cho các nhà khác cho đến khi tất cả các món quà đã được chuyển đến ngôi nhà mà họ hiện đang ở.

Nếu chúng tôi cho rằng ông già Noel có quá nhiều yêu tinh cho khu vực này, sẽ chỉ mất một thời gian để gửi quà cho ai đó trong danh sách nghịch ngợm, 5 giây, mỗi nhà hoặc 4 giây mỗi nhà nếu mọi người đều tốt.

Tuy nhiên, trái ngược với các mùa trước, ông già Noel Giáng sinh sắp tới này có thể không có quá nhiều yêu tinh cho mỗi vùng, vì vậy 4 giây là khoảng thời gian tối thiểu tuyệt đối * mà họ sẽ phải gửi quà đến bất kỳ ngôi nhà nào, trừ khi có 0 người tốt và 0 người nghịch ngợm trong trường hợp đó sẽ mất 0 giây.

Ngoài ra, nếu thậm chí một trong những ngôi nhà có ai đó trong danh sách nghịch ngợm, ông già Noel sẽ cần ít nhất ba yêu tinh. Nếu ít nhất một trong những ngôi nhà có ai đó trong danh sách đẹp và không ai trong số họ có người trong danh sách nghịch ngợm, ông già Noel sẽ cần ít nhất hai yêu tinh. Nếu không có ngôi nhà nào trong tinh thần Giáng sinh, bất kỳ số lượng yêu tinh (bao gồm 0) sẽ mất 0 giây.

Trên bản đồ của ông già Noel, một ngôi nhà được đại diện bởi a *và mỗi ngôi nhà được chia cho a +. Santa vẫn sử dụng các bản đồ giống như trong thử thách khác , nhưng tôi sẽ bao gồm tài liệu về chúng ở đây.

Sẽ có một số ở hai bên của ngôi nhà - một bên trái đại diện cho số người nghịch ngợm trong nhà, và một bên phải đại diện cho số người tốt trong nhà. Nếu không có số ở một bên thì nó được hiểu là 0.

Tôi biết nó nghe có vẻ điên rồ, nhưng một số người "không thích Giáng sinh", vì vậy đôi khi, một ngôi nhà có thể không có số ở hai bên của nó.

Một trong những bản đồ của ông già Noel có thể trông giống như thế này.

1*3+2*+*5+*+4*7

Hãy nói rằng Santa có chín yêu tinh trong chiếc xe trượt tuyết của mình.

  1. (0s) Ngôi nhà đầu tiên có 1 người nghịch ngợm và 3 người tốt bụng. Ba trong số các yêu tinh giao than, mất năm giây và sáu lần giao quà, mất bốn giây. Sau năm giây, xe trượt tuyết của ông già Noel chuyển sang nhà kế bên

  2. (5s) Ngôi nhà thứ hai có 2 người nghịch ngợm và 0 người tốt bụng. Sáu trong số các yêu tinh giao than, mất năm giây. Sau năm giây, xe trượt tuyết của ông già Noel chuyển sang nhà kế bên

  3. (10s) Ngôi nhà thứ ba có 0 người nghịch ngợm và 5 người tốt bụng. Tám trong số các yêu tinh đi giao bốn món quà (một món quà bị bỏ lại không thể tặng quà). Sau bốn giây, tất cả các yêu tinh đã quay trở lại, và hai trong số họ đi giao món quà khác (xe trượt tuyết phải đợi yêu tinh quay trở lại trước khi đến nhà kế tiếp), mất thêm bốn giây

  4. (18s) Ngôi nhà thứ tư không theo tinh thần Giáng sinh, vì vậy có 0 người nghịch ngợm và 0 người tốt bụng, và bị bỏ qua

  5. (18s) Ngôi nhà thứ năm có 4 người nghịch ngợm và 7 người tốt bụng. Điều này hơi phức tạp ...

    I. Tất cả chín yêu tinh đi giao ba món quà than (để lại t + 0, trả lại t + 5s) II. Sau 5s, tất cả đều quay trở lại xe trượt tuyết, và ba trong số họ đi giao món quà cuối cùng của than (để lại t + 5s, trả lại t + 10) trong khi sáu người còn lại đi giao ba món quà xinh xắn (để lại t + 5s, trả về t + 9s).

    III. Sau bốn giây, sáu trong số các yêu tinh đã trở lại và đi để cung cấp thêm ba món quà tốt đẹp (để lại t + 9s, trả lại t + 13s).

    IV. Một giây sau khi họ rời đi, ba yêu tinh đang giao quà than trở lại, và hai trong số họ rời đi để trao món quà tốt đẹp cuối cùng (nghỉ + 10 giây, trả lại t + 14s)

  6. (18 + 14 = 32 giây ) Ông già Noel đã hoàn thành việc giao quà cho khu vực đó.

Như chúng ta có thể thấy, ông già Noel mất tổng cộng 32 giây để chuyển quà đến khu vực này. Tuy nhiên, đó là phiên bản đơn giản hóa quá mức của một trong những bản đồ của ông già Noel. Thông thường, bản đồ của ông già Noel có nhiều đường kẻ và có dạng hình vuông để phù hợp hơn với danh sách của ông. Một bản đồ bình thường có thể trông giống như thế này (một \nở cuối mỗi dòng)

1*2+*+*4+1*
2*4+3*+1*6+*
*+*+4*2+1*1
*4+*3+1*+2*3
3*10+2*+*5+*

Với 26 yêu tinh (hoặc bất kỳ số tiền nào cao hơn), sẽ mất Santa 71 giây .
Với 20 yêu tinh , sẽ mất Santa 76 giây .
Với 15 yêu tinh , Santa sẽ mất 80 giây .
Với 3 yêu tinh , sẽ mất Santa 288 giây .
Với 2 yêu tinh (hoặc bất kỳ số tiền thấp hơn), điều đó là không thể.

Ồ, và một điều nữa - thứ tự mà yêu tinh đưa ra vấn đề (vì sự khác biệt về thời gian của việc tặng quà cho những người nghịch ngợm / tốt bụng), vì vậy mã của bạn phải luôn tạo ra ít thời gian nhất mà yêu tinh có thể nhận quà.

Thử thách

Giúp Santa xác định sẽ mất bao lâu để một số lượng yêu tinh nhất định gửi quà.

Nhà

  • Một ngôi nhà được đại diện bởi một *
  • Nhà bị chia cắt +
  • Số ở bên trái của ngôi nhà tượng trưng cho số người nghịch ngợm (không có số có nghĩa là 0)
  • Số bên phải tượng trưng cho số người tốt (không có số có nghĩa là 0)
  • Có thể có dòng mới ( \n) trong đầu vào, cũng nên được xử lý dưới dạng phân tách

Yêu tinh

  • Ông già Noel cần sự giúp đỡ của ba yêu tinh cho những người nghịch ngợm (than nặng hơn nhiều so với quà) và sẽ phải mất những yêu tinh này năm giây * để chuyển quà
  • Ông già Noel cần sự giúp đỡ từ hai người tí hon cho người đẹp, và nó sẽ đưa những người tí hon Bốn giây * để cung cấp những món quà
  • Nếu không có số ở hai bên của ngôi nhà, ông già Noel sẽ không đến thăm ngôi nhà đó và vì thế sẽ không mất thời gian (mọi người không có tinh thần Giáng sinh thậm chí không xứng đáng với than đá)

Ông già Noel

  • Ông già Noel phải giao quà đến từng nhà một
  • Ông già Noel không thể chuyển sang ngôi nhà tiếp theo cho đến khi tất cả các yêu tinh trở lại trên chiếc xe trượt tuyết và tất cả những món quà đã được chuyển đến ngôi nhà đó (chúng ta không muốn để lại yêu tinh phía sau, bây giờ phải không?)
  • Xe trượt tuyết của ông già Noel không dành thời gian đi từ nhà này sang nhà khác (Một lần nữa, vì những lý do mà tôi không được tự do chia sẻ)

Phải làm gì

Đưa ra một bản đồ của một ngôi nhà và một số yêu tinh, hãy in ông già Noel sẽ mất bao lâu để chuyển quà đến những ngôi nhà trên bản đồ.

* (Tôi không thể chia sẻ lượng thời gian cần thiết để yêu tinh gửi quà. Tôi không thể xác nhận cũng không phủ nhận rằng thời gian trong thử thách này là chính xác)

Quy tắc

  • Có hai đầu vào - bản đồ và số lượng yêu tinh. Các đầu vào có thể được lấy làm đối số cho hàm hoặc từ STDIN hoặc tương đương. Nếu việc sử dụng hai đầu vào là không thể trong ngôn ngữ của bạn, thì và chỉ sau đó bạn mới có thể chấp nhận hai đầu vào dưới dạng một chuỗi đầu vào, được phân tách bằng một số ký tự không bình thường trong một đầu vào (không phải một trong +*\nhoặc 0-9- chuỗi đầu vào không thể mơ hồ) ví dụ ,.
  • Số lượng yêu tinh sẽ luôn là một số nguyên không âm (0 là hợp lệ)
  • Đầu ra có thể là giá trị trả về của hàm hoặc được in ra STDOUT hoặc tương đương. Nếu ông già Noel không thể giao quà cho khu vực nhất định với một số lượng yêu tinh nhất định, bạn phải xuất ra một số âm nhất quán hoặc một thông điệp nhất quán mà không có bất kỳ số nào trong đó
  • Mọi thứ được in ra STDERR sẽ bị bỏ qua, do đó bạn không thể in kết quả hoặc thông báo lỗi sang STDERR
  • Chương trình của bạn không thể bị sập với số lượng yêu tinh không hợp lệ cho một khu vực
  • Đầu ra chỉ nên là tổng thời gian ông già Noel sẽ phải giao quà với số lượng yêu tinh đã cho.
  • Đầu ra phải luôn luôn là ít thời gian nhất để yêu tinh gửi quà
  • Các đầu vào sẽ chỉ chứa số, +, *, và dòng mới \n(trừ khi bạn chỉ định một nhân vật khác mà đầu vào sẽ bao gồm nếu ngôn ngữ của bạn không thể lấy hai đầu vào (nhìn vào quy tắc đầu tiên) )
  • Áp dụng sơ hở tiêu chuẩn

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

"1*1", 5 elves => 5
"1*1", 3 elves => 9
"1*2", 7 elves => 5
"1*2", 5 elves => 10
"1*2", 3 elves => 13
"2*1", 8 elves => 5
"2*1", 5 elves => 9
"2*1", 3 elves => 14
"1*" , 3 elves => 5
"1*" , 2 elves => (error message)
"*1" , 2 elves => 4
"*1" , 0 elves => (error message)
"*"  , 0 elves => 0

"1*1+1*1",   5 elves => 10
"1*1+1*1",   3 elves => 18
"1*1+*+1*1", 3 elves => 18
"1*2+2*1",   8 elves => 10
"1*2+2*1",   7 elves => 14
"1*2+2*1",   6 elves => 18
"1*2+2*1",   3 elves => 27
"1*2+2*1",   2 elves => (error message)
"*+*+*+*",   2 elves => 0
"*+*+*+*",   0 elves => 0

"1*3+2*+*5+*+4*7", 9 elves => 32

(hy vọng tôi hiểu đúng tất cả)

Chấm điểm

Ông già Noel mỗi ngày luôn luôn nhìn vào rất nhiều thứ - tất cả những món quà ông sẽ giao, tất cả những yêu tinh ông có, tất cả những ngôi nhà ông đang tặng quà cho ... Đối với ông già Noel, món quà Giáng sinh tuyệt vời nhất sẽ được có thể nhìn thấy một chút của một cái gì đó. Vì lý do này, bài nộp ngắn nhất tính bằng byte sẽ thắng .

Bảng xếp hạng

Đây là một Stack Snippet tạo ra cả bảng xếp hạng và tổng quan về người chiến thắng theo ngôn ngữ.

Để đảm bảo câu trả lời của bạn hiển thị, vui lòng bắt đầu câu trả lời của bạn bằng một tiêu đề bằng cách sử dụng mẫu Markdown sau

## Language Name, N bytes

Trong đó N là kích thước, tính bằng byte, của trình của bạn

Nếu bạn muốn bao gồm nhiều số trong tiêu đề của mình (ví dụ: vượt qua các điểm số cũ hoặc bao gồm các cờ trong số byte), chỉ cần đảm bảo rằng điểm thực tế là số cuối cùng trong tiêu đề của bạn

## Language Name, <s>K</s> X + 2 = N bytes


Tôi nghĩ 288 nên đọc 281 : (1+0+0+1+2+3+1+0+0+0+4+1+0+0+1+2+3+2+0+0)*5+(2+0+4+0+4+0+6+0+0+0+2+1+4+3+0+3+10+0+5+0)*4=21*5+44*4=105+176=281(mặc dù tôi phải nói rằng tôi chưa đọc toàn bộ "bài luận"!)
Jonathan Allan

@Jonathan ALLan Yea ... Tôi đã vô tình dành quá nhiều thời gian để viết thử thách ... ôi ... Dù sao, điều quan trọng còn thiếu là xe trượt tuyết của ông già Noel phải đợi tất cả các yêu tinh trở lại trên tàu trước khi chuyển đến ngôi nhà tiếp theo, vì vậy mặc dù việc thêm tất cả các số lên và nhân chúng có thể hoạt động trong một số trường hợp, nhưng nó không hoạt động trong hầu hết. Ví dụ: với 9 yêu tinh, ngôi nhà 4*7mất 14 giây (bao phủ khoảng một nửa trong "bài luận", ngay trước khi bản đồ 2D được giới thiệu) nhưng (4 * 5) + (7 * 4) = 48
Jojodmo

Giá trị 288 là ví dụ với 3 yêu tinh, vì vậy họ luôn phải thực hiện toàn bộ cú đánh naughty*5+nice*4ở mỗi nhà, phải không? (lưu ý rằng không có 4*7trong ví dụ đó)
Jonathan Allan

Có phải các yêu tinh luôn lấy than ra khỏi đầu tiên (như trong ví dụ của bạn) hoặc họ lên lịch hiệu quả? Ví dụ: nếu bản đồ là 5*15và có 9yêu tinh thì sẽ mất (tối thiểu) 20 giây hay 22 giây? Xem các biểu diễn văn bản này để xem một minh họa về ví dụ đó.
Jonathan Allan

EDIT ở trên 5*15nên đọc 4*15.
Jonathan Allan

Câu trả lời:


4

Ruby , 433 400 byte

Chà, cái này thực sự khó, vì hóa ra yêu tinh lập kế hoạch là NP khó.

Ngoài ra, xin vui lòng, đây là lần gửi đầu tiên của tôi, vì vậy tôi có thể đã bỏ lỡ một số tối ưu hóa rõ ràng:

->e,h{h.split(/\+|\n/).map{|h|n,g=h.split(?*).map(&:to_i)+[0,0];return-1if(g>0&&e<2)||(n>0&&e<3);([[3,5]]*n+[[2,4]]*g).permutation.map{|j|c=[0]*e;j.map{|q|w,y=q;k=l=0;r=c.map{|x|a=b=0;c[k..e].map{|r|r<=x ?a+=1:break};(t=k+=1).times{c[t-=1]<=x ?b+=1:break};[a,b]};d=r.inject([]){|v,x|v<<l if x[0]>=w;l+=1;v}.min{|a,b|c[a]<=>c[b]};b=d-r[d][1]+1;z=c[d]+y;(b..(b+w-1)).map{|x|c[x]=z}};c.max}.min||0}.sum}

Hãy thử trực tuyến!

Ban đầu tôi có các trường hợp thử nghiệm dài hơn, nhưng vì tôi lặp đi lặp lại tất cả các hoán vị có thể có để lập lịch trình trong một số trường hợp phải mất nhiều thời gian, vì vậy tôi đã loại bỏ chúng.


2
Chào mừng đến với PPCG! Bạn chắc chắn đã chọn một thử thách khó khăn cho câu trả lời đầu tiên của mình
Jo King

2

Java (OpenJDK 8) , 344 byte

Lịch trình của Elf khó khăn hơn tôi nghĩ nên việc này mất một chút thời gian và khá dài.

Mặc dù vậy, đây chắc chắn là thử thách yêu thích của tôi để viết mã golf!

(e,d)->{int r=0,x,y,c,p,b,g,m;for(String h:d[0].split("\\+")){d=h.split("\\*",-1);b=new Byte("0"+d[0]);g=new Byte("0"+d[1]);m=-1>>>1;for(y=1;y<=e/3&(x=(e-y*3)/2)>0;c=b/y+(b%y++<1?0:1),p=g/x+(g%x<1?0:1),x=c*5>p*4?c*5:p*4,m=x<m?x:m);for(y=0;b+g>0;b-=c,g-=p){c=e/3<b?e/3:b;x=(e-c*3)/2;p=x<g?x:g;if(c+p<1)return-1;y+=c>0?5:4;}r+=m<y?m:y;}return r;}

Hãy thử trực tuyến (với tất cả các bài kiểm tra)!

Giải trình;

Tự ôm mình: Đó là một cái dài

    int r=0,x,y,c,p,b,g,m;               // Define all the variables I need

    for(String h:d[0].split("\\+")){     // Split houses on '+' and loop through them

        d=h.split("\\*",-1);             // Split the current house on '*' using the limit
                                         // to preserve empty strings.

        b=new Byte("0"+d[0]);            // Parse the naughty (b) and nice (g) people
        g=new Byte("0"+d[1]);

        m=-1>>>1;                        // Initialise minimum time as max integer using
                                         // overflow

        for(y=1;y<=e/3&(x=(e-y*3)/2)>0;  // For each number of elves that can concurrently
                                         // deliver coal, and still leave enough elves to
                                         // deliver presents

            c=b/y+(b%y++<1?0:1),         // Determine the number of runs needed to deliver
                                         // all coal using this number of elves

            p=g/x+(g%x<1?0:1),           // Determine the number of runs needed to deliver
                                         // all presents using this number of elves

            x=c*5>p*4?c*5:p*4,           // Get the maximum time required for the
                                         // delivery of coal or presents

            m=x<m?x:m);                  // If this is less than the current minimum time,
                                         // set it as the minimum time


        for(y=0;b+g>0;b-=c,g-=p){        // While there are still people to deliver to;

            c=e/3<b?e/3:b;               // Determine the max amount of coal to deliver

            x=(e-c*3)/2;                 // Determine how many presents can be
                                         // delivered with the remaining elves.

            p=x<g?x:g;                   // If this number is more than nice people
                                         // remaining, just use the nice people remaining

            if(c+p<1)return-1;           // If no presents can be delivered, return the
                                         // error code (-1)

            y+=c>0?5:4;                  // Increase the time by 5 if coal was
                                         // delivered, and 4 if only presents

        }                                // At the end of each loop (see above)
                                         // remove the presents and coal delivered
                                         // from the number of naughty and nice houses

        r+=m<y?m:y;                      // Increment the total time by which ever
                                         // is smaller of the calculated times
    }
    return r;                            // Return the total time

NB: Câu trả lời này phụ thuộc vào sự điều chỉnh của tôi đối với các trường hợp kiểm tra là chính xác


Tôi nghĩ (e-y*3)/2-> e-y*3>>1tiết kiệm một byte. (Nhiều khả năng cũng có thể áp dụng cho (e-c*3)/2.)
Jonathan Frech

runTest("1*4",5,12);thất bại (bạn hiểu "1*4", 5 elves => 13 FAILED. Tôi đã rất ngạc nhiên khi thuật toán của bạn rất tốt để lên lịch trong một vài byte, vì vậy tôi đã chạy nó với tất cả các kết hợp có thể từ 0 đến 7 (yêu tinh, nghịch ngợm và tốt đẹp) và chỉ tìm thấy một vài nơi mà nó không thành công Cho thời gian tối ưu. Đây là sự kết hợp nhỏ nhất đã thất bại. BTW, logic tuyệt vời để lên lịch, trong một thời gian dài tôi không biết bạn đã làm như thế nào.
elyalvarado
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.