Dada una matriz a que contiene solo números en el rango de 1 a una longitud, encuentre el primer número duplicado para el cual la segunda aparición tiene el índice mínimo. En otras palabras, si hay más de 1 números duplicados, devuelva el número para el que la segunda aparición tiene un índice más pequeño que la segunda aparición del otro número. Si no hay tales elementos, su programa / función puede resultar en un comportamiento indefinido.
Ejemplo:
Para a = [2, 3, 3, 1, 5, 2]
, la salida debe ser
firstDuplicate(a) = 3
.
Hay 2 duplicados: los números 2 y 3. La segunda aparición de 3 tiene un índice más pequeño que la segunda aparición de 2, por lo que la respuesta es 3.
Para a = [2, 4, 3, 5, 1]
, la salida debe ser
firstDuplicate(a) = -1
.
Este es el código de golf , por lo que la respuesta más corta en bytes gana.
BONIFICACIÓN: ¿Puedes resolverlo en O (n) complejidad de tiempo y O (1) complejidad de espacio adicional?
fuente
Respuestas:
Python 2 , 34 bytes
O (n 2 ) tiempo, O (n) espacio
¡Ahorré 3 bytes gracias a @vaultah, y 3 más de @xnor!
Pruébalo en línea!
fuente
lambda l:l[map(l.remove,set(l))<0]
funciona, aunque el orden de evaluación es extraño.-1
cuando no se encuentran duplicados sin el 'código de pie de página', ¿ese código no cuenta para los bytes? Soy nuevo en el código de golf, lo siento si es una pregunta básica.JavaScript (ES6),
47363125 bytesGuardado 6 bytes gracias a ThePirateBay
Devuelve
undefined
si no existe una solución.Complejidad del tiempo: O (n) :-)
Complejidad del espacio: O (n) :-(
¿Cómo?
Realizamos un seguimiento de los valores ya encontrados guardándolos como nuevas propiedades de la matriz original a mediante el uso de números negativos. De esta manera, no pueden interferir con las entradas originales.
Manifestación
Mostrar fragmento de código
fuente
a=>a.find(c=>!(a[-c]^=1))
Mathematica, 24 bytes
¡La capacidad de coincidencia de patrones de Mathematica es genial!
Devuelve el original
List
para una entrada no válida.Explicación
En la entrada, reemplace ...
A
List
con un elemento duplicado, con 0 o más elementos antes, entre y después de los duplicados ...Con el elemento duplicado.
fuente
Jalea , 5 bytes
Pruébalo en línea!
Cómo funciona
fuente
œ-
elimina las ocurrencias más a la derecha? TIL-1
sin duplicados. Lanzar una excepción está bien según OP, pero no estoy seguro de si0
es así aunque no esté en el rango.Haskell , 35 bytes
Pruébalo en línea! Se bloquea si no se encuentra ningún duplicado.
fuente
Jalea , 6 bytes
Pruébalo en línea!
Devuelve el primer duplicado, o 0 si no hay duplicado.
Explicación
fuente
ŒQi0ị
.i0
devolvería 0, donde indexaríaị
y devolvería el último valor de la entrada en lugar de 0.Japt , 7 bytes
¡Pruébelo en línea!
Explicación
Alternativamente:
¡Pruébelo en línea!
Explicación
fuente
Pyth, 5 bytes
Banco de pruebas
Elimine de Q la primera aparición de cada elemento en Q, luego devuelva el primer elemento.
fuente
Dyalog APL,
27242019131211 bytes¡Ahora modificado para no depender de v16! Pruébalo en línea!
¿Cómo? (Con entrada N )
⊢⊃⍨...
- N en este índice:⍴↑∪
- N con duplicados eliminados, acolchado a la derecha0
para encajar N⊢=
- Igualdad entre elementos con N0⍳⍨
- Índice de la primera0
. ``fuente
⎕AV
, ¿verdad?⎕U2378
al cargar. Pruébalo en línea!Python 3 ,
9492 bytesO (n) tiempo y O (1) memoria extra.
Pruébalo en línea!
Fuente del algoritmo .
Explicación
La idea básica del algoritmo es ejecutar cada elemento de izquierda a derecha, realizar un seguimiento de los números que han aparecido y devolver el número al llegar a un número que ya apareció, y devolver -1 después de atravesar cada elemento.
Sin embargo, utiliza una forma inteligente de almacenar los números que han aparecido sin usar memoria adicional: almacenarlos como el signo del elemento indexado por el número. Por ejemplo, puedo representar el hecho de que
2
y3
ya ha aparecido por tenera[2]
ya[3]
negativo, si la matriz es 1-indexado.fuente
i
donde a [i]> n?1
a a.length pero para un [i] = a.length ¿no estaría esto fuera de límites?t=abs(a[i])-1=a.length-1
Perl 6 , 13 bytes
Intentalo
Explicación
El
*
está en una posición de término, por lo que toda la declaración es un lambda WhateverCode .El
.repeated
es un método que da como resultado cada valor, excepto la primera vez que se vio cada valor.[0]
solo devuelve el primer valor en la Seq .Si no hay valor, se devuelve Nil .
( Nil es la base de los tipos de Fallo , y todos los tipos tienen su propio valor indefinido, por lo que Nil es diferente de un valor indefinido en la mayoría de los otros idiomas)
Tenga en cuenta que, dado que la implementación de
.repeated
genera una Seq, eso significa que no comienza a hacer ningún trabajo hasta que solicite un valor, y solo hace suficiente trabajo para generar lo que solicita.Por lo tanto, sería fácil argumentar que esto tiene en el peor de los casos O (n) complejidad de tiempo, y en el mejor de los casos O (2) complejidad de tiempo si el segundo valor es una repetición del primero.
Similarmente se puede decir de la complejidad de la memoria.
fuente
APL (Dyalog) , 20 bytes
Pruébalo en línea!
2⍴¯1
negativo uno r eshaped en una lista longitud de dos⎕,
obtener entrada (mnemónica: caja de consola) y anteponer eson←
almacenar eso en n,\
prefijos de n (literalmente, concatenación acumulativa)(
...)¨
aplique la siguiente función tácita a cada prefijo,
[es] el enmarañamiento (solo asegura que el prefijo sea una lista)≢
diferente de∪
los elementos únicos [?] (es decir, ¿el prefijo tiene duplicados?)n/⍨
use eso para filtrar n (elimina todos los elementos hasta el primero para el que se encontró un duplicado)⊃
elige el primer elemento de esefuente
APL (Dyalog) , 11 bytes
Según las nuevas reglas , arroja un error si no existen duplicados.
Pruébalo en línea!
⍳⍨
los índices de la primera aparición de cada elemento~
retirado de⍳∘≢
de todos los índices⍬⍴
remodelar eso en un escalar (da cero si no hay datos disponibles)⊃⍨
usar eso para elegir (da error en cero)⊢
el argumentofuente
APL, 15
Parece que podemos devolver 0 en lugar de -1 cuando no hay duplicados, (gracias Adám por el comentario). Entonces 3 bytes menos.
Un poco de descripción:
Como referencia, la solución anterior agregó -1 a la lista al final, por lo que si la lista terminara vacía, contendría -1 y el primer elemento sería -1.
Pruébalo en tryapl.org
fuente
¯1
, por lo que{⊃⍵[(⍳⍴⍵)~⍵⍳⍵]}
debería hacerlo.Retina ,
2624 bytesPruébalo en línea! Explicación:
\b(\d+)\b
coincide con cada número por turno, y luego mira hacia atrás para ver si el número es un duplicado; si es la salida de1
st match!
, en lugar del recuento de coincidencias. Desafortunadamente, poner el lookbehind primero no parece funcionar, de lo contrario ahorraría varios bytes. Editar: seagregaron 7 bytes para cumplir con elGuardado 2 bytes gracias a @MartinEnder.-1
valor de retorno en caso de no coincidencia.fuente
-1
.MATL , 8 bytes
Da un error (sin salida) si no existe ningún duplicado.
¡Pruébelo en MATL Online!
Explicación
fuente
R, 34 bytes
Corte algunos caracteres de la respuesta de @djhurio, aunque no tengo suficiente reputación para comentar.
fuente
-1
pero con la nueva especificación, logré reducir aún más. Esto sigue siendo sólido y es un enfoque diferente de la forma en que lo hizo, ¡así que te daré un +1!J,
1716 bytes¿Cómo?
fuente
R , 28 bytes
Pruébalo en línea!
fuente
NA
por valores perdidos ya que la especificación ha cambiado; Entonces(x=scan())[duplicated(x)][1]
es perfectamente válido.J , 12 bytes
Pruébalo en línea!
Explicación
fuente
Dyalog APL Classic, 18 caracteres
Solo funciona en
⎕IO←0
.Elimine de la lista de índices de los elementos del argumento con un "-1" antepuesto los índices de lista de su protuberancia y luego elija el primero de lo que queda. Si después de la eliminación solo queda un vector vacío, su primer elemento es, por definición, 0, que se utiliza para indexar el argumento extendido que produce el -1 deseado.
fuente
¯1
, para que pueda eliminarlo¯1,
y usarlo⎕IO←1
.Ruby ,
2836 bytesEntendió mal el desafío la primera vez.
O(n)
tiempo,O(n)
espacioPruébalo en línea!
fuente
Java (OpenJDK 8) ,
65117109 bytesSolución anterior de 65 bytes:
Nueva solución Se incluyen 19 bytes para
import java.math.*;
-8 bytes gracias a @Nevay
Pruébalo en línea!
Editar
El algoritmo en mi programa original estaba bien, pero el tamaño estático del tipo de datos utilizado significaba que se rompió bastante rápido una vez que el tamaño superó un cierto umbral.
He cambiado el tipo de datos utilizado en el cálculo para aumentar el límite de memoria del programa para acomodar esto (utilizando
BigInteger
precisión arbitraria en lugar deint
olong
). Sin embargo, esto hace discutible si esto cuenta o no comoO(1)
complejidad espacial.Dejaré mi explicación a continuación intacta, pero deseo agregar que ahora creo que es imposible lograr
O(1)
la complejidad del espacio sin hacer algunas suposiciones.Prueba
Definir
N
como un entero tal que2 <= N
.Deje
S
ser una lista que representa una serie de enteros aleatorios[x{1}, ..., x{N}]
, dondex{i}
tiene la restricción1 <= x{i} <= N
.La complejidad de tiempo (en notación Big-O) requerida para recorrer esta lista exactamente una vez por elemento es
O(n)
El desafío dado es encontrar el primer valor duplicado en la lista. Más específicamente, estamos buscando el primer valor
S
que es un duplicado de un elemento anterior en la lista.Dejar
p
yq
ser las posiciones de dos elementos en la lista de tal manera quep < q
yx{p} == x{q}
. Nuestro desafío es encontrar el más pequeñoq
que satisfaga esas condiciones.El enfoque obvio para este problema es recorrer en iteración S y verificar si
x{i}
existe en otra listaT
: six{i}
no existe enT
, la almacenamosT
. Six{i}
existe enT
, es el primer valor duplicado y, por lo tanto, el más pequeñoq
, y como tal lo devolvemos. Esta eficiencia espacial esO(n)
.Para lograr
O(1)
la complejidad del espacio mientras se mantiene laO(n)
complejidad del tiempo, tenemos que almacenar información única sobre cada objeto en la lista en una cantidad finita de espacio. Debido a esto, la única forma en que cualquier algoritmo podría funcionar enO(1)
la complejidad del espacio es si: 1. A N se le asigna un límite superior correspondiente a la memoria requerida para almacenar el número máximo de valores posibles para un tipo de datos finito en particular. 2. La reasignación de una sola variable inmutable no se cuenta en función de la complejidad, solo el número de variables (una lista son múltiples variables). 3. (Basado en otras respuestas) La lista es (o al menos, los elementos de la lista son) mutables, y el tipo de datos de la lista está preestablecido como un entero con signo, lo que permite que se realicen cambios en los elementos más adelante en la lista sin usar memoria adicional.1 y 3 requieren supuestos y especificaciones sobre el tipo de datos, mientras que 2 requiere que solo se considere el número de variables para el cálculo de la complejidad del espacio, en lugar del tamaño de esas variables. Si no se acepta ninguno de estos supuestos, sería imposible lograr la
O(n)
complejidad del tiempo yO(1)
la complejidad del espacio.Explicación
Whoo boy, este tomó
un tiempo vergonzosamente largo para pensarun poco de poder mental.Entonces, ir por la bonificación es difícil. Necesitamos ambos para operar sobre la lista completa exactamente una vez y rastrear qué valores ya hemos iterado sin complejidad de espacio adicional.
La manipulación de bits resuelve esos problemas. Inicializamos nuestro
O(1)
'almacenamiento', un par de enteros, luego iteramos a través de la lista, OR-on el bit i en nuestro primer entero y almacenamos ese resultado en el segundo.Por ejemplo, si tenemos
1101
, y realizamos una operación OR con10
, obtenemos1111
. Si hacemos otro OR con10
, todavía tenemos1101
.Ergo, una vez que realizamos la operación OR y terminamos con el mismo número, encontramos nuestro duplicado. Ningún duplicado en la matriz hace que el programa se ejecute y arroje una excepción.
fuente
PHP,
56 44 3832 bytesCorre así:
Explicación
Ajustes
Complejidad
Como se puede ver en la versión comentada del código, la complejidad del tiempo es lineal
O(n)
. En términos de memoria,n+1
se asignará un máximo de variables. Entonces eso esO(n)
.fuente
error_reporting
opción al recuento de bytes (o usar-n
, que es gratis)./dev/null
, que es lo mismo.O(1)
de espacio adicional? Literalmente está asignando una nueva variable porn
, que esO(n)
Java 8,
827876 bytesYa no es viable,756764 bytes a continuación en ediciónComo una función lambda:
Probablemente se puede hacer mucho más pequeño, esto fue muy rápido.
Explicación:
*Editar*
756764 bytes usando la estrategia de negación:Pruébalo en línea!
(-3 bytes gracias a @Nevay)
Explicación:
Recorre la matriz, negando el seguimiento. Si no hay engaños, simplemente corre y arroja un error.
Ambos trabajan en O (n) tiempo y O (n) complejidad espacial.
fuente
Number
, ya quei
es unlong
y-1
es unint
.long
, pero no aLong
lo requerido para que la lambda se asigne a aFunction
. ¿Lo probaste? De todos modos, esa solución se puede reemplazar con la nueva.Set s=new HashSet();
para guardar 7 bytes. (Además: afaik la importación dejava.util.*;
debe incluirse en el recuento de bytes -> +19 bytes.) La declaración de retorno puede serreturn++j
, la declaración if puede eliminarsea->{int i=0,j;for(;(a[j=Math.abs(a[i++])-1]*=-1)<0;);return++j;}
(-3 bytes).Brachylog , 5 bytes
Pruébalo en línea!
Explicación
El adfix incorporado
a
enumera primero todos los prefijos en orden creciente de longitud, luego los sufijos en orden decreciente de longitud. Por lo tanto, la salida es producida por el prefijo más corto que lo permite, si lo hay. Si un prefijo no tiene duplicados, el resto del programa falla, ya que cada subsecuencia de elementos iguales tiene longitud 1, y el primer elemento de su cola no existe. Si un prefijo tiene un elemento repetido, podemos elegir la subsecuencia de longitud 2 que contiene ambos, y el programa devuelve el último.fuente
a⊇Ċ=h
que solo analiza los subconjuntos de longitud 2.C #, 145 bytes
Probablemente sea una forma mucho más corta de hacer esto en C # con un bucle simple, pero quería probarlo con Linq.
Pruébalo en línea!
Versión completa / formateada:
fuente
Haskell ,
7869 bytesPruébalo en línea!
Guardado 9 bytes gracias a @nimi
Una ruta básica a través de la lista. Si el elemento actual aún no se ha visto (
i<0
) y está en la lista de acumuladores (elem x a
), guarde el índice actual. De lo contrario, mantenga el índice -1. En cualquier caso, agregue el elemento actual a la lista de acumuladores.EDITAR : No leí la pregunta con suficiente atención: este código genera el índice del segundo elemento de un elemento duplicado.
fuente
\ ... ->(last$i:[j|i<0,elem x a],x:a)
. Además: no es necesariof=
, porque se permiten funciones sin nombre.Python 2,
7165 bytesDevuelve
None
si no hay elemento duplicadoEditar: -6 bytes gracias a @ musicman523
Pruébalo en línea!
O (n) complejidad temporal, O (n) complejidad espacial, O (1) espacio auxiliar.
Como la lista de entrada usa el espacio O (n) , la complejidad del espacio está limitada por esto. Lo que significa que no podemos tener una complejidad espacial menor que O (n)
Modifica la lista original, si esto no está permitido podríamos hacerlo en la misma complejidad con 129 bytes
Explicación
Dado que cada elemento es mayor que 0 y menor o igual que el tamaño de la lista, la lista tiene para cada elemento a, un elemento en el índice a - 1 (0 indexado). Explotamos esto diciendo que si el elemento en el índice i es negativo, lo hemos visto antes.
Para cada elemento a en la lista n, seremos negativos el valor absoluto de a. (Dejamos que sea negativo ya que Python puede indexar listas con índices negativos, y de lo contrario tendríamos que hacerlo
u=abs(a)-1
) Si el elemento en el índice u en la lista es negativo, lo hemos visto antes y, por lo tanto, podemos devolver -u (para obtener el valor absoluto de a, ya que todos los elementos son positivos) . De lo contrario, establecemos que el elemento en el índice u sea negativo, para recordar que hemos visto un elemento de valor a antes.fuente
1
yn
, como se proporcionó, entonces obviamente no funciona.Jalea , 4 bytes
Pruébalo en línea!
En caso de que todos los elementos sean únicos, esto devuelve
0
(comportamiento indefinido).fuente