È di nuovo Halloween!


10

Descrizione del problema

Adoriamo tutti un Twix (perché è la migliore caramella), ma questo è il primo Halloween dei bambini --- dobbiamo prendere almeno uno di ogni tipo di caramella per loro. Ogni Halloween tutti i residenti di Numberline avenue inviano un'e-mail che dice quali tipi di caramelle regaleranno quest'anno.

Oh! E viviamo in un mondo 1D.

Essendo eccezionalmente pigri in alcuni modi e non in altri, abbiamo creato una mappa delle case che ne indicano la posizione lungo la strada. Abbiamo anche notato i tipi di caramelle che hanno. Ecco la mappa che abbiamo realizzato per quest'anno:

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

Per il bene delle zampe dei bambini, dobbiamo trovare la passeggiata più breve che inizia in qualsiasi casa del quartiere per raccogliere almeno uno di ogni tipo di caramella.

Esempi

Su richiesta di un paio di utenti (incluso Shaggy), lancerò alcuni esempi funzionanti. Spero che questo chiarisca le cose. :) Ingresso:

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

Produzione:

[1, 2, 3]

Un'altra mappa e soluzione ...

Ingresso:

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

Uscita :

[0, 1, 2]

Potremmo iniziare dalla casa coordinata 9 che raccoglie caramelle alle case 6 e 1. Ciò riempie la quota di caramelle camminando per 8 unità, ma è la soluzione più breve?

Regole

Le voci devono contenere un singolo argomento strutturato in modo simile all'esempio e produrre gli indici delle case da visitare nella soluzione più breve.

Si applicano le regole tipiche del codice golf: vince la soluzione corretta più breve in byte!

PS Questa è stata una domanda di intervista che mi è stata data da una delle più grandi aziende tecnologiche del mondo. Se non ti piace il golf, prova a trovare una soluzione temporale O (k * n) in cui k è il numero di tipi di caramelle e n è il numero di case.

modificare

Come ha sottolineato Jonathon Allan, esiste una certa confusione sul significato degli "indici" in questo caso. Vogliamo produrre le posizioni delle case nell'elenco degli argomenti e non le loro coordinate sulla corsia.


6
Ciò richiede un esempio funzionante e alcuni casi di test.
Shaggy

2
Possiamo prendere due argomenti; un elenco di numeri civici e un corrispondente elenco di tipi di caramelle?
Adám

1
@KevinCruijssen Né: uscita degli indici delle case da visitare nella soluzione più breve
Adám

2
Supponevo che "indici" e "posizioni" fossero sinonimi (ovvero che gli indirizzi su Numberline Avenue sarebbero ciò che dovremmo restituire) è sbagliato?
Jonathan Allan

1
@KevinCruijssen Grandi domande! I numeri sono garantiti in ordine nell'input. E permetterò l'ipotesi che le stringhe non contengano cifre poiché tutte le caramelle che conosco con i numeri le spiegano (Centinaia e Tre Moschettieri). :)
Qfwfq

Risposte:


3

Gelatina , 16 byte

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

Un collegamento monadico che accetta l'input come descritto in un elenco ordinato dalle case Numberline Avenue dal più basso al più alto (se dobbiamo accettare qualsiasi ordine possiamo anteporre un ) che produce il percorso più breve partendo dalla casa con il numero più basso e viaggiando lungo il viale.

Provalo online!

Se vogliamo trovare tutti questi percorsi più brevi, sostituiamo i byte finali ÞḢ, con ÐṂ; questo è anche 16 byte.

Come?

Œ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
Bello. Per la tua spiegazione, penso che intendi il massimo per il secondo veloce.
Nick Kennedy

Sì, l'ho fatto.
Jonathan Allan,

3

Python 2 , 133 130 127 byte

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

Provalo online!


2

05AB1E , 22 byte

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

Presuppone che i numeri nell'elenco di input siano ordinati dal più basso al più alto.
Se viene trovata più di una soluzione, verranno prodotte tutte.

Provalo online.

Spiegazione:

æ            # 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 byte

Grazie a @ ASCII-only per miglioramenti, c'è anche una variante di 271 byte che ha proposto nei commenti :)

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

Provalo online!


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

Primo tentativo


dovresti restituire solo il terzo elemento di quella tupla e hai una nuova riga estranea dopo le tue importazioni
solo ASCII il

315? (deve comunque restituire solo il terzo elemento)
ASCII il


quindi sì, non puoi hardcodificare la lunghezza
solo ASCII


0

O (k * n) soluzione temporale, con O (k * n) spazio

xii0i<nxicii

i1j1i0<i1i0j0i0j0

Pertanto, il nostro algoritmo è:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.