Vấn đề cây cầu và ngọn đuốc


17

Cảm hứng cho câu đố golf mã là Bridge và Torch vấn đề , trong đó d người lúc bắt đầu của một cây cầu đều phải vượt qua nó trong thời gian ngắn nhất.

Điều hấp dẫn là nhiều nhất hai người có thể băng qua cùng một lúc, nếu không cây cầu sẽ đè bẹp dưới sức nặng của họ, và nhóm chỉ có quyền truy cập vào một ngọn đuốc, phải được mang theo để qua cầu.

Mỗi người trong toàn bộ câu đố có một thời gian xác định mà họ dành để đi bộ qua cầu. Nếu hai người giao nhau, cặp đôi đi chậm như người chậm nhất.

Không có số lượng người phải qua cầu; giải pháp của bạn PHẢI làm việc cho bất kỳ giá trị nào của d .

Bạn không cần sử dụng đầu vào tiêu chuẩn cho vấn đề này, nhưng để giải thích vấn đề, tôi sẽ sử dụng định dạng đầu vào và đầu ra sau đây để giải thích. Số đầu tiên, d , là số người ở đầu cầu. Sau đó, mã sẽ quét các số d , mỗi số đại diện cho tốc độ của một người.

Đầu ra mã sẽ là lượng thời gian HẤP DẪN nhất để vượt qua tất cả mọi người từ đầu cầu đến cuối cầu, trong khi đáp ứng các tiêu chí đã giải thích trước đó.

Dưới đây là một số trường hợp đầu vào và trường hợp đầu ra và giải thích cho trường hợp đầu vào đầu tiên. Tùy thuộc vào bạn để rút ra một thuật toán từ thông tin này để giải quyết vấn đề trong ít byte mã nhất có thể.

đầu vào

4
1 2 5 8

đầu ra

15

Để đạt được đầu ra này, người dân phải vượt qua theo cách sau.

A and B cross forward (2 minutes)
A returns (1 minute)
C and D cross forward (8 minutes)
B returns (2 minutes)
A and B cross forward (2 minutes)

Đây là một trường hợp thử nghiệm khác để hướng dẫn bạn trên con đường của bạn.

đầu vào

5
3 1 6 8 12

đầu ra

29

Quy tắc:

  1. Giả sử rằng đầu vào sẽ không được sắp xếp và bạn phải tự làm điều đó (nếu bạn cần)
  2. Số người trong câu đố không cố định ở 4 (N> = 1)
  3. Mỗi nhóm và cá nhân băng qua phải có một ngọn đuốc. Chỉ có một ngọn đuốc.
  4. Mỗi nhóm phải bao gồm tối đa chỉ có 2 người!
  5. Không, bạn không được nhảy khỏi cầu và bơi sang phía bên kia. Không có thủ đoạn nào khác như thế này;).

Như xnor tìm thấy bên dưới, hãy chắc chắn kiểm tra các trường hợp như 1 3 4 5, sẽ trả về 14 chứ không phải 15
vui mừng

1 4 5 6 7có một vấn đề tương tự. 25 so với 26
Sherlock9

1
Đây có vẻ là một câu hỏi kỳ lạ, nhưng số người tối thiểu và tối đa trong câu đố là bao nhiêu? Khi làm việc với các giải pháp của tôi, tôi nhận thấy rằng họ chỉ xử lý N >= 2mọi người (có nghĩa là, thật kỳ lạ khi đó là công việc phụ để xử lý trường hợp tầm thường của "1 người cần phải vượt qua"), vì vậy một số giải thích rõ ràng về điểm này sẽ rất tuyệt. Cảm ơn trước.
Sherlock9

@ Sherlock9 Giả sử giải pháp của bạn phải hoạt động cho N> = 1
baseman101

Các trường hợp thử nghiệm cho thấy rằng chúng ta có thể sử dụng độ dài làm tham số, nhưng bạn có thể làm rõ hơn trong quy tắc không? Là đầu vào được phép là mảng thời gian và số lượng người, hay chỉ là thời gian được phép?
Sherlock9

Câu trả lời:


8

Python 3, 100 99 byte

một giải pháp đệ quy

f=lambda s:s[0]+s[-1]+min(2*s[1],s[0]+s[-2])+f(s[:-2])if s.sort()or 3<len(s)else sum(s[len(s)==2:])

Cảm ơn @xnor cho bài viết này

Nhờ @lirtosiast lưu 2 byte, @movatica lưu 1 byte và @gladed chỉ ra rằng giải pháp trước đây của tôi không hoạt động

sử dụng mẹo sau đây để đánh giá một cái gì đó trong hàm lambda s.sort() or s ở đây chúng tôi tính toán sắp xếp và trả về kết quả của bài kiểm tras.sort()or len(s)>3

Bị đánh cắp

def f(s):
    s.sort()                                   # sort input in place
    if len(s)>3:                               # loop until len(s) < 3
        a = s[0]+s[-1]+min(2*s[1],s[0]+s[-2])  # minimum time according to xnor paper
        return  a + f(s[:-2])                  # recursion on remaining people
    else:
        return sum(s[len(s)==2:])              # add last times when len(s) < 3

Các kết quả

>>> f([3, 1, 6, 8, 12])
29
>>> f([1, 2, 5, 8])
15
>>> f([5])
5
>>> f([1])
1
>>> f([1, 3, 4, 5])
14

Bạn có thể lưu 1 byte và đổi len(s)==2thànhlen(s)<3
Mr Public

@MrPublic bạn tìm thấy một lỗi, tôi đã thay đổi giải pháp s[0]*(len(s)==2)không phải (s[0]*len(s)==2) là lỗi f([1]) -> 0mà tại sao chúng ta không thể thay thế bằng <3lời cảm ơn
Erwan

Bài viết này có một biểu thức cho thời gian tối ưu đó là tối thiểu của nhiều khả năng. Bạn có chắc chắn giải pháp của bạn là tối ưu trong mọi trường hợp?
xnor 17/03/2016

@xnor wow có vẻ như tôi có giải pháp tối ưu tôi sử dụng biểu thức trong Bổ đề 3A5:22
Erwan

1
@movatica cập nhật với bạn đề xuất
Erwan

4

Python 2, 119 114 112 119 110 100 95 byte

Tôi đã được khuyên nên tách câu trả lời của tôi ra.

Một giải pháp sử dụng Theorem 1, A2:09 giấy này xnor liên kết . Để trích dẫn bài báo (thay đổi nó thành zero-indexing):The difference between C_{k-1} and C_k is 2*t_1 - t_0 - t_{N-2k}.

lambda n,t:t.sort()or(n-3)*t[0]*(n>1)+sum(t)+sum(min(0,2*t[1]-t[0]-t[~k*2])for k in range(n/2))

Ungolfing:

def b(n, t): # using length as an argument
    t.sort()
    z = sum(t) + (n-3) * t[0] * (n>1) # just sum(t) == t[0] if len(t) == 1
    for k in range(n/2):
        z += min(0, 2*t[1] - t[0] - t[-(k+1)*2]) # ~k == -(k+1)
    return z

bạn có chắc chúng ta có thể cho rằng độ dài có thể là một đối số không?
Erwan

@Erwan Các trường hợp thử nghiệm ví dụ dường như cho phép nó. Tôi sẽ hỏi
Sherlock9

2

Ruby, 94 133 97 96 101 96 99 byte

Tôi đã được khuyên nên tách câu trả lời của tôi ra.

Đây là một giải pháp dựa trên các thuật toán được mô tả trong A6:06-10các tài liệu này trên cầu và Torch vấn đề .

Chỉnh sửa: Sửa một lỗi a=s[0]chưa được xác định khi ađược gọi ở cuối if s.size <= 3.

->s{r=0;(a,b,*c,d,e=s;r+=a+e+[b*2,a+d].min;*s,y,z=s)while s.sort![3];r+s.reduce(:+)-~s.size%2*s[0]}

Ungolfing:

def g(s)
  r = 0
  while s.sort![3]      # while s.size > 3
    a, b, *c, d, e = s  # lots of array unpacking here
    r += a + e + [b*2, a+d].min
    *s, y, z = s        # same as s=s[:-2] in Python, but using array unpacking
  end
  # returns the correct result if s.size is in [1,2,3]
  return r + s.reduce(:+) - (s.size+1)%2 * s[0]
end

1

Scala, 113 135 (darnit)

def f(a:Seq[Int]):Int={val(s,b)=a.size->a.sorted;if(s<4)a.sum-(s+1)%2*b(0)else b(0)+Math.min(2*b(1),b(0)+b(s-2))+b(s-1)+f(b.take(s-2))}

Ungolfed phần nào:

def f(a:Seq[Int]):Int = {
    val(s,b)=a.size->a.sorted      // Sort and size
    if (s<4) a.sum-(s+1)%2*b(0)    // Send the rest for cases 1-3
    else Math.min(b(0)+2*b(1)+b(s-1),2*b(0)+b(s-2)+b(s-1)) + // Yeah.
        f(b.take(s-2))             // Repeat w/o 2 worst
}

Kiểm thử:

val tests = Seq(Seq(9)->9, Seq(1,2,5,8)->15, Seq(1,3,4,5)->14, Seq(3,1,6,8,12)->29, Seq(1,5,1,1)->9, Seq(1,2,3,4,5,6)->22, Seq(1,2,3)->6, Seq(1,2,3,4,5,6,7)->28)
println("Failures: " + tests.filterNot(t=>f(t._1)==t._2).map(t=>t._1.toString + " returns " + f(t._1) + " not " + t._2).mkString(", "))

Nói chung không tuyệt vời, nhưng có lẽ không tệ đối với một ngôn ngữ được gõ mạnh. Và bắt đầu cảm ơn xnor vì đã phát hiện ra một trường hợp tôi không bắt được.


Bài viết này có một biểu thức cho thời gian tối ưu đó là tối thiểu của nhiều khả năng. Bạn có chắc chắn giải pháp của bạn là tối ưu trong mọi trường hợp?
xnor 17/03/2016

1

Ruby, 104 95 93 byte

Tôi đã được khuyên nên tách câu trả lời của tôi ra.

Đây là một giải pháp dựa trên giải pháp Python 2 của tôiTheorem 1, A2:09của bài viết này về Vấn đề Cầu và Ngọn đuốc .

->n,t{z=t.sort!.reduce(:+)+t[0]*(n>1?n-3:0);(n/2).times{|k|z+=[0,2*t[1]-t[0]-t[~k*2]].min};z}

Ungolfing:

def b(n, t) # using length as an argument
  z = t.sort!.reduce(:+) + t[0] * (n>1 ? n-3 : 0)
  (n/2).times do each |k|
    a = t[1]*2 - t[0] - t[-(k+1)*2] # ~k == -(k+1)
    z += [0, a].min
  end
  return z
end
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.