Köprü ve Meşale Sorunu


17

Bu kod golf bulmaca için ilham kaynağıdır Köprü ve Meşale sorun olduğu, d köprü başında insanlar her zaman en az miktarda de geçip gerekir.

Yakalama, en fazla iki kişinin aynı anda geçebileceği, aksi takdirde köprü ağırlıklarının altında ezilecek ve grubun köprüyü geçmek için taşınması gereken sadece bir meşale erişimi var.

Tüm bulmacanın her insanı, köprüden yürümek için belirli bir zamana sahiptir. İki kişi birlikte geçerse, çift en yavaş kişi kadar yavaş gider.

Köprüden geçmesi gereken belirli sayıda insan yoktur; çözümünüz herhangi bir d değeri için ZORUNLU olmalıdır .

Bu sorun için standart girdi kullanmanız gerekmez, ancak sorunu açıklamak için, açıklama için aşağıdaki giriş ve çıkış biçimini kullanacağım. İlk sayı olan d , köprünün başlangıcındaki kişi sayısıdır. Daha sonra kod , her biri bir kişinin hızını temsil eden d numaraları tarar .

Kod çıktısı, daha önce açıklanan kriterleri karşılarken, köprünün başından köprünün sonuna kadar herkesi geçmek için gereken EN AZ süre olacaktır.

İşte bazı giriş durumları ve çıkış durumları ve ilk giriş durumunun açıklaması. Sorunu mümkün olan en az bayt kodda çözmek için bu bilgilerden bir algoritma türetmek size kalmıştır.

giriş

4
1 2 5 8

çıktı

15

Bu çıktıya ulaşmak için, insanlar şu şekilde geçmelidir.

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)

İşte size yol boyunca rehberlik edecek başka bir test örneği.

giriş

5
3 1 6 8 12

çıktı

29

Kurallar:

  1. Girişin sıralanmayacağını ve bunu kendi başınıza yapmanız gerektiğini varsayalım (gerekirse)
  2. Bulmacadaki kişi sayısı 4'te sabit değil (N> = 1)
  3. Her grupta ve bireysel geçişte bir meşale bulunmalıdır. Sadece bir meşale var.
  4. Her grup en fazla 2 kişiden oluşmalıdır!
  5. Hayır, köprüden atlayıp diğer tarafa yüzemezsiniz. Bunun gibi başka hile yok;).

Aşağıdaki xnor tarafından tespit edildiği gibi 1 3 4 5, 14 değil 15 döndürmelidir gibi vakaları test ettiğinizden emin olun .
Mart'ta

1 4 5 6 7benzer bir sorunu var. 25
Sherlock9

1
Bu tuhaf bir soru gibi görünüyor, ama bulmacadaki minimum ve maksimum insan sayısı nedir? Çözümlerim üzerinde çalışırken, sadece N >= 2insanları ele aldıklarını fark ettim (yani, garip bir şekilde "1 kişinin geçmesi gerekiyor" önemsiz durumunu ele almak için ekstra bir iş), bu nedenle bu konuda bazı açıklamalar harika olurdu. Şimdiden teşekkürler.
Sherlock9

@ Sherlock9 Çözümünüzün N> = 1 için çalışması gerektiğini varsayalım
baseman101

Test senaryoları, uzunluğu parametre olarak kullanabileceğimizi gösterir, ancak bunu kurallarda daha açık hale getirebilir misiniz? Girdinin, zaman dizisi ve kişi sayısı olmasına izin veriliyor mu, yoksa yalnızca izin veriliyor mu?
Sherlock9

Yanıtlar:


8

Python 3, 100 99 bayt

özyinelemeli bir çözüm

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

Teşekkür için @xnor için bu yazıda

@Lirtosiast 2 bayt kaydetme, @movatica 1 bayt kaydetme ve önceki çözümümün çalışmadığını gösteren @gladed işaret sayesinde

lambda fonksiyonundaki bir şeyi değerlendirmek için aşağıdaki hileyi kullanın s.sort() or s burada sıralıyoruz ve testin sonucunu döndürüyoruzs.sort()or len(s)>3

Ungolfed

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

Sonuçlar

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

Sen 1 byte ve değişim kaydedebilirsiniz len(s)==2içinlen(s)<3
Bay Kamu

Eğer bir hata bulmak @MrPublic, ben öyle bir çözüm değişti s[0]*(len(s)==2)değil (s[0]*len(s)==2) böcekle f([1]) -> 0biz tarafından yerini alamaz bu yüzden <3teşekkür
Erwan

Bu makalede , en uygun zamanın birden fazla olasılığın minimumu olan bir ifade vardır. Çözümünüzün her durumda optimum olduğundan emin misiniz?
xnor

@xnor wow, Lemma 3'teki ifadeyi kullandığım optimal çözüme sahip olduğum anlaşılıyorA5:22
Erwan

1
@movatica size öneri ile güncelleme
Erwan

4

Piton 2, 119 114 112 119 110 100 95 bayt

Yanıtlarımı ayırmam tavsiye edildi.

Theorem 1, A2:09 Bağlantılı bu kâğıdın kullanıldığı bir çözüm . Kağıdı alıntılamak için (sıfır indeksleme olarak değiştirerek):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

bu uzunluğun bir argüman olabileceğini varsayabilir miyiz?
Erwan

@Erwan Örnek test senaryoları buna izin veriyor gibi görünüyor. Ben soracağım
Sherlock9

2

Yakut, 94 133 97 96 101 96 99 bayt

Yanıtlarımı ayırmam tavsiye edildi.

Bu tarif algoritmaya dayalı bir çözümdür A6:06-10ait Köprüsü ve Torch Problem bu yazıda .

Düzenleme: Eğer sonunda çağrıldığında a=s[0]henüz tanımlanmamış bir hatayı düzeltmek .as.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))}

Biraz çözülmedi:

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
}

Tester:

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(", "))

Genel olarak harika değil, ama güçlü bir dil için kötü değil. Ve yakalamadığım bir davayı tespit ettiği için xnor sayesinde yalvarıyorum.


Bu makalede , en uygun zamanın birden fazla olasılığın minimumu olan bir ifade vardır. Çözümünüzün her durumda optimum olduğundan emin misiniz?
xnor

1

Yakut, 104 95 93 bayt

Yanıtlarımı ayırmam tavsiye edildi.

Bu dayalı bir çözümdür benim Python 2 solüsyon ve Theorem 1, A2:09bir Köprüsü ve Torch Problem bu yazıda .

->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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.