Encuentra el primer elemento duplicado


39

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 , 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?


Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Martin Ender

Respuestas:


15

Python 2 , 34 bytes

O (n 2 ) tiempo, O (n) espacio

¡Ahorré 3 bytes gracias a @vaultah, y 3 más de @xnor!

lambda l:l[map(l.remove,set(l))<0]

Pruébalo en línea!


1
Parece que lambda l:l[map(l.remove,set(l))<0]funciona, aunque el orden de evaluación es extraño.
xnor

Esto no regresa -1cuando 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.
Chris_Rands

@Chris_Rands Debajo de la pregunta, el músico preguntó si la excepción está bien en lugar de -1 y OP dijo que está bien y la respuesta del músico arroja una excepción.
LiefdeWen

Eso me llevó un tiempo darme cuenta. Bien jugado. Obtener el elemento 0 de l usando el condicional después de modificarlo es realmente inteligente.
Thoth19

¿Python garantiza la complejidad de tiempo y espacio de las funciones de la biblioteca estándar como set.remove?
Draconis

11

JavaScript (ES6), 47 36 31 25 bytes

Guardado 6 bytes gracias a ThePirateBay

Devuelve undefinedsi no existe una solución.

Complejidad del tiempo: O (n) :-)
Complejidad del espacio: O (n) :-(

a=>a.find(c=>!(a[-c]^=1))

¿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


25 bytes:a=>a.find(c=>!(a[-c]^=1))

@ThePirateBay Oh, por supuesto. ¡Gracias!
Arnauld

Solo tenga en cuenta que los objetos en JavaScript pueden no implementarse como tabla hash. La complejidad temporal del acceso a las claves de algún objeto puede no ser O (1).
tsh

6

Mathematica, 24 bytes

#/.{h=___,a_,h,a_,h}:>a&

¡La capacidad de coincidencia de patrones de Mathematica es genial!

Devuelve el original Listpara una entrada no válida.

Explicación

#/.

En la entrada, reemplace ...

{h=___,a_,h,a_,h}

A Listcon un elemento duplicado, con 0 o más elementos antes, entre y después de los duplicados ...

... :>a

Con el elemento duplicado.


6

Jalea , 5 bytes

Ṛœ-QṪ

Pruébalo en línea!

Cómo funciona

Ṛœ-QṪ  Main link. Argument: A (array)

Ṛ      Yield A, reversed.
   Q   Unique; yield A, deduplicated.
 œ-    Perform multiset subtraction.
       This removes the rightmost occurrence of each unique element from reversed
       A, which corresponds to the leftmost occurrence in A.
    Ṫ  Take; take the rightmost remaining element, i.e., the first duplicate of A.

œ-elimina las ocurrencias más a la derecha? TIL
Erik the Outgolfer

Esto no parece volver -1sin duplicados. Lanzar una excepción está bien según OP, pero no estoy seguro de si 0es así aunque no esté en el rango.
Erik the Outgolfer


4

Jalea , 6 bytes

xŒQ¬$Ḣ

Pruébalo en línea!

Devuelve el primer duplicado, o 0 si no hay duplicado.

Explicación

xŒQ¬$Ḣ  Input: array M
    $   Operate on M
 ŒQ       Distinct sieve - Returns a boolean mask where an index is truthy
          for the first occurrence of an element
   ¬      Logical NOT
x       Copy each value in M that many times
     Ḣ  Head

Es Golfier utilizar la indexación como esto: ŒQi0ị.
Erik the Outgolfer

@EriktheOutgolfer Si no hay duplicados, i0devolvería 0, donde indexaría y devolvería el último valor de la entrada en lugar de 0.
millas

4

Japt , 7 bytes

æ@bX ¦Y

¡Pruébelo en línea!

Explicación

 æ@   bX ¦ Y
UæXY{UbX !=Y}  Ungolfed
               Implicit: U = input array
UæXY{       }  Return the first item X (at index Y) in U where
     UbX         the first index of X in U
         !=Y     is not equal to Y.
               In other words, find the first item which has already occured.
               Implicit: output result of last expression

Alternativamente:

æ@¯Y øX

¡Pruébelo en línea!

Explicación

 æ@   ¯ Y øX
UæXY{Us0Y øX}  Ungolfed
               Implicit: U = input array
UæXY{       }  Return the first item X (at index Y) in U where
     Us0Y        the first Y items of U (literally U.slice(0, Y))
          øX     contains X.
               In other words, find the first item which has already occured.
               Implicit: output result of last expression

4

Pyth, 5 bytes

h.-Q{

Banco de pruebas

Elimine de Q la primera aparición de cada elemento en Q, luego devuelva el primer elemento.


@LuisMendo Ok, gracias. Perdón por crear confusión, debería aprender a leer ...
Sr. Xcoder

@ Mr.Xcoder No, es culpa del OP. Esa información debería estar en el texto del desafío, pero solo en un comentario
Luis Mendo

4

Dyalog APL, 27 24 20 19 13 12 11 bytes

⊢⊃⍨0⍳⍨⊢=⍴↑∪

¡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 derecha 0para encajar N
    • ⊢=- Igualdad entre elementos con N
    • 0⍳⍨- Índice de la primera 0. ``

no importa, leí mal la pregunta. aunque no hay suficientes casos de prueba ...
Uriel

Perdón por engañarlo, también leí mal la pregunta.
millas

Me parecen 36 bytes.
Adám

Oh dios, iota underbar no está adentro ⎕AV, ¿verdad?
Zacharý

@ Zacharý Right, Classic lo traduce ⎕U2378 al cargar. Pruébalo en línea!
Adám el

3

Python 3 , 94 92 bytes

O (n) tiempo y O (1) memoria extra.

def f(a):
 r=-1
 for i in range(len(a)):t=abs(a[i])-1;r=[r,i+1][a[t]<0>r];a[t]*=-1
 return r

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 2y 3ya ha aparecido por tener a[2]y a[3]negativo, si la matriz es 1-indexado.


¿Qué haría esto para idonde a [i]> n?
Downgoat

@Downgoat lee la pregunta nuevamente.
Leaky Nun

La pregunta le dice 1a a.length pero para un [i] = a.length ¿no estaría esto fuera de límites?
Downgoat

@Downgoatt=abs(a[i])-1=a.length-1
Leaky Nun


3

Perl 6 , 13 bytes

*.repeated[0]

Intentalo


Explicación

  • El *está en una posición de término, por lo que toda la declaración es un lambda WhateverCode .

  • El .repeatedes un método que da como resultado cada valor, excepto la primera vez que se vio cada valor.

    say [2, 3, 3, 3, 1, 5, 2, 3].repeated.perl; # (3, 3, 2, 3).Seq
    #   (      3, 3,       2, 3).Seq
  • [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.


3

APL (Dyalog) , 20 bytes

n/⍨(,≢∪)¨,\n←⎕,2⍴¯1

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 eso

n← 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 ese


Wow, te golpearon tres veces. Aún así, +1. ¿Y puede agregar una explicación de cómo funciona esto?
Zacharý

@ Zacharý Aparentemente solo necesitaba hacer rodar la pelota. Aqui tienes.
Adám

@ Zacharý Finalmente, logré vencerlos a todos .
Adám

3

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 argumento


Bueno, sí, cuando se cambian las reglas, ¡por supuesto que puedes vencerlas a todas!
Zacharý

Bueno, te até.
Zacharý

3

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:

⍵⍳⍵         search the argument in itself: returns for  each element the index of it's first occurrence
(⍳⍴⍵)~⍵⍳⍵   create a list of all indexes, remove those found in ⍵⍳⍵; i.e. remove all first elements
⊃⍵[...]     of all remaining elements, take the first. If the array is empty, APL returns zero

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.

{⊃⍵[(⍳⍴⍵)~⍵⍳⍵],¯1}

Pruébalo en tryapl.org


Puede devolver un cero en lugar de¯1 , por lo que {⊃⍵[(⍳⍴⍵)~⍵⍳⍵]}debería hacerlo.
Adám

3

Retina , 26 24 bytes

1!`\b(\d+)\b(?<=\b\1 .*)

Pruébalo en línea! Explicación: \b(\d+)\bcoincide 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 de 1st match !, en lugar del recuento de coincidencias. Desafortunadamente, poner el lookbehind primero no parece funcionar, de lo contrario ahorraría varios bytes. Editar: se agregaron 7 bytes para cumplir con el -1valor de retorno en caso de no coincidencia. Guardado 2 bytes gracias a @MartinEnder.


2
Para el registro, la búsqueda no retrocederá. Esto evita que esto funcione si intenta ponerlo antes. He cometido este error muchas veces, y Martin siempre me corrige.
FryAmTheEggman

Obtuve 30 bytes usando un lookahead en lugar de un lookbehind. Además, las reglas ahora dicen que no necesita regresar -1.
Value Ink el

@ValueInk Pero la respuesta correcta para ese caso de prueba es 3 ...
Neil

OH. Leí mal el desafío, whoops
Value Ink

2

MATL , 8 bytes

&=Rsqf1)

Da un error (sin salida) si no existe ningún duplicado.

¡Pruébelo en MATL Online!

Explicación

&=   % Implict input. Matrix of all pairwise equality comparisons
R    % Keep the upper triangular part (i.e. set lower part to false)
s    % Sum of each column
q    % Subtract 1
f    % Indices of nonzero values
1)   % Get first. Gives an error is there is none. Implictly display

2

R, 34 bytes

c((x=scan())[duplicated(x)],-1)[1]

Corte algunos caracteres de la respuesta de @djhurio, aunque no tengo suficiente reputación para comentar.


oh ... no vi esta respuesta; Esto es bueno para la especificación anterior cuando se requieren valores perdidos, -1pero 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!
Giuseppe

2

J, 17 16 bytes

(*/{_1,~i.&0)@~:

¿Cómo?

(*/{_1,~i.&0)@~:

             @~: returns the nub sieve which is a vector with 1 for the first occurrence of an element in the argument and 0 otherwise

        i.&0     returns the first index of duplication

    _1,~         appends _1 to the index

 */              returns 0 with duplicates (product across nub sieve)

     {           select _1 if no duplicates, otherwise return the index

2

R , 28 bytes

(x=scan())[duplicated(x)][1]

Pruébalo en línea!


Creo que ahora puede regresar NApor valores perdidos ya que la especificación ha cambiado; Entonces (x=scan())[duplicated(x)][1]es perfectamente válido.
Giuseppe

2

J , 12 bytes

,&_1{~~:i.0:

Pruébalo en línea!

Explicación

,&_1{~~:i.0:  Input: array M
      ~:      Nub-sieve
          0:  The constant 0
        i.    Find the index of the first occurrence of 0 (the first duplicate)
,&_1          Append -1 to M
    {~        Select the value from the previous at the index of the first duplicate

2

Dyalog APL Classic, 18 caracteres

Solo funciona en ⎕IO←0.

     w[⊃(⍳∘≢~⍳⍨)w←¯1,⎕]

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.


Um ... ¿qué pasa con los espacios iniciales aleatorios? +1 por superarme en un byte.
Zacharý

Puede lanzar un error en lugar de regresar¯1 , para que pueda eliminarlo ¯1,y usarlo ⎕IO←1.
Adám


2

Java (OpenJDK 8) , 65 117 109 bytes

Solución anterior de 65 bytes:

r->{for(int a,b=0,z,i=0;;b=a)if((a=b|1<<(z=r[i++]))==b)return z;}

Nueva solución Se incluyen 19 bytes paraimport java.math.*;

-8 bytes gracias a @Nevay

r->{int z,i=0;for(BigInteger c=BigInteger.ZERO;c.min(c=c.setBit(z=r[i++]))!=c;);return z;}

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 BigIntegerprecisión arbitraria en lugar de into long). Sin embargo, esto hace discutible si esto cuenta o no como O(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 Ncomo un entero tal que 2 <= N.

Deje Sser una lista que representa una serie de enteros aleatorios [x{1}, ..., x{N}], donde x{i}tiene la restricción 1 <= 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 Sque es un duplicado de un elemento anterior en la lista.

Dejar py qser las posiciones de dos elementos en la lista de tal manera que p < qy x{p} == x{q}. Nuestro desafío es encontrar el más pequeño qque satisfaga esas condiciones.

El enfoque obvio para este problema es recorrer en iteración S y verificar si x{i}existe en otra lista T: si x{i}no existe en T, la almacenamos T. Si x{i}existe en T, es el primer valor duplicado y, por lo tanto, el más pequeño q, y como tal lo devolvemos. Esta eficiencia espacial es O(n).

Para lograr O(1)la complejidad del espacio mientras se mantiene la O(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 y O(1)la complejidad del espacio.

Explicación

Whoo boy, este tomó un tiempo vergonzosamente largo para pensar un 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 con 10, obtenemos 1111. Si hacemos otro OR con 10, todavía tenemos 1101.

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.


Además, su segunda prueba incluye el número 100, pero eso es imposible, ya que la matriz en sí es sólo el 5 tiempo
Colegial

Además, esto falla ya que un int no tiene suficiente almacenamiento.
SchoolBoy

@SchoolBoy Buena captura. Mi único problema es que no parece haber ningún límite superior en el tamaño de la matriz, por lo que no puedo cambiar mi código de manera realista para resolver problemas de memoria.
Xanderhall

@ Xanderhall Verdadero, pero siento que 32 (o si usa un número largo, 64) es demasiado pequeño: p. De cualquier manera, imponer un límite en la entrada y luego asignar la memoria máxima necesaria y llamarla memoria O (1) es solo una trampa. Sigue siendo O (n) ya que si el tamaño de la entrada aumentara, también lo haría este límite superior a la memoria. Por eso también creo que es imposible crear un algoritmo O (n) O (1)
SchoolBoy

@ Xanderhall PD Me estoy acercando a tus 65, estoy en 67 bytes: p
SchoolBoy

2

PHP, 56 44 38 32 bytes

for(;!${$argv[++$x]}++;);echo$x;

Corre así:

php -nr 'for(;!${$argv[++$x]}++;);echo$x;' -- 2 3 3 1 5 2;echo
> 3

Explicación

for(
  ;
  !${                 // Loop until current value as a variable is truthy
    $argv[++$x]       // The item to check for is the next item from input
  }++;                // Post increment, the var is now truthy
);
echo $x;              // Echo the index of the duplicate.

Ajustes

  • Guardado 12 bytes usando variables en lugar de una matriz
  • Se guardaron 6 bytes haciendo uso de la regla de "comportamiento indefinido" para cuando no hay coincidencia.
  • Se guardaron 6 bytes usando el incremento posterior en lugar de establecerlo en 1 después de cada ciclo

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+1se asignará un máximo de variables. Entonces eso es O(n).


Gracias por no usar una codificación extraña. Pero debe agregar la error_reportingopción al recuento de bytes (o usar -n, que es gratis).
Titus

Hemos estado aquí antes. Los avisos y advertencias de PHP son ignorables. También podría canalizarlos /dev/null, que es lo mismo.
aross

Tiendo a recordar los comentarios equivocados. :) ¿No es esto O (n)?
Titus

Sí, es lineal
aross el

¿Cómo es eso O(1)de espacio adicional? Literalmente está asignando una nueva variable por n, que esO(n)
Xanderhall

2

Java 8, 82 78 76 bytes Ya no es viable, 75 67 64 bytes a continuación en edición

Como una función lambda:

a->{Set<Long>s=new HashSet<>();for(long i:a)if(!s.add(i))return i;return-1;}

Probablemente se puede hacer mucho más pequeño, esto fue muy rápido.

Explicación:

a->{                                //New lambda function with 'a' as input
    Set<Long>s=new HashSet<>();     //New set
    for(long i:a)                   //Iterate over a
        if(!s.add(i))               //If can't add to s, already exists
            return i;               //Return current value
        return-1;                   //No dupes, return -1
}

*Editar*

75 67 64 bytes usando la estrategia de negación:

a->{int i=0,j;while((a[j=Math.abs(a[i++])-1]*=-1)<0);return++j;}

Pruébalo en línea!

(-3 bytes gracias a @Nevay)

Explicación:

a->{                                         //New lambda expression with 'a' as input
    int i=0,j;                               //Initialise i and declare j
    while((a[j=Math.abs(a[i++])-1]*=-1)<0);  //Negate to keep track of current val until a negative is found
    return++j;                               //Return value
}

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.


Vale la pena señalar que esto tendrá que asignarse a un lambda que regresa Number, ya que ies un longy -1es un int.
Jakob

@Jakob No es necesario, -1 como int se lanzará automáticamente a un largo sin especificar explícitamente el elenco
SchoolBoy

Se lanzará implícitamente a long, pero no a Longlo requerido para que la lambda se asigne a a Function. ¿Lo probaste? De todos modos, esa solución se puede reemplazar con la nueva.
Jakob

Puede usar tipos sin formato Set s=new HashSet();para guardar 7 bytes. (Además: afaik la importación de java.util.*;debe incluirse en el recuento de bytes -> +19 bytes.) La declaración de retorno puede ser return++j, la declaración if puede eliminarse a->{int i=0,j;for(;(a[j=Math.abs(a[i++])-1]*=-1)<0;);return++j;}(-3 bytes).
Nevay

2

Brachylog , 5 bytes

a⊇=bh

Pruébalo en línea!

Explicación

a⊇=bh  Input is a list.
a      There is an adfix (prefix or suffix) of the input
 ⊇     and a subsequence of that adfix
  =    whose elements are all equal.
   b   Drop its first element
    h  and output the first element of the rest.

El adfix incorporado aenumera 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.


Otra solución de 5 bytes: a⊇Ċ=hque solo analiza los subconjuntos de longitud 2.
Fatalize

1

C #, 145 bytes

using System.Linq;a=>{var d=a.Where(n=>a.Count(t=>t==n)>1);return d.Select((n,i)=>new{n,i}).FirstOrDefault(o=>d.Take(o.i).Contains(o.n))?.n??-1;}

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:

namespace System.Linq
{
    class P
    {
        static void Main()
        {
            Func<int[], int> f = a =>
            {
                var d = a.Where(n => a.Count(t => t == n) > 1);
                return d.Select((n, i) => new { n, i }).FirstOrDefault(o => d.Take(o.i).Contains(o.n))?.n ?? -1;
            };

            Console.WriteLine(f(new[] { 2, 3, 3, 1, 5, 2 }));
            Console.WriteLine(f(new[] { 2, 4, 3, 5, 1 }));

            Console.ReadLine();
        }
    }
}

Aquí está la versión de bucle simple. Pero me gusta mucho la versión de Linq.
LiefdeWen

@LiefdeWen Publíquelo como respuesta :) Aunque generalmente también me gusta más Linq :) También podría acortarlo con Linq, pero ahora estoy seguro.
TheLethalCoder

No, esta pregunta está superpoblada y prefiero que obtengas los votos positivos para esta pregunta.
LiefdeWen

1

Haskell , 78 69 bytes

 fst.foldl(\(i,a)(j,x)->(last$i:[j|i<0,elem x a],x:a))(-1,[]).zip[1..]

Prué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.


Se puede utilizar el "más corto condicional" de nuestros "Consejos para jugar al golf en Haskell" : \ ... ->(last$i:[j|i<0,elem x a],x:a). Además: no es necesario f=, porque se permiten funciones sin nombre.
nimi

@nimi gracias por el consejo!
jferard

1

Python 2, 71 65 bytes

Devuelve Nonesi no hay elemento duplicado

Editar: -6 bytes gracias a @ musicman523

def f(n):
 for a in n:
	u=-abs(a)
	if n[u]<0:return-u
	n[u]=-n[u]

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.


¡Buen trabajo! 65 bytes
musicman523

¿Estás seguro de que esto es O (1) en la memoria? Todavía está utilizando n bits de memoria para almacenar los números que ya se han visitado, aunque los bits estén en el signo. Me parece que esto es O (n) disfrazado
Wheat Wizard

Técnicamente, esto utiliza el espacio O (n) : los n bits de signo. Si la matriz solo puede contener valores entre 1y n, como se proporcionó, entonces obviamente no funciona.
Oliver Ni

Esto realmente se reduce a la representación que eliges para los números. Si se utilizan números sin signo, este es el espacio auxiliar O (n) . Si se usan números con signo, entonces el bit de signo ya está allí, lo que significa espacio auxiliar O (1) .
Halvard Hummel

Estoy de acuerdo contigo allí. Personalmente, te dejaría pasar usando números enteros con signo, siempre y cuando no hayas usado el bit de signo, debería tratarse del algoritmo, no de los aspectos técnicos del sistema. Dicho esto, creo que si vas a usar los bits de signo, tienes que contarlos. Creo que esta respuesta es bastante inteligente. Si me quedara algún voto hoy, lo votaría para contrarrestarlo.
Wheat Wizard

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.