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.


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)

1
Miły. Dla twojego wyjaśnienia myślę, że masz na myśli maksymalny drugi szybki.
Nick Kennedy

Tak, zrobiłem.
Jonathan Allan,


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)


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


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,


więc tak, nie można zakodować na stałe długości
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)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.