C'est encore Halloween!

10

Description du problème

Nous aimons tous un Twix (parce que c'est le meilleur bonbon), mais c'est le premier Halloween des enfants --- nous devons prendre au moins un de chaque type de bonbons pour eux. À chaque Halloween, tous les résidents de l'avenue Numberline envoient un e-mail indiquant les types de bonbons qu'ils donneront cette année.

Oh! Et nous vivons dans un monde 1D.

Étant exceptionnellement paresseux à certains égards et pas à d'autres, nous avons fait une carte des maisons indiquant leurs positions le long de la rue. Nous avons également noté les types de bonbons dont ils disposent. Voici la carte que nous avons faite pour cette année:

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

Pour le bien des petites jambes des enfants, nous devons trouver la marche la plus courte à partir de n'importe quelle maison du quartier pour recueillir au moins un bonbon de chaque type.

Exemples

À la demande de quelques utilisateurs (dont Shaggy), je vais lancer quelques exemples pratiques. Espérons que cela clarifie les choses. :) Entrée:

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

Production:

[1, 2, 3]

Une autre carte et solution ...

Contribution:

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

Sortie :

[0, 1, 2]

Nous pourrions commencer à la maison coordonnée 9 à ramasser des bonbons aux maisons 6 et 1. Cela remplit le quota de bonbons en marchant 8 unités, mais est-ce la solution la plus courte?

Règles

Les entrées doivent prendre un argument unique structuré de manière similaire à l'exemple et produire les indices des maisons à visiter dans la solution la plus courte.

Les règles de golf de code typiques s'appliquent: la solution correcte la plus courte en octets gagne!

PS C'était une question d'entrevue qui m'a été donnée par l'une des plus grandes entreprises technologiques du monde. Si vous n'aimez pas le golf, essayez de trouver une solution temporelle O (k * n) où k est le nombre de types de bonbons et n est le nombre de maisons.

Éditer

Comme l'a souligné Jonathon Allan, il existe une certaine confusion quant à la signification des «indices» dans ce cas. Nous voulons afficher les positions des maisons dans la liste des arguments et non leurs coordonnées sur la voie.

Qfwfq
la source
6
Cela a besoin d'un exemple fonctionnel et de certains cas de test.
Shaggy
2
Pouvons-nous prendre deux arguments; une liste de numéros de maison et une liste correspondante de types de bonbons?
2019
1
@KevinCruijssen Ni: afficher les indices des maisons à visiter dans la solution la plus courte
Adám
2
J'ai supposé que les "indices" et les "positions" étaient synonymes (c'est-à-dire que les adresses sur Numberline Avenue seraient celles que nous devrions renvoyer).
Jonathan Allan
1
@KevinCruijssen Grandes questions! Les numéros sont garantis dans l'ordre dans l'entrée. Et je vais permettre l'hypothèse que les cordes ne contiennent pas de chiffres comme tous les bonbons que je connais avec des chiffres les épelent (cent grands et trois mousquetaires). :)
Qfwfq

Réponses:

3

Gelée , 16 octets

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

Un lien monadique acceptant l'entrée comme décrit dans une liste triée des maisons de l'avenue Numberline les plus basses aux plus hautes (si nous devons accepter toute commande, nous pouvons ajouter une ) qui donne le chemin le plus court commençant à la maison numérotée la plus basse et remontant l'avenue.

Essayez-le en ligne!

Si nous voulons trouver tous ces chemins les plus courts, remplacez les octets de fin,, ÞḢpar ÐṂ; c'est aussi 16 octets.

Comment?

Œ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
la source
1
Agréable. Pour votre explication, je pense que vous voulez dire maximale pour le deuxième rapide.
Nick Kennedy
Oui, je l'ai fait.
Jonathan Allan
3

Python 2 , 133 130 127 octets

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

Essayez-le en ligne!

TFeld
la source
2

05AB1E , 22 octets

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

Suppose que les nombres dans la liste d'entrée sont triés du plus bas au plus élevé.
Si plusieurs solutions sont trouvées, elles sortiront toutes.

Essayez-le en ligne.

Explication:

æ            # 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
la source
1

Perl 6 , 70 octets

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

Essayez-le en ligne!

nwellnhof
la source
0

Haskell , 343 372 octets

Merci à @ ASCII uniquement pour les améliorations, il y a aussi une variante de 271 octets qu'il a proposée dans les commentaires :)

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

Essayez-le en ligne!


Non golfé

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

Premier essai

Bugs
la source
vous ne devez renvoyer que le troisième élément de ce tuple, et vous avez une nouvelle ligne superflue après vos importations
ASCII uniquement le
315? (mais je ne dois toujours renvoyer que le troisième élément)
ASCII uniquement
eh bien en fait ... cela ne fonctionne même pas sur le deuxième testcase
uniquement ASCII le
alors oui, vous ne pouvez pas coder en dur la longueur
ASCII uniquement
358
ASCII uniquement
0

Solution temporelle O (k * n), avec espace O (k * n)

xii0i<nxicii

i1j1i0<i1i0j0i0j0

Ainsi, notre algorithme est:

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