Esta tarea es generar la ruta más corta a un archivo, después de la expansión global.
¿Qué es el globbing de conchas? En la mayoría de los shells, puede usar el *personaje en una ruta para representar cualquier personaje en la posición. Por ejemplo, si el directorio foocontiene archivos bar bazy asdf, luego foo/b*se expandirá a foo/bar foo/baz.
Ahora, digamos que el directorio actual contiene un archivo llamado ihavealongnamey nada más. Si quiero hacer referencia a este archivo, podría escribir *, que representará solo ese archivo, en lugar de escribir el nombre completo.
Si el directorio también contiene un archivo llamado ialsohavealongname, no puedo hacerlo *, ya que coincidirá con ambos archivos. Lo que tendría que hacer, al menos ih*,.
El *patrón también funciona para hacer coincidir directorios sobre el archivo que estoy buscando. Si solo hay dos directorios fooy bar, pero foocontiene solo un archivo bazy barcontiene un archivo asdf, puedo coincidir foo/bazcon */baz. O, aún más concisamente */b*. Si barestuviera vacío, */*funcionaría.
Su tarea: Dada una serie de rutas de cadenas que representan el "directorio actual" y una ruta de destino única, genera la cadena más corta posible que se expandiría solo a esa ruta de destino después de expandir * s.
La ruta de destino se puede tomar como su propia cadena, como un índice en la matriz de rutas, como el primer elemento en la matriz de rutas pasadas, o de alguna otra manera conveniente que no sea codificación rígida. Pregunte en comentarios si no está seguro.
La ruta de destino está garantizada para estar presente en el "directorio actual".
Puede suponer que todas las rutas contienen solo ASCII alfanuméricos (y /s). Puede tomar como rutas de entrada que están enraizadas (comienzan con /) o relativas (no comienzan con /).
Si hay múltiples posibilidades igualmente cortas, devuelva una o todas ellas.
Este es el código de golf , ¡gana la menor cantidad de bytes!
Casos de prueba , gracias a Kevin Cruijssen .
fuente

*,?,[etc?*y ejecutaría Perlglobpara obtener todos los nombres de archivo que puedan ser relevantes (por ejemplo, sefoo/bar/bazconvierte en*/*/*). Después de eso se convierte en un desafío de procesamiento de cadenas. Y ese desafío ya es bastante difícil. Creo que este desafío sería más limpio ya que "dada una lista de/rutas alfanuméricas (y ) relativas, encuentre el globo más corto que coincida solo con esta ruta objetivo existentea*fpara seleccionarazzfdeazzf,azzg,bzzf. Extender a voluntad aa*b*cetc.Respuestas:
Perl 5 ,
136107102 bytesIncluye
+2paran0Dar una lista de archivos en STDIN. Se supone que el primero es el archivo de destino
Solo el código sin hacer que las nuevas líneas sean literales:
Se bloquea intencionalmente después de imprimir la solución.
Todavía parece demasiado largo (el uso de
$ay1/0son muy incómodos), pero es un comienzo y debería ser razonablemente eficiente.Pruébalo en línea!
Cómo funciona
El programa crea globos candidatos al crecerlos desde atrás hacia adelante, comenzando con la cadena vacía. Esto se hace de una primera forma de anchura, por lo que primero pegotes de longitud 0 se trató (sólo ``), a continuación, la longitud 1 (como
t,i,*), junto longitud 2 (comofb,i*,*g,**), junto longitud 3 y así sucesivamente hasta que una Se encuentra un globo que solo coincide con la primera ruta. Este será el globo más corto que resuelva el problema (pueden existir otros de la misma longitud).Los globos de longitud
n+1se generan a partir de los globos de longitudnanteponiendo cada personaje de la lista de caminos y también*delante de cada globo de longitudn. Así por ejemplo, longitud 3 pegote*i*contribuirá longitud de 4 globosf*i*,o*i*,o*i*,/*i*,b*i*...s*i*,t*i*y finalmente**i*. Tenga en cuenta que cada carácter de la lista de rutas de entrada se antepone incluso si aparece varias veces o no tiene ningún sentido porque conduce a algo que nunca puede coincidir.Hacer esto ingenuamente conduciría a una explosión combinatoria. Es por eso que cada glob candidato es evaluado por su utilidad al determinar en qué puntos de las rutas podría coincidir si el glob se usara al final de un glob completo. Hago esto insertando un
;en cada lugar donde es posible una coincidencia. Por ejemplo, para el globt*obtendré la cadena:Esto representa el "poder distintivo" del globo. Cada globo que tiene exactamente el mismo poder distintivo es igualmente bueno. Si los reemplaza uno al otro al final de un glob completo, todos coincidirán exactamente con los mismos caminos. Así que también puedes usar el más corto.
Entonces, al considerar los
nglobos de longitud , primero miro su poder distintivo. Si se ha visto antes, hubo otro globo de longitudno menor que ya se consideró y expandió, por lo que este globo no tiene sentido y se poda. Esto, por ejemplo, eliminará a candidatos como**i*ya se habrá visto el mismo poder distintivo*i*. También elimina candidatos imposibles,f*i*ya que la cadena distintiva no tendrá;y simplemente ser la lista original de caminos. Solo se aceptará el primer pegote imposible, se considerará que todos los demás tienen el mismo poder distintivo y se podarán. E incluso ese primero no se expandirá realmente, ya que todas las expansiones son aún imposibles y se podarán cuando se consideren. Simularmentein*será podado pori*etc.Lo anterior conduce a una poda muy agresiva y, por lo tanto, el programa puede manejar casos complejos en muy poco tiempo. Sin embargo, una gran ineficiencia es que antepone los globos candidatos con todos los caracteres posibles, no solo los que están justo antes de una parte
;en la ruta de destino de la cadena distintiva. Todos los caracteres añadidos que no están delante de un;no son un problema, ya que conducen a un globo imposible que se eliminará cuando se considere, pero que todavía deja a los personajes justo antes;en los otros caminos. Entonces, al final, el programa también crea globos que podrán combinar cualquier combinación de las rutas dadas. No tiene idea de que debería concentrarse en el primer camino.Ahora considere una solución al problema. En el ejemplo dado que podría ser
*/*er/t. Esto proporciona la siguiente cadena distintiva:Reconozco una solución al tener un
;en la primera posición (para que coincida con el primer camino) y no tener un;al comienzo de cualquier otro camino (para que los otros no coincidan)Con el algoritmo explicado, ahora llego al programa real:
Los globos globulares candidatos estarán en una matriz
@aque recorro usando una variable$aque contiene el globo que se está considerando actualmente.*Sin embargo, en lugar de en el globo, lo usaré, por\w*lo$aque en realidad es una expresión regular en lugar de un globo. Voy a abusar de una rareza del perl for loop que puede agregar elementos a la matriz que se está enlazando mientras el bucle se está ejecutando y estos nuevos elementos se recogerán en el bucle. Dado que al generar losn+1globos de longitud todos los globos de longitudnya están en la matriz,@aesto es primero la amplitud.Debido a la
-n0opción (bucle implícito sobre toda la entrada), la lista de rutas está en$_una sola cadena grande con cada ruta terminada con una nueva líneaDentro del
{ }tenemos:Vaya, acabo de destruirlo
$_y lo necesitaré para el próximo ciclo. Así que envuelva el código de trabajo real dentroEsto coincide con la cadena vacía al comienzo
$_y le permite ejecutar código para determinar con qué se reemplaza. Si me aseguro de que ese código se evalúe como la cadena vacía$_, al final permanecerá sin cambios incluso si cambio$_durantecode.Volviendo a justo después de que lo reemplazara
$_por la cadena distintiva:Esto es como:
//en perl es'defined or. Es como un corto circuitoordonde el segundo argumento solo se evalúa si el primero lo esundef. Y se puede combinar con una tarea como+=en otros idiomas. Así que si ellos clave$_en picadillo%seenesundef(que es es lo que obtienes cuando se accede a un elemento no existente) sólo entonces ejecutar expresión y asignarlo como valor en la clave$_. Entonces, si me aseguro deexpressionque no regrese,undefeso básicamente significa "evaluar la expresión si y solo si es la primera vez que vemos esa cadena distintiva en particular". Y debido a que$_se garantiza que contiene un\n, de hecho es seguro abusar del hash global de Perl para almacenar las cadenas distintivas, por lo que en$$_lugar de$seen{$_}Para el
expressionuso:Básicamente "Para cada carácter (excepto la nueva línea) en la cadena distintiva y también lo
*antepone al globo actual y lo empuja en el conjunto de globos candidatos". Excepto que utilizo\w*para*obtener una expresión regular válida (podría usar en''lugar de""deshacerme de una barra invertida pero no pude ejecutar mi código desde la línea de comandos). Tenga en cuenta que esto también recoge el;y los agrega a los globos globulares candidatos, pero cuando más tarde los pruebe en el restaurado$_que no tiene;eso, volverá a ser un globo imposible y se podará.Tenga en
/^;/>/\n;/cuenta que tiene un valor equivalente a la cadena vacía en caso de que aún no se encuentre una solución, por lo que funcionará como una cadena de reemplazo vacía y$_se restauraráfuente
-Eactiva el último nivel de idioma. Necesita al menos Perl5.10.0para poder usarsay. Así que ponuse 5.10.0;en la sección del encabezado y funcionará. Las opciones para establecer el nivel de idioma cuentan como gratuitas de todos modos, incluso si no pudieras hacerlo también usando-E. De hecho, todas las opciones cuentan como gratuitas hoy en día (por lo que ni siquiera tengo que contarn0), pero considero que es demasiado indulgente para Perl1/solución es válida. Necesito recordar eso también ...Java 10,
854824796738728703688655652647624 bytesQué desastre. Ciertamente, este no es un desafío fácil en Java.
Definitivamente se puede jugar un par de cientos de bytes, pero me alegra que finalmente esté funcionando ahora.Te lo dije. :)-5 bytes gracias a @ceilingcat .
-23 bytes cambiando de Java 8 a Java 10
Ingrese como un conjunto de cadenas de rutas de archivos (con directorios como elementos separados, y todos los elementos que contienen un inicio
/), y una cadena con la ruta de archivos de entrada para recortar.Explicación:
Pruébalo en línea. (Los casos de prueba con
ialsohavealongname/ihavealongnameaswelltienen una longitud ligeramente reducida ys.add(x.replaceAll("~+","\\*"));se han reemplazado{s.remove(x);s.add(x.replaceAll("~+","\\*"));}por trabajar en 5-10 segundos con TIO, en lugar de agotar el tiempo de espera después de más de 60 segundos).Explicación general adicional:
Ejemplo: tomemos
/foo, /foo/bar, /foo/barber, /foo/bar/test, /foo/barber/test, /foo/barber/testing, /foo/barber/coding, /foo/testcomo rutas de archivo dadas, yfoo/bar/testcomo ruta de entrada de archivo para recortar.1) Comienzo dividiendo la entrada de ruta de archivo por
/, y genero todos los recortes de archivo de estas palabras separadas:2) Luego genero todas las permutaciones con estas palabras en el mismo orden (volviendo a aplicar el
/intermedio y al frente):3) Luego hago un bucle sobre los elementos de esta lista anterior y valido si solo coincide con una única ruta de archivo en la matriz de entrada de rutas de archivo. (Hago esto marcando dos cosas: si la cantidad de barras es la misma y si coincide con la expresión regular donde
*se reemplaza cada una.*).Si lo hace: mantenga el (primero) más corto, que al final devolveremos.
fuente
>>>? Sé que>>es bitwise desplazamiento a la derecha.>>>actúa igual que>>. Pero para enteros negativos cambia el bit de paridad a 0 (puede ver algunos ejemplos aquí en la sección " >> vs >>> " ).-1>>>1es solo una variante más corta deInteger.MAX_VALUE(y1<<31seríaInteger.MIN_VALUE).