¡Es Halloween de nuevo!

10

Descripción del problema

Todos amamos un Twix (porque es el mejor dulce), pero este es el primer Halloween de los niños --- tenemos que agarrar al menos uno de cada tipo de dulce para ellos. Cada Halloween, todos los residentes de Numberline Avenue envían un correo electrónico diciendo qué tipos de dulces regalarán este año.

Oh! Y vivimos en un mundo 1D.

Siendo excepcionalmente perezosos en algunos aspectos y no en otros, hemos hecho un mapa de las casas dando sus posiciones a lo largo de la calle. También notamos los tipos de dulces que tienen. Aquí está el mapa que hicimos para este año:

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

Por el bien de las patitas de los niños, necesitamos encontrar la caminata más corta que comience en cualquier casa del vecindario para recolectar al menos uno de cada tipo de dulce.

Ejemplos

A petición de un par de usuarios (incluido Shaggy), agregaré algunos ejemplos prácticos. Esperemos que esto aclare las cosas. :) Entrada:

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

Salida:

[1, 2, 3]

Otro mapa y solución ...

Entrada:

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

Salida :

[0, 1, 2]

Podríamos comenzar en la casa de coordenadas 9 recolectando dulces en las casas 6 y 1. Eso llena la cuota de dulces caminando 8 unidades, pero ¿es la solución más corta?

Reglas

Las entradas deben incluir un argumento único estructurado de manera similar al ejemplo y generar los índices de las casas para visitar en la solución más corta.

Se aplican las reglas típicas del código de golf: ¡la solución correcta más corta en bytes gana!

PD: Esta fue una pregunta de entrevista que me hizo una de las compañías tecnológicas más grandes del mundo. Si no le gusta el golf, intente encontrar una solución de tiempo O (k * n) donde k es el número de tipos de dulces yn es el número de casas.

Editar

Como señaló Jonathon Allan, existe cierta confusión sobre lo que significa "índices" en este caso. Queremos generar las posiciones de las casas en la lista de argumentos y no sus coordenadas en el carril.

Qfwfq
fuente
66
Esto necesita un ejemplo trabajado y algunos casos de prueba.
Shaggy
2
¿Podemos tomar dos argumentos? una lista de números de casas y una lista correspondiente de tipos de dulces?
Adám
1
@KevinCruijssen Ninguno de los dos: generar los índices de las casas para visitar en la solución más breve
Adám,
2
Supuse que "índices" y "posiciones" eran sinónimos (es decir, que las direcciones en Numberline Avenue serían lo que deberíamos devolver) ¿está mal?
Jonathan Allan
1
@KevinCruijssen ¡Grandes preguntas! Los números están garantizados para estar en orden en la entrada. Y permitiré suponer que las cadenas no contienen dígitos, ya que todos los dulces que conozco con números los deletrean (Cien Grandes, y Tres Mosqueteros). :)
Qfwfq

Respuestas:

3

Jalea , 16 bytes

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

Un enlace monádico que acepta la entrada como se describe en una lista ordenada de las casas de Numberline Avenue más bajas a más altas (si necesitamos aceptar cualquier pedido podemos anteponer un ) que produce el camino más corto que comienza en la casa con el número más bajo y sube por la Avenida.

Pruébalo en línea!

Si queremos encontrar todos esos caminos más cortos reemplazan los bytes finales, ÞḢcon ÐṂ; Esto también es de 16 bytes.

¿Cómo?

Œ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
fuente
1
Agradable. Para su explicación, creo que quiere decir máximo para el segundo rápido.
Nick Kennedy
Sí, eso hice.
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

Pruébalo en línea!

TFeld
fuente
2

05AB1E , 22 bytes

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

Asume que los números en la lista de entrada están ordenados de menor a mayor.
Si se encuentra más de una solución, dará salida a todas ellas.

Pruébalo en línea.

Explicación:

æ            # 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
fuente
0

Haskell , 343 372 bytes

Gracias a @ ASCII-only por las mejoras, también hay una variante de 271 bytes que propuso en los comentarios :)

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

Pruébalo en línea!


Sin 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

Primer intento

loco
fuente
solo debe devolver el tercer elemento de esa tupla, y tiene una nueva línea extraña después de sus importaciones
solo ASCII el
315? (Sin embargo, todavía tengo que devolver el tercer elemento)
Solo ASCII
bueno, en realidad ... ni siquiera funciona en el segundo caso de prueba
solo ASCII el
así que sí, no puedes codificar la longitud
solo ASCII
358
Solo ASCII
0

Solución de tiempo O (k * n), con espacio O (k * n)

xii0i<nxicii

i1j1i0<i1i0j0i0j0

Por lo tanto, nuestro algoritmo es:

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