Das Brücken- und Fackelproblem

17

Die Inspiration für diesen Code Golf Puzzle ist die Brücke und Torch Problem , bei dem d Menschen am Anfang einer Brücke alle es in der geringsten Menge an Zeit überqueren müssen.

Der Haken ist, dass höchstens zwei Personen gleichzeitig überqueren können, da sonst die Brücke unter ihrem Gewicht zusammenbricht und die Gruppe nur Zugang zu einer Fackel hat, die getragen werden muss, um die Brücke zu überqueren.

Jede Person im gesamten Puzzle hat eine bestimmte Zeit, die sie benötigt, um über die Brücke zu gehen. Wenn sich zwei Personen kreuzen, ist das Paar genauso langsam wie die langsamste Person.

Es gibt keine festgelegte Anzahl von Personen, die die Brücke überqueren müssen. Ihre Lösung muss für jeden Wert von d funktionieren .

Sie müssen für dieses Problem keine Standardeingabe verwenden, aber um das Problem zu erläutern, verwende ich das folgende Eingabe- und Ausgabeformat für die Erläuterung. Die erste Zahl, d , ist die Anzahl der Personen am Beginn der Brücke. Anschließend sucht der Code nach d- Nummern, die jeweils die Geschwindigkeit einer Person darstellen.

Die Code-Ausgabe ist die LEISTE Zeit, die erforderlich ist, um alle Benutzer vom Beginn der Brücke bis zum Ende der Brücke zu überqueren, wobei die zuvor erläuterten Kriterien erfüllt werden.

Hier sind einige Eingabe- und Ausgabefälle sowie die Erklärung für den ersten Eingabefall. Es liegt an Ihnen, einen Algorithmus aus diesen Informationen abzuleiten, um das Problem in möglichst wenigen Byte Code zu lösen.

Eingang

4
1 2 5 8

Ausgabe

15

Um diesen Ausgang zu erreichen, müssen die Menschen auf folgende Weise kreuzen.

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)

Hier ist ein weiterer Testfall, der Sie auf Ihrem Weg führt.

Eingang

5
3 1 6 8 12

Ausgabe

29

Regeln:

  1. Angenommen, die Eingabe wird nicht sortiert, und Sie müssen dies selbst tun (falls erforderlich).
  2. Die Anzahl der Personen im Puzzle ist nicht auf 4 festgelegt (N> = 1)
  3. Jede Gruppen- und Einzelkreuzung muss eine Fackel haben. Es gibt nur eine Fackel.
  4. Jede Gruppe darf maximal aus 2 Personen bestehen!
  5. Nein, Sie dürfen nicht von der Brücke springen und auf die andere Seite schwimmen. Keine anderen Tricks wie diese;).
baseman101
quelle
Wie von xnor unten festgestellt, sollten Sie Fälle wie " 1 3 4 514" und "15"
testen
1 4 5 6 7hat ein ähnliches problem. 25 vs. 26
Sherlock9
1
Dies scheint eine seltsame Frage zu sein, aber wie viele Personen sind mindestens und maximal im Puzzle? Als ich an meinen Lösungen arbeitete, bemerkte ich, dass sie nur mit N >= 2Menschen umgehen (was seltsamerweise bedeutet, dass es zusätzliche Arbeit ist, den trivialen Fall "1 Person muss sich kreuzen" zu behandeln). Daher wäre eine Klarstellung in diesem Punkt sehr hilfreich. Danke im Voraus.
Sherlock9
@ Sherlock9 Angenommen, Ihre Lösung muss für N> = 1
funktionieren
Die Testfälle zeigen, dass wir die Länge als Parameter verwenden können, aber können Sie das in den Regeln klarer machen? Darf die Eingabe eine Reihe von Zeiten und die Anzahl der Personen sein oder sind nur die Zeiten zulässig?
Sherlock9

Antworten:

8

Python 3, 100 99 Bytes

eine rekursive Lösung

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

Vielen Dank an @xnor für diesen Artikel

Dank @lirtosiast 2 Bytes sparen, @movatica 1 Bytes sparen und @gladed darauf hinweisen, dass meine vorherige Lösung nicht funktioniert

Verwenden Sie den folgenden Trick, um etwas in der Lambda-Funktion auszuwerten. s.sort() or s Hier berechnen wir die Sortierung und geben das Ergebnis des Tests zurücks.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

Ergebnisse

>>> 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
Erwan
quelle
Sie können 1 Byte speichern und um len(s)==2len(s)<3
Mr Public
@ MrPublic Sie finden einen Fehler, ich habe die Lösung geändert, es ist s[0]*(len(s)==2)nicht (s[0]*len(s)==2) mit dem Fehler f([1]) -> 0, warum wir nicht durch <3Dank ersetzen können
Erwan
Dieses Papier enthält einen Ausdruck für die optimale Zeit, die aus einer Vielzahl von Möglichkeiten besteht. Sind Sie sicher, dass Ihre Lösung in allen Fällen optimal ist?
xnor
@xnor wow es scheint, dass ich die optimale Lösung habe Ich verwende den Ausdruck in Lemma 3A5:22
Erwan
1
@Movatica Update mit Ihrem Vorschlag
Erwan
4

Python 2, 119 114 112 119 110 100 95 Bytes

Mir wurde geraten, meine Antworten zu trennen.

Eine Lösung unter Verwendung Theorem 1, A2:09 dieses Papiers ist nicht verlinkt . So zitieren Sie das Papier (indem Sie es auf Null-Indexierung ändern):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
Sherlock9
quelle
Sind Sie sicher, dass wir davon ausgehen können, dass Länge ein Argument sein kann?
Erwan
@Erwan Die Beispiel-Testfälle scheinen dies zu ermöglichen. Ich werde fragen
Sherlock9
2

Ruby, 94 133 97 96 101 96 99 Bytes

Mir wurde geraten, meine Antworten zu trennen.

Dies ist eine Lösung auf dem Algorithmus in beschrieben anhand A6:06-10von dieser Arbeit auf der Brücke und Fackel Problem .

Bearbeiten: Behebung eines Fehlers, bei dem a=s[0]noch nicht definiert ist, wann aam Ende if aufgerufen wird 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
Sherlock9
quelle
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))}

Etwas ungolfed:

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
}

Prüfer:

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

Im Allgemeinen nicht besonders gut, aber für eine stark typisierte Sprache vielleicht nicht schlecht. Und danke an xnor, dass er einen Fall entdeckt hat, den ich nicht verstanden habe.

froh
quelle
Dieses Papier enthält einen Ausdruck für die optimale Zeit, die aus einer Vielzahl von Möglichkeiten besteht. Sind Sie sicher, dass Ihre Lösung in allen Fällen optimal ist?
xnor
1

Ruby, 104 95 93 Bytes

Mir wurde geraten, meine Antworten zu trennen.

Dies ist eine Lösung, die auf meiner Python 2-Lösung basiert und Theorem 1, A2:09von dieser Arbeit auf der Brücke und Fackel Problem .

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