Es ist wieder Halloween!

10

Problembeschreibung

Wir alle lieben einen Twix (weil er die beste Süßigkeit ist), aber dies ist das erste Halloween der Kinder - wir müssen mindestens eine Süßigkeit von jeder Art für sie kaufen. An jedem Halloween senden alle Bewohner der Numberline Avenue eine E-Mail, in der sie angeben, welche Arten von Süßigkeiten sie dieses Jahr verschenken werden.

Oh! Und wir leben in einer 1D-Welt.

Da wir in gewisser Hinsicht außergewöhnlich faul und in anderer Hinsicht nicht faul sind, haben wir eine Karte der Häuser erstellt, in der ihre Positionen entlang der Straße angegeben sind. Wir haben auch die Arten von Süßigkeiten notiert, die sie haben. Hier ist die Karte, die wir für dieses Jahr erstellt haben:

 [(-2, {"Kisses", "KitKats"}),
 (1, {"KitKats", "Peanut Butter Cups"}),
 (6, {"Kisses", "Twix"}),
 (9, {"Skittles"}),
 (10, {"Twix"})]

Um den kleinen Beinen der Kinder willen müssen wir den kürzesten Weg finden, der bei jedem Haus in der Nachbarschaft beginnt, um mindestens eine von jeder Art von Süßigkeiten zu sammeln .

Beispiele

Auf Wunsch einiger Benutzer (einschließlich Shaggy) werde ich einige Beispiele einbringen. Hoffentlich klärt das die Dinge auf. :) Eingabe:

 [(-2, {"Kisses", "KitKats"}),
 (1, {"KitKats", "Peanut Butter Cups"}),
 (6, {"Kisses", "Twix"}),
 (9, {"Skittles"}),
 (10, {"Twix"})]

Ausgabe:

[1, 2, 3]

Eine weitere Karte und Lösung ...

Eingang:

[(-3, {"KitKats", "Twix"}),
(-1, {"Hundred Grands"}),
(3, {"Kisses"}),
(12, {"Hundred Grands", "Twix", "KitKats"})]

Ausgabe :

[0, 1, 2]

Wir könnten an der Koordinate 9 beginnen, wo wir Süßigkeiten sammeln, bis zu den Häusern 6 und 1. Das füllt die Süßigkeitenquote, indem wir 8 Einheiten laufen, aber ist es die kürzeste Lösung?

Regeln

Die Einträge müssen ein ähnlich strukturiertes Einzelargument für das Beispiel enthalten und die Indizes der zu besuchenden Häuser in kürzester Zeit ausgeben.

Es gelten die typischen Code-Golfregeln: Die kürzeste korrekte Lösung in Bytes gewinnt!

PS Dies war eine Interviewfrage, die mir von einem der weltweit größten Technologieunternehmen gestellt wurde. Wenn Sie nicht gerne Golf spielen, versuchen Sie, eine O (k * n) -Zeitlösung zu finden, bei der k die Anzahl der Bonbontypen und n die Anzahl der Häuser ist.

Bearbeiten

Wie Jonathon Allan betonte, besteht eine gewisse Verwirrung darüber, was "Indizes" in diesem Fall bedeuten. Wir wollen die Hauspositionen in der Argumentliste ausgeben und nicht ihre Koordinaten auf der Spur.

Qfwfq
quelle
6
Dies erfordert ein funktionierendes Beispiel und einige Testfälle.
Shaggy
2
Können wir zwei Argumente annehmen? eine Liste der Hausnummern und eine entsprechende Liste der Bonbonsorten?
Adám
1
@ KevinCruijssen Weder: Ausgabe der Indizes der zu besuchenden Häuser in der kürzesten Lösung
Adám
2
Ich nahm an, dass "Indizes" und "Positionen" synonym sind (dh dass die Adressen auf der Numberline Avenue das sind, was wir zurückgeben sollten). Ist das falsch?
Jonathan Allan
1
@ KevinCruijssen Tolle Fragen! Die Nummern sind in der Eingabe garantiert in Ordnung. Und ich erlaube die Annahme, dass die Zeichenfolgen keine Ziffern enthalten, da alle Süßigkeiten, die ich mit Zahlen kenne, sie buchstabieren (Hundert Grands und Drei Musketiere). :)
Qfwfq

Antworten:

3

Gelee , 16 Bytes

ŒPṪ€ẎQLƲÐṀẎISƊÞḢ

Ein monadischer Link, der die Eingabe akzeptiert, wie in einer Liste beschrieben, die vom niedrigsten zum höchsten Haus in der Numberline Avenue sortiert ist (wenn wir eine Bestellung annehmen müssen, können wir ein vorangestelltes ), das den kürzesten Weg ergibt, der beim Haus mit der niedrigsten Nummer beginnt und die Avenue hinauf fährt.

Probieren Sie es online aus!

Wenn wir alle diese kürzesten Pfade finden wollen, ersetzen Sie die nachfolgenden Bytes ÞḢdurch ÐṂ; Dies ist auch 16 Bytes.

Wie?

ŒPṪ€ẎQLƲÐṀẎISƊÞḢ - Link: list of [index, candies]
ŒP               - power-set
        ÐṀ       - keep those for which this is maximal:
       Ʋ         -   last four links as a monad:
  Ṫ€             -     tail €ach -- this removes the candies lists from the current list
                 -                  and yields them for use now
    Ẏ            -     tighten (to a flat list of candies offered by these hoses)
     Q           -     de-duplicate (get the distinct candies offered)
      L          -     length (how many distinct candies are on offer)
              Þ  - sort (now just the indexes of remaining sets due to Ṫ) by:
             Ɗ   -   last three links as a monad:
          Ẏ      -     tighten (to a flat list of indexes since Ṫ leaves a list behind)
           I     -     incremental differences (distances between houses)
            S    -     sum
               Ḣ - head (get the first)
Jonathan Allan
quelle
1
Nett. Für Ihre Erklärung denke ich, Sie meinen maximal für die Sekunde schnell.
Nick Kennedy
Ja, das habe ich getan.
Jonathan Allan
3

Python 2 , 133 130 127 Bytes

def f(l):r=range(len(l));v,c=zip(*l);print min((v[j]-v[i],r[i:j+1])for i in r for j in r if s(*c)==s(*c[i:j+1]))[1]
s={0}.union

Probieren Sie es online aus!

TFeld
quelle
2

05AB1E , 22 Bytes

æʒ€θ˜I€θ˜åP}€€нD€¥OWQÏ

Angenommen, die Zahlen in der Eingabeliste sind vom niedrigsten zum höchsten sortiert.
Wenn mehr als eine Lösung gefunden wird, werden alle ausgegeben.

Probieren Sie es online aus.

Erläuterung:

æ            # Get the powerset (all possible combinations) of the (implicit) input-list
 ʒ           # Filter this list of combinations by:
  €θ         #  Get the last items of each (the list of strings)
    ˜        #  Flatten the list
  I          #  Get the input-list again
   €θ˜       #  Get the last items of each (the list of strings) flattened as well
      å      #  Check for each if it is in the list of strings of this combination
       P     #  Check if all are present
 }           # Close the filter (we now have all combinations, containing all unique strings)
  €€н        # Only leave the first items of each item in the combination (the integers)
     D       # Duplicate this list
      €¥     # Get the deltas (forward differences) of each
        O    # Sum these deltas
         W   # Get the lowest sum (without popping the list)
          Q  # Check for each if it's equal to this minimum
           Ï # And only leave the list of integers at the truthy indices
             # (which are output implicitly as result)
Kevin Cruijssen
quelle
0

Haskell , 343 372 Bytes

Dank @ ASCII-only für Verbesserungen gibt es auch eine 271-Byte-Variante, die er in den Kommentaren vorgeschlagen hat :)

import Data.List
import Data.Function
f s=subsequences(map(\a@(x,y)->(x,y,[(a`elemIndices`s)!!0]))s)
g f s=if f*s<=0 then f+abs f+abs s else f+abs(f-s)
h=foldl(\(a,b,c)(d,e,f)->(g a d,nub(b++e),c++f))(0,[],[])
i s=map h(filter(not.null)s)
l m=filter(\(_,x,_)->length x==(maximum$map(\(_,x,_)->length x)m))m
m=minimumBy(compare`on`(\(p,_,_)->p))
n s=(\(_,_,l)->l)$m$l$i$f s

Probieren Sie es online aus!


Ungolfed

import Data.List
import Data.Function

allPaths :: [(Integer, [String])] -> [[(Integer, [String], [Int])]]
allPaths xs = subsequences(map (\a@(x,y) -> (x,y,[(a`elemIndices`s) !! 0])) s)

pathLength :: Integer -> Integer -> Integer
pathLength f s = if f*s <= 0 then f + abs f + abs s else f + abs(f - s)

traversePath :: [(Integer, [String], [Int])] -> (Integer, [String], [Int])
traversePath = foldl (\(n1, a1, c1) (n2, a2, c2) -> (pathLength n1 n2, nub (a1 ++ a2), c1 ++ c2)) (0, [], [])

allTraversedPaths :: [[(Integer, [String], [Int])]] -> [(Integer, [String], [Int])]
allTraversedPaths xs = map traversePath (filter (not . null) xs)

getCompletePaths :: [(Integer, [String], [Int])] -> [(Integer, [String], [Int])]
getCompletePaths m = filter (\(_,x,_) -> length x == ( maximum $ map (\(_,x,_) -> length x) m)) m

getFastestPath :: [(Integer, [String], [Int])] -> (Integer, [String], [Int])
getFastestPath = minimumBy (compare `on` (\(p, _, _) -> p))

getPath :: [(Integer, [String])] -> (Integer, [String], [Int])
getPath xs = (\(_,_,l) -> l) getFastestPath $ getCompletePaths $ allTraversedPaths $ allPaths xs

Erster Versuch

Fehler
quelle
Sie sollten nur das dritte Element dieses Tupels zurückgeben, und Sie haben nach Ihren Importen eine überflüssige neue Zeile
ASCII-nur
315? (müssen aber immer noch nur das dritte Element zurückgeben)
Nur ASCII
Naja,
ASCII-only
Also ja, Sie können die Länge nicht fest codieren
ASCII
358
ASCII-
0

O (k * n) Zeitlösung mit O (k * n) Raum

xii0i<nxicii

i1j1i0<i1i0j0i0j0

Unser Algorithmus lautet also:

// A[k] is the number of each candy we get from the first k houses
A := array of n bags
A[0] := {}
for k := 0 to n - 1
  A[k] := A[k - 1] + c[k - 1]
end
best_distance := ∞
best_i := -1
best_j := -1
// Find the range [i, j] such that we get all candy types
j := n
for i := n - 1 to 0
  while j > i and (A[j - 1] - A[i]) has all candy types
    j := j - 1
  end
  if (A[j] - A[i]) does not have all candy types then continue end
  distance = x[j - 1] - x[i]
  if distance < best_distance then
    best_distance = distance
    best_i = i
    best_j = j
  end
end
return best_i ..^ best_j

AO(k)O(nk)nnnO(n)O(nk)O(k)O(nk)

bb94
quelle