Znowu Halloween!

10

opis problemu

Wszyscy uwielbiamy Twix (ponieważ jest to najlepszy cukierek), ale to jest pierwsze Halloween dla dzieci - musimy zdobyć dla nich przynajmniej jeden z każdego rodzaju cukierków. Każdego Halloween wszyscy mieszkańcy alei Numberline wysyłają e-mail z informacją, jakie rodzaje cukierków rozdadzą w tym roku.

O! I żyjemy w świecie 1D.

Będąc pod pewnymi względami wyjątkowo leniwymi, a nie innymi, stworzyliśmy mapę domów, podając ich pozycje wzdłuż ulicy. Zauważyliśmy również, jakie mają rodzaje cukierków. Oto mapa, którą stworzyliśmy na ten rok:

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

Ze względu na małe nogi dzieci musimy znaleźć najkrótszy spacer rozpoczynający się w dowolnym domu w okolicy, aby zebrać przynajmniej jeden z każdego rodzaju cukierków.

Przykłady

Na prośbę kilku użytkowników (w tym Kudłatego) podrzucę kilka sprawdzonych przykładów. Mam nadzieję, że to wszystko wyjaśni. :) Wejście:

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

Wynik:

[1, 2, 3]

Kolejna mapa i rozwiązanie ...

Wejście:

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

Wyjście :

[0, 1, 2]

Możemy zacząć od współrzędnych 9 domów zbierających cukierki w domach 6 i 1. To wypełnia limit cukierków, przechodząc 8 jednostek, ale czy jest to najkrótsze rozwiązanie?

Zasady

Wpisy muszą przyjmować podobnie ustrukturyzowany pojedynczy argument jak w przykładzie i generować wskaźniki domów do odwiedzenia w najkrótszym rozwiązaniu.

Obowiązują typowe zasady gry w golfa: wygrywa najkrótsze prawidłowe rozwiązanie w bajtach!

PS To było pytanie do wywiadu udzielone mi przez jedną z największych firm technologicznych na świecie. Jeśli nie lubisz golfa, spróbuj znaleźć rozwiązanie czasowe O (k * n), w którym k jest liczbą rodzajów cukierków, a n jest liczbą domów.

Edytować

Jak zauważył Jonathon Allan, istnieje pewne zamieszanie wokół tego, co w tym przypadku oznaczają „wskaźniki”. Chcemy wyprowadzić pozycje domów na liście argumentów, a nie ich współrzędne na linii.

Qfwfq
źródło
6
To wymaga sprawdzonego przykładu i niektórych przypadków testowych.
Shaggy
2
Czy możemy wziąć dwa argumenty; lista numerów domów i odpowiadająca im lista rodzajów cukierków?
Adám
1
@KevinCruijssen Żadne: wyprowadzaj indeksy domów do odwiedzenia w najkrótszym rozwiązaniu
Adám
2
Zakładałem, że „wskaźniki” i „pozycje” były synonimami (tzn. Że adresy na Numberline Avenue byłyby tym, co powinniśmy zwrócić), czy to źle?
Jonathan Allan
1
@KevinCruijssen Świetne pytania! Liczby są gwarantowane w kolejności na wejściu. I pozwolę sobie założyć, że struny nie zawierają cyfr, ponieważ wszystkie cukierki, które znam liczbami, je przeliterują (Sto Wróżek i Trzej Muszkieterowie). :)
Qfwfq,

Odpowiedzi:

3

Galaretka , 16 bajtów

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

Monadyczny link akceptujący dane wejściowe, zgodnie z opisem na liście posortowanej od domów od najniższej do najwyższej Numberline Avenue (jeśli musimy zaakceptować dowolne zamówienie, możemy dodać an ), który daje najkrótszą ścieżkę, zaczynając od domu o najniższym numerze i idąc w górę alei.

Wypróbuj online!

Jeżeli chcemy znaleźć wszystkie te najkrótsze ścieżki zastąpi bajtów spływu, ÞḢz ÐṂ; to także 16 bajtów.

W jaki sposób?

Œ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
źródło
1
Miły. Dla twojego wyjaśnienia myślę, że masz na myśli maksymalny drugi szybki.
Nick Kennedy
Tak, zrobiłem.
Jonathan Allan,
3

Python 2 , 133 130 127 bajtów

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

Wypróbuj online!

TFeld
źródło
2

05AB1E , 22 bajty

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

Zakłada, że ​​liczby na liście wprowadzania są posortowane od najniższej do najwyższej.
Jeśli zostanie znalezione więcej niż jedno rozwiązanie, wygeneruje je wszystkie.

Wypróbuj online.

Wyjaśnienie:

æ            # 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
źródło
1

Perl 6 , 70 bajtów

{grep({.[@^i;1]⊇.[*;1]},combinations ^$_).min:{[-] .[@^i[*-1,0];0]}}

Wypróbuj online!

nwellnhof
źródło
0

Haskell , 343 372 bajtów

Dzięki @ ASCII tylko dla ulepszeń, istnieje również wariant 271 bajtów, który zaproponował w komentarzach :)

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

Wypróbuj online!


Nie golfił

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

Pierwsze podejscie

błędy
źródło
powinieneś zwrócić tylko trzeci element tej krotki, a po imporcie masz obcy nowy wiersz
tylko ASCII
315? (wciąż muszę zwrócić tylko trzeci element)
tylko ASCII,
no cóż, właściwie ... to nawet nie działa na drugiej próbie
tylko ASCII,
więc tak, nie można zakodować na stałe długości
tylko ASCII
358
Tylko ASCII,
0

Rozwiązanie czasowe O (k * n) z przestrzenią O (k * n)

xjaja0ja<nxjadojaja

ja1jot1ja0<ja1ja0jot0ja0jot0

Zatem naszym algorytmem jest:

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

ZAO(k)O(nk)nnnO(n)O(nk)O(k)O(nk)

bb94
źródło