Desafío
Su tarea para esta pregunta es dividir una matriz de entrada de enteros en la segunda aparición de cada entero en esa matriz.
¿No está lo suficientemente claro? Aquí hay un ejemplo para ayudar
Matriz de entrada:
[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5]
Salida:
[[2 1] [] [3 2 2 4 5 6 7] [] [0] []]
Explicación:
Aquí está la matriz con solo el segundo elemento resaltado en negrita:
[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5 ]
Ahora colocamos los bloques de la matriz de división alrededor de estas segundas ocurrencias en negrita:
[2 1] 1 [] 2 [3 2 2 4 5 6 7] 3 [] 7 [0] 5 []
y envolver estas matrices divididas en una matriz para obtener el resultado final
[[2 1] [] [3 2 2 4 5 6 7] [] [0] []]
Tenga en cuenta que cuando ocurran segundas ocurrencias adyacentes, habrá matrices vacías.
Reglas
Como de costumbre, debe escribir un programa completo o una función que tome la matriz de entrada a través de STDIN, ARGV o argumento de función.
Entrada
La entrada consiste en cualquier formato de matriz conveniente (o tipo matriz) de enteros.
Por ejemplo, cualquiera de los siguientes sería aceptable:
2 1 1 1 4 5 6
[2 1 1 1 4 5 6]
[2, 1, 1, 1, 4, 5, 6]
Salida
Al salir a STDOUT, su matriz también se puede imprimir en cualquier formato conveniente (anidado) de matriz, por ejemplo, uno de
[[2 1] [1 4 5 6]]
[[2, 1], [1, 4, 5, 6]]
{{2, 1}, {1, 4, 5, 6}}
(Esta suele ser la representación de cadenas nativas de matrices en su idioma).
También tenga en cuenta que las matrices vacías finales deben imprimirse como parte de la matriz.
Puntuación
Este es el código de golf, ¡el código más corto en bytes gana!
""
como la matriz vacía? Esto huele a favoritismo hacia un lenguaje de golf específico.2 1, 1 4 5 6
?Respuestas:
APL 25
Ejemplo:
El viejo:
Esta es una buena pregunta para el operador clave (⌸) que se introdujo con Dyalog APL v14. Toma la función de argumento izquierdo ({1 ↑ 1 ↓ ⍵}) y le da para cada argumento único, los índices en el vector para ese argumento. Aquí estoy tomando el segundo índice, luego verifico cuál de los índices está presente en esta lista ((⍳⍴⍵) ∊) y uso el booleano resultante para dividir el vector original.
Se puede probar en línea aquí:
http://tryapl.org
fuente
1↓¨{1,∨⌿<\2=+\∘.=⍨⍵}⊂1∘,
APL (Dyalog 14) (31)
Esta es una función que toma una matriz y devuelve una matriz anidada.
Prueba:
Explicación:
0,⍵
: Agregue una0
al frente de⍵
, para un procesamiento más fácil. (No cuenta como una ocurrencia).(
...)⊂
: divide la matriz de acuerdo con la máscara de bits dada. Un nuevo grupo comienza en cada uno1
en la máscara de bits.+\∘.=⍨⍵
: para cada valor en (el original)⍵
, encuentre todas las ocurrencias en⍵
. Luego haga una suma continua para cada valor, dando una matriz cuadrada que muestre para cada posición⍵
cuántos de cada valor ya han ocurrido.↓
: Divida la matriz por sus filas, dando para cada valor una matriz que muestra la cantidad de veces que ha ocurrido en cada posición.2⍳⍨¨
: En cada una de estas matrices, encuentre el índice de la primera2
.(⍳⍴⍵)∊
: Para cada posible índice en⍵
, vea si está contenido en la lista de índices de segundas ocurrencias. (Estos comienzan cada grupo, excepto el primero).1,
: Agregue un1
al frente, marcando el inicio del primer grupo.1↓¨
: Elimine el primer elemento de cada grupo. (Estos son los agregados0
y la segunda aparición de cada valor).fuente
J,
2824 charUn agradecimiento especial a randomra .
Funciona así. Sobre todos los prefijos (
\
) de la matriz de entrada, observamos cuántos (+/@
) elementos del prefijo son iguales al último elemento (={:
) de ese prefijo. Cuando este número es 2, sabemos que esta es la segunda aparición de ese elemento en la matriz, por lo que dividimos la matriz allí usando<;._1
.Cosa vieja usando trucos ordenar:
(1&,<;._1~1,1=i.~(]-{)/:@/:)
.fuente
(1&,<;._1~1,2=+/@(={:)\)
es 4 bytes más corto y mucho más simple. (/:@/:
Es un buen truco sin embargo.)Mathematica,
585149 bytesEsta es una función sin nombre que toma una lista como
y devuelve una lista anidada como
Cómo funciona
Esto usa algo de magia bastante oscura con
SplitBy
.Estoy realizando un seguimiento de las ocurrencias de cada número en una función
f
. En Mathematica, puede definir el valor de una función para cada entrada por separado, y no necesita especificar el valor para todas las entradas posibles (es más como una tabla hash con esteroides).Así que empiezo inicializando
f
a 0 para los valores que están presentes en la entrada con(f@#=0;#)&/@
.Ahora
SplitBy
toma una lista y una función y "divide la lista en sublistas que consisten en ejecuciones de elementos sucesivos que dan el mismo valor cuandof
se aplica" (tenga en cuenta queSplitBy
no elimina ningún elemento). Pero la captura (no documentada) es, quef
se llama dos veces en cada elemento, cuando se compara con su predecesor y su sucesor. Entonces si lo hacemosno solo obtenemos cada número una vez, sino que esto imprime
que son 6 llamadas para 3 comparaciones.
Podemos dividir la lista antes de cada segundo evento, si escribimos una función que siempre regresa
False
pero regresaTrue
cuando se compara un segundo evento con el elemento anterior. Esa es la tercera verificación en ese elemento (dos verificaciones en la primera aparición, más la primera verificación en la segunda aparición). Por lo tanto, usamos++f[#]==3&
. Lo bueno es que esto ya regresaFalse
nuevamente en la segunda verificación de la segunda ocurrencia, de modo que puedo regresarTrue
por segundas ocurrencias consecutivas, pero aún dividido entre ellas . Del mismo modo, esto no se dividirá después de las segundas ocurrencias, porque la función ya regresaFalse
nuevamente en la segunda verificación.Ahora, la pregunta quiere que también eliminemos esas segundas ocurrencias, por lo que eliminamos el primer elemento de cada lista, con
Rest/@
. Pero, por supuesto, no queremos eliminar el primer elemento de la entrada, por lo que en realidad comenzamos agregando un elementoa
al comienzo de la lista con{a}~Join~#
.a
es una variable indefinida, que Mathematica solo trata como un desconocido, por lo que no afectará a ningún otro valor def
. Esto también asegura que el primer elemento real en la entrada obtenga sus dos verificaciones como cualquier otro elemento.fuente
Boole
en realidad allí.Python, 148 bytes
Una solución bastante horrenda. Tiene que haber una mejor manera ...
Llamada con
s([2, 1, 1, 1, 4, 5, 6])
.Versión sin golf
fuente
Haskell,
11511310688Esto almacena la cantidad que cada elemento apareció hasta ahora como una función desde los elementos hasta su cantidad respectiva, lo cual es un truco interesante.
esto funciona usando
%
una función que da una función f y un argumentox
devuelve una nueva función que devuelvef
aplicada a su argumento si es diferente dex
, y de lo1 + f x
contrario.por ejemplo,
3 % const 0
es una función que devuelve 0 para cada argumento, excepto 3, para el que devuelve 1. actualización: fusionó elfoldl
para obtener un programa mucho más pequeño.fuente
Demo de Ruby 66
Ruby stabby lambda que toma una matriz como parámetro y devuelve una matriz de matrices.
fuente
Python: 100 bytes
Solución directa. Repito la lista, cuento cuántas veces apareció un personaje antes y agrego la parte desde la última comprobación a la lista de salida.
fuente
Rubí, 66
Explicación
e
es un Hash de recuentos de ocurrencia para cada elemento,r
es una matriz en la que se almacena el resultado.1
.2
, necesitamos dividirnos. Agregar un vacíoArray
al resultado.Array
resultado.fuente
CJam,
2524 bytesToma información de STDIN como
y salidas como
Básicamente, estoy iterando sobre todos los elementos de la matriz, uno por uno, colocándolos en otra matriz. Luego obtengo el recuento del elemento actual en la otra matriz. Si es 2, comienzo otra matriz desde esa ubicación. Este tipo de inicio de matriz aleatoria solo se puede lograr en un lenguaje basado en pila.
Expansión de código :
Pruébalo en línea aquí
1 byte guardado de la sugerencia de Martin en el chat
fuente
Ruby, 64 bytes
fuente
Perl 5: 36
No estoy seguro de si esto es aceptable ya que aquí no ocurre una división real.
Ejemplo:
fuente
-pa
como dos bytes adicionales (porque "cuesta" solo dos bytes, ya que puede escribirlo como en-pae
lugar de-e
). Eso sería 38, no 36.CJam, 28 bytes
Toma entrada en STDIN como
e imprime la salida a STDOUT como
Tenga en cuenta que las cadenas vacías y las matrices vacías son lo mismo en CJam, y se muestran
""
de forma predeterminada (esto es la representación nativa de las matrices vacías).(Comencé a trabajar en esto un poco antes de que se publicara el desafío, porque estábamos discutiendo lo difícil que sería el desafío).
Explicación
Básicamente, estoy duplicando cada elemento en la matriz, a menos que sea la segunda aparición, en cuyo caso reemplazo la primera copia con un espacio. Por razones de golf, esta matriz modificada se construye a la inversa. Entonces se
[2 1 1 2 3 2 3]
convierteLuego selecciono cada segundo elemento desde el final, que es la matriz original, pero con las segundas ocurrencias reemplazadas por espacios, es decir
Finalmente, simplemente dividí la matriz en espacios. Aquí hay un desglose del código:
fuente
""
se permite explícitamente en la primera revisión de la pregunta. La revisión actual establece "cualquier formato conveniente ... generalmente la represión de cadenas nativas de las matrices".Herramientas Unix, 100 bytes.
Excepto la entrada a través de stdin. Básicamente, simplemente reemplaza cada segundo caso con
"] ["
. No funciona con cadenas vacías,[]
dará una cadena vacía, que creo que es una representación conveniente de una matriz vacía :)fuente
11
? ¿se convertirá a1][
?APL, 42 caracteres
Ejemplo:
Salida:
Probado aquí.
Si debo generar una cadena que se interpreta exactamente como la estructura correcta en APL ... 49 caracteres
fuente
1↓1
parece solucionar el problema, pero eso parece demasiado extraño.Java, 223
Esto solo funciona en Oracle o OpenJDK JRE, ya que uso esta peculiaridad en su implementación del cuantificador y la verificación de longitud en el retrospectivo para implementar el retrospectivo de longitud variable.
La mayor parte del trabajo se realiza en la expresión regular, que se muestra a continuación en forma cruda:
Antes de ver la expresión regular anterior, echemos una mirada a la expresión regular equivalente de .NET, que es más simple, ya que admite directamente la mirada retrospectiva de longitud variable (la mirada retrospectiva de .NET probablemente se realiza mediante el modo de coincidencia de derecha a izquierda) :
*\b(\d+)\b
y*
al final coincide con un número y los espacios circundantes (si los hay). Los controles encuadernados son para evitar que un número parcial coincida, ya que los espacios en ambos lados son opcionales. También captura el número para verificar si es la segunda aparición en la matriz.(?<=(.*\b\1\b){2})
comprueba que se puedan encontrar 2 instancias del número capturado anteriormente.(?<!(.*\b\1\b){3})
comprueba que no se puedan encontrar 3 instancias del número capturado. Ambas condiciones combinadas afirman que solo hay 2 instancias del número hasta ahora. Los cheques encuadernados están ahí para asegurarse de que se pruebe el número entero.Volver a la versión de Java. Para implementar una mirada de longitud variable detrás, transformamos
a
Estoy un poco indeciso con respecto al hecho de que
.
excluye los separadores de línea, pero se puede arreglar fácilmente y no quiero complicar aún más la sintaxis.La anticipación siempre tiene una longitud de 0, y la verificación de longitud pasa debido a la implementación de
*
cuantificador.los
^
es necesario para que funcione, pero está ahí para hacer que el caso fallido falle más rápido. La implementación de Oracle / OpenJDK se realiza retrocediendo la longitud mínima del patrón, luego coincide, luego enjuaga y repite incrementando la longitud hasta encontrar una coincidencia, o en el peor de los casos, hasta la longitud máxima del patrón . Con^
, me aseguro de que la cadena de prefijo solo coincida una vez.Sin embargo, la vista hacia el interior dentro de la vista posterior no está limitada por el límite derecho de la vista posterior, por lo que puede coincidir hasta el final de la cadena. Para afirmar el límite, capturo el resto de la cadena en otro grupo de captura dentro de una mirada hacia adelante, y lo uso para limitar el reinado del patrón de longitud variable.
Como mi patrón ya comienza
.*
, no necesito agregar otro.*
al frente.fuente
Perl 108
En acción:
Nota: Las dos primeras líneas
$Data::...
están ahí solo para una mejor presentación y la tercera línea@a=@b=@e=();
está ahí para hacer que la herramienta funcione en varias líneas.fuente
R, 76
Salida para el ejemplo: una lista de cinco elementos, incluidos tres vectores vacíos. (
numeric(0)
)Por cierto: el código genera un mensaje de advertencia que puede ignorarse.
fuente
awk 29
Esto toma un poco de libertad con los formatos de entrada y salida. La entrada "matriz" es vertical, un número por línea. La salida también es vertical, un número por línea, con guiones que separan las matrices.
Entrada:
Salida:
fuente
Pyth 30
32Esta es la primera vez que experimento con Pyth. Es la misma solución que en mi solución Python.
Puedes probarlo en línea: Pyth Compiler / Executor
Por ejemplo, la entrada
imprimirá
Explicación:
fuente
=Y+Y...
?~Y...
Pitón 2, 84
La lista
l
es el resultado hasta ahora. Repetimos los elementos. Si la actual es la segunda aparición, comenzamos una nueva sublista vacía; de lo contrario, lo agregamos a la última sublista. La lista de elementos vistos hasta ahora se almacena enp
. Curiosamente, reconstruir la lista parece más corto que cortar la entrada.fuente
Puro bash
1119481 por solo dividir:
La segunda linea
declare -p c
simplemente descarga la variableMuestra:
Nota: la línea
local b c d i
solo es necesaria para ejecutar la función varias veces.Para la presentación más sexy (+26)
Renderizará algo como:
fuente
Scala,
122111Tome carácter colección, imprimir en forma de
[21][][3224567][][0][]
,122111:... o toma una colección de personajes y devuelve listas anidadas,
135129:Estoy seguro de que podría obtener algunos ahorros, no he buscado demasiado.
fuente
Python 220 bytes
¡El siguiente es de 220 bytes, que no es excelente en comparación con muchos de los otros, pero funciona lo suficientemente rápido con enteros más grandes!
fuente
=
, el cambioxlist
yresult
a los nombres más cortos, y quitar los espacios alrededor==
,;
y:
. Si necesita más ayuda, simplemente escriba@NoOneIsHere
(o cualquier nombre de usuario) y yo / el usuario intentaré ayudarlo.Java: 563 bytes
tenga en cuenta que esto usa Java 8, pre-JDK8 sería unos pocos bytes más debido al foreach.
fuente
Integer.MAX_VALUE
a2147483647
? Es el mismo valor con menos bytes. Además,IndexOutOfBoundsException
se puede acortar aException