Find the first duplicated element

39

2

Given an array a that contains only numbers in the range from 1 to a.length, find the first duplicate number for which the second occurrence has the minimal index. In other words, if there are more than 1 duplicated numbers, return the number for which the second occurrence has a smaller index than the second occurrence of the other number does. If there are no such elements, your program / function may result in undefined behaviour.

Example:

For a = [2, 3, 3, 1, 5, 2], the output should be firstDuplicate(a) = 3.

There are 2 duplicates: numbers 2 and 3. The second occurrence of 3 has a smaller index than the second occurrence of 2 does, so the answer is 3.

For a = [2, 4, 3, 5, 1], the output should be firstDuplicate(a) = -1.

This is , so shortest answer in bytes wins.

BONUS: Can you solve it in O(n) time complexity and O(1) additional space complexity?

Jeanderson Candido

Posted 2017-07-30T20:19:21.207

Reputation: 491

Comments are not for extended discussion; this conversation has been moved to chat.

– Martin Ender – 2017-09-03T13:12:36.197

Answers

15

Python 2, 34 bytes

O(n2) time, O(n) space

Saved 3 bytes thanks to @vaultah, and 3 more from @xnor!

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

Try it online!

musicman523

Posted 2017-07-30T20:19:21.207

Reputation: 4 472

1It looks like lambda l:l[map(l.remove,set(l))<0] works, even though the order of evaluation is weird. – xnor – 2017-07-31T00:08:32.077

This doesn't return -1 when no duplicates are found without the 'footer code', does that code not count towards the bytes? I'm new to code golf, sorry if it's a basic question! – Chris_Rands – 2017-07-31T12:38:59.957

@Chris_Rands Beneath the question musicman did ask if exception is okay instead of -1 and OP said its okay and musicman's answer throws exception. – LiefdeWen – 2017-07-31T13:55:51.003

That took me a while to figure out. Well played. Getting the 0th element of l using the conditional after modifying it is really clever. – Thoth19 – 2017-07-31T22:45:40.897

Does Python guarantee the time and space complexity of standard-library functions like set.remove? – Draconis – 2017-08-01T02:30:39.577

@Draconis This is actually list remove, and set construction. The whole algorithm is O(n^2): list remove is O(n) and there are O(n) iterations. It uses O(n) extra space by constructing the set and the list constructed as a result of the map function – musicman523 – 2017-08-01T03:58:38.010

@musicman523 Of course, my mistake! I see what you're doing now. Clever. – Draconis – 2017-08-01T05:22:11.500

11

JavaScript (ES6), 47 36 31 25 bytes

Saved 6 bytes thanks to ThePirateBay

Returns undefined if no solution exists.

Time complexity: O(n) :-)
Space complexity: O(n) :-(

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

How?

We keep track of already encountered values by saving them as new properties of the original array a by using negative numbers. This way, they can't possibly interfere with the original entries.

Demo

let f =

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

console.log(f([2, 3, 3, 1, 5, 2]))
console.log(f([2, 4, 3, 5, 1]))
console.log(f([1, 2, 3, 4, 1]))

Arnauld

Posted 2017-07-30T20:19:21.207

Reputation: 111 334

25 bytes: a=>a.find(c=>!(a[-c]^=1)) – None – 2017-07-30T22:11:22.797

@ThePirateBay Oh, of course. Thanks! – Arnauld – 2017-07-30T22:14:02.477

Just notice that Objects in JavaScript may not be implemented as hash table. Time complexity of accessing keys of some object may not be O(1). – tsh – 2017-08-01T09:47:03.930

6

Mathematica, 24 bytes

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

Mathematica's pattern matching capability is so cool!

Returns the original List for invalid input.

Explanation

#/.

In the input, replace...

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

A List with a duplicate element, with 0 or more elements before, between, and after the duplicates...

... :>a

With the duplicate element.

JungHwan Min

Posted 2017-07-30T20:19:21.207

Reputation: 13 290

6

Jelly, 5 bytes

Ṛœ-QṪ

Try it online!

How it works

Ṛœ-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.

Dennis

Posted 2017-07-30T20:19:21.207

Reputation: 196 637

œ- removes the rightmost occurrences? TIL – Erik the Outgolfer – 2017-07-31T09:42:13.987

This doesn't seem to return -1 for no duplicates. Throwing an exception is okay as per OP but I'm not sure if 0 is even though it's not in the range. – Erik the Outgolfer – 2017-07-31T12:18:34.930

5

Haskell, 35 bytes

f s(h:t)|h`elem`s=h|1<2=f(h:s)t
f[]

Try it online! Crashes if no duplicate is found.

Lynn

Posted 2017-07-30T20:19:21.207

Reputation: 55 648

4

Dyalog APL, 27 24 20 19 13 12 11 bytes

⊢⊃⍨0⍳⍨⊢=⍴↑∪

Now modified to not depend on v16! Try it online!

How? (With input N)

  • ⊢⊃⍨... - N at this index:
    • ⍴↑∪ - N with duplicates removed, right-padded with 0 to fit N
    • ⊢= - Element-wise equality with N
    • 0⍳⍨ - Index of the first 0. `

Zacharý

Posted 2017-07-30T20:19:21.207

Reputation: 5 710

nevermind, I misread the question. not enough test cases though... – Uriel – 2017-07-30T21:44:20.987

Sorry for misleading you, I also misread the question. – miles – 2017-07-30T22:12:05.973

Looks like 36 bytes to me. – Adám – 2017-07-31T11:09:36.013

Oh god, iota underbar isn't in ⎕AV, is it? – Zacharý – 2017-07-31T11:22:24.147

@Zacharý Right, Classic translates it to ⎕U2378 when loading. Try it online!

– Adám – 2017-08-04T04:44:28.683

You may throw an error instead of returning ¯1 – Adám – 2017-08-04T05:27:28.383

That is a very clever solution. +1. – Adám – 2017-08-05T22:02:56.013

I guess I'm in the array (or at least vector) oriented way of thinking now! – Zacharý – 2017-08-05T22:18:05.817

In the link the solution result enclosed in () where above is not enclose; in my cellphone I not know how to run that in tio ( dialog Unicode and classic) – RosLuP – 2017-11-30T13:24:07.140

It's sort of like an anonymous/lambda function in JavaScript/Python. You need but parentheses to call it, but the actual function doesn't require parentheses. – Zacharý – 2017-11-30T16:29:05.263

4

Jelly, 6 bytes

xŒQ¬$Ḣ

Try it online!

Returns the first duplicate, or 0 if there is no duplicate.

Explanation

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

miles

Posted 2017-07-30T20:19:21.207

Reputation: 15 654

It's golfier to use indexing like this: ŒQi0ị. – Erik the Outgolfer – 2017-07-31T12:23:10.870

@EriktheOutgolfer If there are no duplicates, i0 would return 0, where would index and return the last value of the input instead of 0. – miles – 2017-07-31T12:31:21.197

4

Japt, 7 bytes

æ@bX ¦Y

Test it online!

Explanation

 æ@   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

Alternatively:

æ@¯Y øX

Test it online!

Explanation

 æ@   ¯ 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

ETHproductions

Posted 2017-07-30T20:19:21.207

Reputation: 47 880

4

Pyth, 5 bytes

h.-Q{

Test suite

Remove from Q the first appearance of every element in Q, then return the first element.

isaacg

Posted 2017-07-30T20:19:21.207

Reputation: 39 268

@LuisMendo Ok thanks. Sorry for creating confusion, I should learn to read... – Mr. Xcoder – 2017-07-31T11:53:43.007

@Mr.Xcoder No, it's the OP's fault. That information should be in the challenge text, but just in a comment – Luis Mendo – 2017-07-31T12:40:47.357

3

Retina, 26 24 bytes

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

Try it online! Explanation: \b(\d+)\b matches each number in turn, and then the lookbehind looks to see whether the number is a duplicate; if it is the 1st match is ! output, rather than the count of matches. Unfortunately putting the lookbehind first doesn't seem to work, otherwise it would save several bytes. Edit: Added 7 bytes to comply with the -1 return value on no match. Saved 2 bytes thanks to @MartinEnder.

Neil

Posted 2017-07-30T20:19:21.207

Reputation: 95 035

2For the record, the lookaround won't backtrack. This prevents this from working if you try to put it before. I've made this mistake many times, and Martin always corrects me. – FryAmTheEggman – 2017-07-31T00:37:47.773

I got 30 bytes by using a lookahead instead of a lookbehind. Also, the rules now say you don't need to return -1. – Value Ink – 2017-08-04T07:45:40.727

@ValueInk But the correct answer for that test case is 3... – Neil – 2017-08-04T08:00:19.193

OH. I misread the challenge, whoops – Value Ink – 2017-08-04T08:47:46.250

3

Python 3, 94 92 bytes

O(n) time and O(1) extra memory.

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

Try it online!

Source of the algorithm.

Explanation

The basic idea of the algorithm is to run through each element from left to right, keep track of the numbers that have appeared, and returning the number upon reaching a number that has already appeared, and return -1 after traversing each element.

However, it uses a clever way to store the numbers that have appeared without using extra memory: to store them as the sign of the element indexed by the number. For example, I can represent the fact that 2 and 3 has already appeared by having a[2] and a[3] negative, if the array is 1-indexed.

Leaky Nun

Posted 2017-07-30T20:19:21.207

Reputation: 45 011

What would this do for i where a[i] > n? – Downgoat – 2017-07-31T06:02:36.943

@Downgoat read the question again. – Leaky Nun – 2017-07-31T06:04:53.153

The question says 1 to a.length but for a[i]= a.length wouldn't this go out of bounds? – Downgoat – 2017-07-31T06:05:56.763

@Downgoat t=abs(a[i])-1=a.length-1 – Leaky Nun – 2017-07-31T06:09:10.893

Oh duh sorry thanks – Downgoat – 2017-07-31T06:09:40.133

3

Note from feersum: "solution is cheating because it uses integers 1 bit larger than the input."

– Leaky Nun – 2017-07-31T06:22:00.620

-2 bytes with enumerate – musicman523 – 2017-08-13T17:04:27.167

3

APL (Dyalog), 20 bytes

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

Try it online!

2⍴¯1 negative one reshaped into a length-two list

⎕, get input (mnemonic: console box) and prepend to that

n← store that in n

,\ prefixes of n (lit. cumulative concatenation)

( apply the following tacit function to each prefix

, [is] the ravel (just ensures that the prefix is a list)

 different from

 the unique elements[?] (i.e. is does the prefix have duplicates?)

n/⍨ use that to filter n (removes all elements until the first for which a duplicate was found)

 pick the first element from that

Adám

Posted 2017-07-30T20:19:21.207

Reputation: 37 779

Wow, you got beat three times. Still, +1. And can you add an explanation of how this works? – Zacharý – 2017-08-03T22:10:12.563

@Zacharý Apparently I just needed to get the ball rolling. Here you go. – Adám – 2017-08-04T05:13:07.560

@Zacharý Eventually, I managed to beat them all.

– Adám – 2017-08-04T08:09:12.410

3

Perl 6, 13 bytes

*.repeated[0]

Try it


Explanation

  • The * is in a Term position so the whole statement is a WhateverCode lambda.

  • The .repeated is a method that results in every value except for the first time each value was seen.

    say [2, 3, 3, 3, 1, 5, 2, 3].repeated.perl; # (3, 3, 2, 3).Seq
    #   (      3, 3,       2, 3).Seq
    
  • [0] just returns the first value in the Seq.
    If there is no value Nil is returned.
    (Nil is the base of the Failure types, and all types are their own undefined value, so Nil different than an undefined value in most other languages)


Note that since the implementation of .repeated generates a Seq that means it doesn't start doing any work until you ask for a value, and it only does enough work to generate what you ask for.
So it would be easy to argue this has at worst O(n) time complexity, and at best O(2) time complexity if the second value is a repeat of the first.
Similar can probably be said of memory complexity.

Brad Gilbert b2gills

Posted 2017-07-30T20:19:21.207

Reputation: 12 713

3

APL, 15

{⊃⍵[(⍳⍴⍵)~⍵⍳⍵]}

Seems like we can return 0 instead of -1 when there are no duplicates, (thanks Adám for the comment). So 3 bytes less.

A bit of description:

⍵⍳⍵         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

For reference, old solution added -1 to the list at the end, so if the list ended up empty, it would contain -1 instead and the first element would be -1.

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

Try it on tryapl.org

Moris Zucca

Posted 2017-07-30T20:19:21.207

Reputation: 1 519

You may return a zero instead of ¯1, so {⊃⍵[(⍳⍴⍵)~⍵⍳⍵]} should do. – Adám – 2017-08-04T05:29:08.167

3

APL (Dyalog), 11 bytes

As per the new rules, throws an error if no duplicates exist.

⊢⊃⍨⍬⍴⍳∘≢~⍳⍨

Try it online!

⍳⍨ the indices of the first occurrence of each element

~ removed from

⍳∘≢ of all the indices

⍬⍴ reshape that into a scalar (gives zero if no data is available)

⊃⍨ use that to pick from (gives error on zero)

 the argument

Adám

Posted 2017-07-30T20:19:21.207

Reputation: 37 779

Well, yeah, when the rules are changed, of course you can beat them all! – Zacharý – 2017-08-04T20:05:07.090

Well, I tied you. – Zacharý – 2017-08-04T20:56:01.960

2

MATL, 8 bytes

&=Rsqf1)

Gives an error (without output) if no duplicate exists.

Try at MATL Online!

Explanation

&=   % 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

Luis Mendo

Posted 2017-07-30T20:19:21.207

Reputation: 87 464

2

J, 17 16 bytes

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

How?

(*/{_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

bob

Posted 2017-07-30T20:19:21.207

Reputation: 131

2

R, 28 bytes

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

Try it online!

djhurio

Posted 2017-07-30T20:19:21.207

Reputation: 1 113

I think you can now return NA for missing values since the spec has changed; so (x=scan())[duplicated(x)][1] is perfectly valid. – Giuseppe – 2017-07-31T12:53:46.200

2

R, 34 bytes

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

Cut a few characters off the answer from @djhurio, don't have enough reputation to comment though.

RoryT

Posted 2017-07-30T20:19:21.207

Reputation: 121

oh...I didn't see this answer; this is good for the prior spec when missing values required -1 but with the new spec, I managed to golf it down even more. This is still solid and it's a different approach from the way he did it, so I'll give you a +1! – Giuseppe – 2017-07-31T14:22:45.317

2

Java 8, 82 78 76 bytes No longer viable, 75 67 64 bytes below in edit

As a lambda function:

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

Probably can be made much smaller, this was very quick.

Explanation:

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
}

*Edit*

75 67 64 bytes using the negation strategy:

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

Try it online!

(-3 bytes thanks to @Nevay)

Explanation:

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
}

Loops over the array, negating to keep track. If no dupes, just runs over and throws an error.

Both of these work on O(n) time and O(n) space complexity.

SchoolBoy

Posted 2017-07-30T20:19:21.207

Reputation: 121

It's worth noting that this will need to be assigned to a lambda returning Number, since i is a long and -1 is an int. – Jakob – 2017-08-10T14:36:02.670

@Jakob Not necessary, -1 being an int will automatically be cast to a long without explicitly specifying the cast – SchoolBoy – 2017-08-10T14:47:51.720

It will cast implicitly to long, but not to Long as required for the lambda to be assigned to a Function. Did you test it? Regardless, that solution can be replaced with your new one. – Jakob – 2017-08-10T16:13:59.387

You can use raw types Set s=new HashSet(); to save 7 bytes. (Besides: afaik the import of java.util.*; has to be included into the byte count -> +19 bytes.) The return statement can be return++j, the if-statement can be removed a->{int i=0,j;for(;(a[j=Math.abs(a[i++])-1]*=-1)<0;);return++j;} (-3 bytes). – Nevay – 2017-08-11T13:34:24.423

2

J, 12 bytes

,&_1{~~:i.0:

Try it online!

Explanation

,&_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

miles

Posted 2017-07-30T20:19:21.207

Reputation: 15 654

2

Dyalog APL Classic, 18 chars

Only works in ⎕IO←0.

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

Remove from the list of indices of the elements of the argument with a prepended "-1" the list indices of its nub and then pick the first of what's left. If after the removal there only remains an empty vector, its first element is by definition 0 which is used to index the extended argument producing the desired -1.

lstefano

Posted 2017-07-30T20:19:21.207

Reputation: 850

Um... what's with the random leading spaces? +1 for outgolfing me by one byte. – Zacharý – 2017-08-03T22:07:39.330

You may throw an error instead of returning ¯1, so you can remove ¯1, and use ⎕IO←1. – Adám – 2017-08-04T05:30:44.540

2

PHP, 56 44 38 32 bytes

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

Run like this:

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

Explanation

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.

Tweaks

  • Saved 12 bytes by using variables instead of an array
  • Saved 6 bytes by making use of the "undefined behavior" rule for when there is no match.
  • Saved 6 bytes by using post-increment instead of setting to 1 after each loop

Complexity

As can be seen from the commented version of the code, the time complexity is linear O(n). In terms of memory, a maximum of n+1 variables will be assigned. So that's O(n).

aross

Posted 2017-07-30T20:19:21.207

Reputation: 1 583

Thanks for not using a weird encoding. But you should add the error_reporting option to the byte count (or use -n, which is free). – Titus – 2017-08-11T11:33:15.793

We've been here before. PHP notices and warnings are ignorable. I might as well pipe them to /dev/null, which is the same. – aross – 2017-08-11T13:02:34.130

I tend to remember the wrong comments. :) Isn´t this O(n)? – Titus – 2017-08-11T13:04:42.033

Yes it's linear – aross – 2017-08-11T13:05:05.387

How is that O(1) for additional space? You're literally assigning a new variable per n, which is O(n) – Xanderhall – 2017-08-11T14:46:37.693

@Xanderhall, I might have misunderstood, but doesn't the question say additional space? I took that to mean O(n) was assumed to be necessary anyway. – aross – 2017-08-11T16:09:24.290

The storage for the initial list hasO(n) space complexity, yes. However, if you're say, storing every single value in a separate list to check if you've passed them, that's O(n) additional space complexity. What you're doing is effectively the same, but without the 'list' construct. In your worst case (say, [1, 2, ..., n, 1] you'll end up with n variables created additionally, which is O(n) space complexity – Xanderhall – 2017-08-11T16:14:50.767

@Xanderhall The list is actually even worse than O(n), its O(n log n) because each number requires at most O(log n) bits to store and there are n of them. I don't understand php so I can't comment on this answers complexity directly but if it stores up to n+1 values that can be as large as n then it has O(n log n) space complexity. It only has O(n) space complexity if each variable is some fixed number of bits. – Post Rock Garf Hunter – 2017-08-13T04:38:48.097

@WheatWizard, not at all. They are INTs (basically booleans) that will never be anything other than 0, 1 or 2. And the 2 case is not used, it's just a simplification of the code – aross – 2017-08-14T08:34:52.950

@Xanderhall, I removed the statement as I'm not sure now what was meant. – aross – 2017-08-14T08:36:10.103

2

Ruby, 28 36 bytes

Misunderstood the challenge the first time. O(n) time, O(n) space.

->a{d={};a.find{|e|b=d[e];d[e]=1;b}}

Try it online!

Value Ink

Posted 2017-07-30T20:19:21.207

Reputation: 10 608

2

Java (OpenJDK 8), 65 117 109 bytes

Previous 65 byte solution:

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

New solution. 19 bytes are included for import java.math.*;

-8 bytes thanks to @Nevay

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

Try it online!

Edit

The algorithm in my original program was fine, but the static size of the datatype used meant that it broke fairly quickly once the size went above a certain threshold.

I have changed the datatype used in the calculation to increase the memory limit of the program to accommodate this (using BigInteger for arbitrary precision instead of int or long). However, this makes it debatable whether or not this counts as O(1) space complexity.

I will leave my explanation below intact, but I wish to add that I now believe it is impossible to achieve O(1) space complexity without making some assumptions.

Proof

Define N as an integer such that 2 <= N .

Let S be a list representing a series of random integers [x{1}, ..., x{N}], where x{i} has the constraint 1 <= x{i} <= N.

The time complexity (in Big-O notation) required to iterate through this list exactly once per element is O(n)

The challenge given is to find the first duplicated value in the list. More specifically, we are searching for the first value in S that is a duplicate of a previous item on the list.

Let p and q be the positions of two elements in the list such that p < q and x{p} == x{q}. Our challenge becomes finding the smallest q that satisfies those conditions.

The obvious approach to this problem is to iterate through S and check if our x{i} exists in another list T: If x{i} does not exist in T, we store it in T. If x{i} does exist in T, it is the first duplicate value and therefore the smallest q, and as such we return it. This space efficiency is O(n).

In order to achieve O(1) space complexity while maintaining O(n) time complexity, we have to store unique information about each object in the list in a finite amount of space. Because of this, the only way any algorithm could perform at O(1) space complexity is if: 1. N is given an upper bound corresponding to the memory required to store the maximum number of possible values for a particular finite datatype. 2. The re-assignment of a single immutable variable is not counted against the complexity, only the number of variables (a list being multiple variables). 3. (Based on other answers) The list is (or at least, the elements of the list are) mutable, and the datatype of the list is preset as a signed integer, allowing for changes to be made to elements further in the list without using additional memory.

1 and 3 both require assumptions and specifications about the datatype, while 2 requires that only the number of variables be considered for the calculation of space complexity, rather than the size of those variables. If none of these assumptions are accepted, it would be impossible to achieve both O(n) time complexity and O(1) space complexity.

Explanation

Whoo boy, this one took an embarrassingly long time to think up a bit of brain power.

So, going for the bonus is difficult. We need both to operate over the entire list exactly once and track which values we've already iterated over without additional space complexity.

Bit manipulation solves those problems. We initialize our O(1) 'storage', a pair of integers, then iterate through the list, OR-ing the ith bit in our first integer and storing that result to the second.

For instance, if we have 1101, and we perform an OR operation with 10, we get 1111. If we do another OR with 10, we still have 1101.

Ergo, once we perform the OR operation and end up with the same number, we've found our duplicate. No duplicates in the array causes the program to run over and throw an exception.

Xanderhall

Posted 2017-07-30T20:19:21.207

Reputation: 1 236

Also, your second test includes the number 100, but thats impossible since the array itself is only 5 long – SchoolBoy – 2017-08-10T14:54:34.740

Also, this fails since an int doesn't have enough storage.

– SchoolBoy – 2017-08-10T14:59:09.533

@SchoolBoy Good catch. My only problem is that there doesn't seem to be any upper limit on the size of the array, so I can't realistically change my code to solve memory issues. – Xanderhall – 2017-08-10T16:26:01.087

@Xanderhall True, but i feel like 32 (or if you use a long, 64) numbers is too little :p. Either way, imposing a limit on the input, and then allocating the maximum memory needed and calling it O(1) memory is just a cheat. It is still O(n) since if the size of the input increased, so would this upper bound to the memory. Which is also why I think it is impossible to create an O(n) O(1) algorithm – SchoolBoy – 2017-08-10T16:29:05.990

@Xanderhall P.S. I'm getting close to your 65, I'm at 67 bytes :p – SchoolBoy – 2017-08-10T16:29:50.590

You don't need d, the if-statement can be removed r->{int z,i=0;for(BigInteger c=BigInteger.ZERO;!c.equals(c=c.setBit(z=r[i++])););return z;} (91+19 bytes). If you don't mind to depend on the implementation rather than on the api, you can use c.min(c=c.setBit(z=r[i++]))!=c instead of #equals to save another byte. – Nevay – 2017-08-11T13:45:59.717

I may not be fully understanding the final part about bit ORing, but just because your current OR product ORed with this new number is the same, doesn't mean it's been in your list before. For example, if your list was [12, 4, 12], you would do 1100 | 0100 = 1100 but 4 isn't a duplicate. Even the example [2, 4, 3, 5, 1] fails since by the time you get to 5 your OR product will be 010 | 100 | 011 = 111, which when ORed with 101 is still 111. Maybe I'm just not understanding what you're trying to say... – Arnold Palmer – 2017-08-11T15:31:32.690

You're not ORing the nth number found in the list with the storage, you're ORing the nth byte in the storage. ie: in [1, 2, 3, 2, 3], you would get 001 (first bit), 011(second bit), 111(third bit), 111(second bit again), then 2 would be returned. – Xanderhall – 2017-08-11T16:07:29.670

I would say that although the input is not specifically limited, imposing a limit like 32 on it is harsh, but using longs or ints instead of BigIntegers should be fine – SchoolBoy – 2017-08-12T15:46:31.343

I know it's been a while, but you can golf import java.math.*;BigInteger c=BigInteger.ZERO; to java.math.BigInteger t=null,c=t.ZERO; for -11 bytes. – Kevin Cruijssen – 2018-03-27T12:28:03.407

2

Brachylog, 5 bytes

a⊇=bh

Try it online!

Explanation

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.

The adfix built-in a lists first all prefixes in increasing order of length, then suffixes in decreasing order of length. Thus the output is produced by the shortest prefix that allows it, if any. If a prefix has no duplicates, the rest of the program fails for it, since every subsequence of equal elements has length 1, and the first element of its tail doesn't exist. If a prefix has a repeated element, we can choose the length-2 subsequence containing both, and the program returns the latter.

Zgarb

Posted 2017-07-30T20:19:21.207

Reputation: 39 083

Another 5 bytes solution: a⊇Ċ=h, which only looks at length-2 subsets. – Fatalize – 2017-12-01T07:20:02.330

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;}

Probably a lot shorter way to do this in C# with a simple loop but I wanted to try it with Linq.

Try it online!

Full/Formatted version:

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();
        }
    }
}

TheLethalCoder

Posted 2017-07-30T20:19:21.207

Reputation: 6 930

Here is the simple loop version. But I like the Linq version much more. – LiefdeWen – 2017-07-31T13:13:09.530

@LiefdeWen Post it as an answer :) Though I do usually like Linq better too :) Might be able to get it shorter with Linq too but I'm now sure. – TheLethalCoder – 2017-07-31T13:16:27.980

Nah, this question is overpopulated and I would rather you get the up-votes for this question. – LiefdeWen – 2017-07-31T13:17:42.953

1

Haskell, 78 69 bytes

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

Try it online!

Saved 9 bytes thanks to @nimi

A basic path through the list. If the current element has not yet been seen (i<0) and is in the accumulator list (elem x a) then store the current index. Else, keep the index -1. In any case, add the current element to the accumulator list.

EDIT: I did not read the question carefully enough: this code outputs the index of the second element of a duplicate element.

jferard

Posted 2017-07-30T20:19:21.207

Reputation: 1 764

You can use the "Shorter Conditional" from our "Tips for golfing in Haskell": \ ... ->(last$i:[j|i<0,elem x a],x:a). Also: no need for the f=, because unnamed functions are allowed.

– nimi – 2017-07-31T14:44:27.050

@nimi thanks for the tip! – jferard – 2017-07-31T20:16:48.063

1

Python 2, 71 65 bytes

Returns None if there is no duplicate element

Edit: -6 bytes thanks to @musicman523

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

Try it online!

O(n) time complexity, O(n) space complexity, O(1) auxiliary space.

As the input list uses O(n) space, the space complexity is bound by this. Meaning we cannot have a lower space complexity than O(n)

Does modify the original list, if this is not allowed we could do it in the same complexity with 129 bytes

Explanation

Since every element is greater than 0 and less than or equal to the size of the list, the list has for each element a, an element on index a - 1 (0 indexed). We exploit this by saying that if the element at index i is negative, we have seen it before.

For each element a in the list n, we let u be negative the absolute value of a. (We let it be negative since python can index lists with negative indices, and we would otherwise need to do u=abs(a)-1) If the element at index u in the list is negative, we have seen it before and can therefore return -u (to get the absolute value of a, as all elements are positive). Else we set the element at index u to be negative, to remember that we have seen an element of value a before.

Halvard Hummel

Posted 2017-07-30T20:19:21.207

Reputation: 3 131

Nice job! 65 bytes

– musicman523 – 2017-08-10T05:50:17.203

Are you sure this is O(1) in memory? You are still using n bits of memory to store what numbers have already been visited, even though the bits are in the sign. It seems to me that this is O(n) in disguise – Post Rock Garf Hunter – 2017-08-10T07:06:19.497

Technically this uses O(n) space - the n sign bits. If the array can only hold values between 1 and n, like how it was given, then it obviously doesn't work. – Oliver Ni – 2017-08-10T07:36:13.390

This really just comes down to the representation you choose for the numbers. If unsigned numbers are used, then this is O(n) auxiliary space. If signed numbers are used, then the sign bit is already there, meaning O(1) auxiliary space. – Halvard Hummel – 2017-08-10T07:52:50.020

I agree with you there. I personally would let you slide using signed integers as long as you didn't use the sign bit, it should be about the algorithm not the technicalities of the system. That being said I do think if you are going to use the sign bits you have to count them. I think this answer is pretty clever. If I any votes left today I would upvote it to counteract the downvote. – Post Rock Garf Hunter – 2017-08-10T14:32:17.060

I think n[u]*=-1 would work to save two bytes. – Zacharý – 2017-08-12T16:15:24.537

1

Jelly, 4 bytes

ŒQi0

Try it online!

In case that all elements are unique, this returns 0 (undefined behavior).

Erik the Outgolfer

Posted 2017-07-30T20:19:21.207

Reputation: 38 134

1

K4, 12 bytes

Solution:

*<0W^*:'1_'=

Example:

*<0W^*:'1_'=2 3 3 1 5 2
3

Explanation:

Returns first item in the list for unique lists otherwise returns first dupe:

*<0W^*:'1_'= / the solution
           = / group the list, e.g. 2 3 1 5!(0 5;1 2;,3;,4)
        1_'  / drop first from each value, e.g. 2 3 1 5!(,5;,2;`long$();`long$())
     *:'     / first (*:) each ('), e.g. 2 3 1 5!5 2 0N 0N
  0W^        / fill (^) nulls with infinity (0W), e.g. 2 3 1 5!5 2 0W 0W
 <           / sort keys based on values, e.g. 3 2 1 5
*            / take the first, e.g. 3

streetster

Posted 2017-07-30T20:19:21.207

Reputation: 3 635

1

Husk, 4 bytes

←Ṡ-u

Returns 0 if no input contains no duplicate, try it online!

Explanation

←Ṡ-u  -- takes a list X as input & returns 0 or first duplicate
 Ṡ-   -- compute X - ...
   u  --       ...   deduplicate X
←     -- get first element or 0 if empty

ბიმო

Posted 2017-07-30T20:19:21.207

Reputation: 15 345

0

Axiom 96, bytes

g(a:List INT):INT==(for i in 2..#a repeat(for j in 1..i-1 repeat if a.i=a.j then return a.i);-1)

it is O(n^2)

RosLuP

Posted 2017-07-30T20:19:21.207

Reputation: 3 036

0

Javascript, 54 bytes

a=>(b=[],a.find(e=>b.includes(e)?e:(b.push(e),0))||-1)

Uses another array to keep track of the already encountered values.

SuperStormer

Posted 2017-07-30T20:19:21.207

Reputation: 927

0

C#, 65 67 bytes

With thanks to LiefdeWen for the 89 bytes base code here, here's an further shortened version of that

a=>{for(int p=0,q=0;;q++)for(p=0;p<q;)if(a[q]==a[p++])return a[q];}

We can dispense with the return -1 and length check as it's apparently OK to throw an exception if not found, so we just let the outer loop run off the end of the array. Some other whitespace changes, and jigging the declarations around to reduce the number of times we write "int" etc..

Caius Jard

Posted 2017-07-30T20:19:21.207

Reputation: 151

1Pretty sure you can cut 1 char by making the second loop a while.

a=>{for(int p=0,q=0;;q++)while(p++<q)if(a[q]==a[p])return a[q];} – Broom – 2017-08-03T15:08:56.133

I checked, and it turns out, alas, it doesnt work out.. Doing p++<q means that although p is indeed incremented after the check of p<q, it is incremented before the inner loop code of if(a[p]==a[q]).. this has the undesirable effect of comparing a[1]==a[1] on the second iteration (q=1) which breaks the program. Still a useful comment though as it allowed me to chase down a bug (missing p=0 on inner loop), that unfortunately added 3 bytes but I was able to save 1 by moving p++ to the if, thanks to your suggestion – Caius Jard – 2017-08-03T15:36:55.380

0

Python 2, 115 113 bytes

a,i,k=input(),0,[]
while 1:
	if i==len(a):print-1;break
	elif a[i]not in k:k+=[a[i]]
	else:print a[i];break
	i+=1

Try it online!

Koishore Roy

Posted 2017-07-30T20:19:21.207

Reputation: 1 144

1I might be wrong, but doesn't the fact that your list k can have up to n elements make this a O(n) space complexity solution? – Value Ink – 2017-08-04T07:47:57.473

Not to mention the fact that check a[i] in k may take O(n) (unless Python arrays is special) – user202729 – 2017-08-04T07:55:03.850

@ValueInk you are correct. my bad. – Koishore Roy – 2017-08-07T19:36:41.687

This is actually O(n log n) in space complexity, because the numbers in your k take O(log n) memory to store each and there are as many as n of them. – Post Rock Garf Hunter – 2017-08-10T07:08:09.443

I should think user202729 is correct too, making your algorithm O(n^2) time complexity. The while loop is O(n) (early break or not), and so is the in call. – Sanchises – 2017-08-10T07:14:23.933

@WheatWizard Wait what? Why the log n? k is filled with integers which are O(1) each, right? Their magnitude is not dependent on n. – Sanchises – 2017-08-10T08:35:15.013

@Sanchises The integers are dependent on n. Since integers can always be as large as the length of the array, each will take (in the worst case) O(log n) bits to represent. Meaning we have an array of length of up to n filled with items of up to log n bits. – Post Rock Garf Hunter – 2017-08-10T13:38:11.330

@WheatWizard Ah yes, I didn't read that. But that means that we cannot even store one integer in O(1) extra space complexity, so I should think the author did not account for that when making the bonus. – Sanchises – 2017-08-10T14:26:17.900

@Sanchises You have a point, and I think you are probably correct however we should probably aim to be correct even if we think the author made a mistake. :) – Post Rock Garf Hunter – 2017-08-10T14:28:17.373

Spaces, print -1=>print-1, a[i] not in=>a[i]not in. – Zacharý – 2017-08-10T20:11:33.673

0

PROLOG (SWI), 54 + 3 = 57 bytes

f([H|_],L,H):-member(H,L).
f([H|T],L,X):-f(T,[H|L],X).

+3 bytes because it requires an empty list as its second argument:

f([5,3,2,1,2,3,5],[],X)

will unify X to the first duplicate value in the list.

Try it online!

Here's the basic algorithm: we have the list to parse, and an accumulator list that starts empty. For each element in the list: pop that element. If it is in the accumulator, return the element. Else, put it in the accumulator.

Nathan.Eilisha Shiraini

Posted 2017-07-30T20:19:21.207

Reputation: 561

0

05AB1E, 16 bytes

ε¹SsQƶ0K1è}W<¹sè

Try it online!

Magic Octopus Urn

Posted 2017-07-30T20:19:21.207

Reputation: 19 422

0

Perl 5, 36 + 2 (-ap) = 38 bytes

Runs in O(n) time.

$s{$_}=1while!$s{$_=shift@F};$_||=-1

Try it online!

Takes the input list space separated.

Xcali

Posted 2017-07-30T20:19:21.207

Reputation: 7 671

0

Python 2, 59 bytes, O(n) time, O(n) memory

a=input()
i=0
for x in a:
 if i&1<<x:print x;break
 i^=1<<x

Try it online!

This does one pass of the list. Thus is O(n) For memory it stores a integer i, which has bits representing which numbers have already been visited. If a number has already been visited we output, otherwise we turn the bit on. If no matches are found we do nothing.

This makes a slight improvement over the naïve way which requires copying the list at the cost of O(n log n) memory.

Post Rock Garf Hunter

Posted 2017-07-30T20:19:21.207

Reputation: 55 382

i needs to have n bits, so I think it should be O(n) memory. (i can take values up to 2**n - 2 even if there is a duplicate.) – tehtmi – 2017-08-10T06:57:45.867

However, it is better than a copy of the list, as a copy of the list in general needs log(n)*n bits if we are equally as strict (log(n) bits per item times n items). – tehtmi – 2017-08-10T07:02:36.497

@tehtmi Fixed now, thanks for that. I have trouble with space complexity. – Post Rock Garf Hunter – 2017-08-10T07:05:08.337

0

C (gcc), 98 bytes

0-indexed

Takes a space separated list of integers. returns i < n on a successful match and i == n on failure.

time complexity is O(n^2) yuck!

space complexity is O(1)

program-name.exe 58 77 57 7 75 44 29 97 92 59 36 52 95 87 44 24 47 18 34 22
Returns 14  (the two 44s)

Golfed

i=1,j;main(int c,char**v){for(;i<c;i++)for(j=i-1;j;j--)if(!strcmp(v[i],v[j]))goto f;f:return i-1;}

Try it online!

Ungolfed

i=1,j;
main(int c, char**v){
    for(;i < c; i++)
        for(j=i-1; j; j--)
            if(!strcmp(v[i], v[j]))
                goto f;
    f:
    return i-1;
}

Marcos

Posted 2017-07-30T20:19:21.207

Reputation: 171

Time complexity is related to looping. A loop that touches every slot of an array with size n is said to have time complexity O(n). Since you have a for loop inside another one, and each one is on the order O(n) (since they aren't always a constant range), your program has time complexity O(n^2). For more info about Big O Notation, check out this Wikipedia page.

– Arnold Palmer – 2017-08-11T15:44:01.857

I see, thanks for the info. I updated my answer. – Marcos – 2017-08-11T15:51:57.600

The time complexity should be O(n^2 log m), where n is how many numbers there are, and m is the largest number given. This is because strcmp takes linear time with respect to the number of characters in each string – musicman523 – 2017-08-13T16:58:37.723

0

PowerShell, 93 bytes

$c=0..$a.Count;$i=0;$r=($a|%{$i++;if($c[$_]++ -ne $_){$i}});if($r.Count -gt 0){$r[0]}else{-1}

Try it online!

Doug Coburn

Posted 2017-07-30T20:19:21.207

Reputation: 141

0

JavaScript (Node.js), 81 bytes

Time complexity is O(n) !!!!

Space complexity is O(1) !!!!

a=>a.reduce((r,e,i)=>r?r:(a[(e<0?~e:e)-1]>0?((a[(e<0?~e:e)-1]^=-1)?0:0):i+2),0)-1

Try it online!

Strategy

This algorithm leverages the fact that indexes are positive but numbers in javascript are signed. Also, zeros are not allowed input. As long as the array is not longer than 2^31, this solution will work. I double the use of the original array as my lookup array -- marking a visited number by switching the value at that index with its 2's compliment.

Doug Coburn

Posted 2017-07-30T20:19:21.207

Reputation: 141

We've had this discussion on another answer using a similar algorithm. Although it may appear that this is O(1) you are actually using O(n) memory. Since you use the sign bit of each number you are actually using 1 bit per number. The fact that the bits are already allocated by Javascript is just a trick to make it appear as if you are using less memory. – Post Rock Garf Hunter – 2017-08-13T04:30:25.107

I don't think you are being intentionally deceitful here, the concept of additional memory that seems to be embedded in the question is rather flawed. O(n) memory is required just to store the array already unless you are using a stream so any algorithm that stores the entire list in memory at any point is truly O(n log n) anyway (log n because each number takes at most log n bits to store). – Post Rock Garf Hunter – 2017-08-13T04:31:57.597

@WheatWizard Wouldn't it be O(n log m) since n (the number of inputs) and m (the largest integer) are independent of one another? Though I usually assume integers are a fixed width (more background in Java/C++/C than Python/Javascript) which means their storage is O(1) – musicman523 – 2017-08-13T16:55:46.207

@WheatWizard, I see your point. Like you said, the question wording is a bit open. However, I think this is a legitimate solution. No other solution makes any attempt to use fewer bits to store each number. The parameters were for O(1) additional space complexity and the array can only contain numbers between 1 and a.len. It is worded like a homework question begging for such a solution. You are correct about O(n log n) initial space complexity if you assume that storage space per number is not fixed. This is seldom an assumption and I don't think it was implied in this competition. – Doug Coburn – 2017-08-13T17:00:06.493

0

APL NARS 52 char 104 bytes

f←{1≠⍴⍴⍵:¯1⋄v←(⍵⍳⍵)-⍳⍴⍵⋄m←v⍳(v<0)/v⋄m≡⍬:¯1⋄(1⌷m)⌷⍵}

comments (for me f could return results even for vectors of characters that here seems to be the old strings)

1≠⍴⍴⍵:¯1     if ⍵ has rank different from 1 than it is not a vector so return -1
v←(⍵⍳⍵)-⍳⍴⍵   v is 0 0 0...0 only if there are not repetitions, else there is some value <0
m←v⍳(v<0)/v   m return the indices j of v where v[j]<0, and so ⍵[j] are all the duplicates
m≡⍬:¯1       if m is void than that index not exist, so no duplicate and return -1
(1⌷m)⌷⍵      else return the value in ⍵ of the first element of m

results

  f 1
¯1
  f 1,2,3,4
¯1
  f 1 2 3 3
3
  f 2 3 3 1 5 2
3
  f ,1
¯1

RosLuP

Posted 2017-07-30T20:19:21.207

Reputation: 3 036

It's possible to use Dyalog's codepage to make it so it's 52 bytes. Also, you don't need to store the results in a function. And would either of these work in NARS? {1≠⍴⍴⍵:¯1⋄⍬≡m←v⍳v/⍨0>v←(⍵⍳⍵)-⍳⍴⍵:¯1⋄⍵⌷⍨1⌷m} or {1≠⍴⍴⍵:¯1⋄⍬≡m←v⍳(0>v)/v←(⍵⍳⍵)-⍳⍴⍵:¯1⋄(1⌷m)⌷⍵}? – Zacharý – 2017-11-30T16:39:13.497

@Zacharý I like "f←{1≠⍴⍴⍵:¯1⋄⍬≡m←v⍳(0>v)/v←(⍵⍳⍵)-⍳⍴⍵:¯1⋄(1⌷m)⌷⍵}" thank you; for what regard if the name of function I ' am not agree with community, for me the name has to be inside the solution, it will for me 2 characters more (or +4 bytes). It seems my target is not 100% codegolf, perhaps 80% . It would be better for a solution in APL count for codegolf it would be in characters and not in bytes – RosLuP – 2017-11-30T17:52:14.520

0

Alice, 21 bytes

/o/
\iHQ@/w].(?~!&WK?

Try it online!

Explanation

The main idea is to store each value we've encountered on the tape and then use the search command to check whether the current value has already been written to the tape. It's important here that the tape is initially completely filled with -1s.

/      Switch to Ordinal mode.
i      Read all input as a string.
/      Switch back to Cardinal mode.
H      Take the absolute value of the top stack element. This doesn't really do
       anything to the numbers, because they're all positive anyway, but
       it forces Alice to convert the input string to individual integer
       values it contains, thus splitting the string.
/      Switch to Ordinal mode.
Q      Reverse the stack so that the first input is on top.
/      Switch back to Cardinal mode.
w      Push the current IP position onto the return address stack. This marks
       the beginning of the main loop.
         Call the current value on top of the stack X.
  ]      Advance the tape head (unnecessary on the first iteration, but
         we need to do it between iterations).
  .      Duplicate X.
  (      Search left of the tape head for X. If X isn't found nothing happens
         and we remain on a -1. Otherwise, the tape head jumps to that
         earlier occurrence.
  ?      Retrieve the value under the tape head. If X is new, this will be
         -1. Otherwise, it will be X. Call this value Y.
  ~!     Store X in the current cell.
  &W     Discard Y values from the return address stack. If Y is negative,
         this does nothing, otherwise it discards the one return address we
         have there, terminating the loop.
$K     If the return address is still there, jump back to the w to process 
       the next element. Otherwise continue.
?      Retrieve X.
\      Switch to Ordinal mode.
o      Output the result.
H      Trim, does nothing.
@      Terminate the program.

I've got an alternative solution at the same byte count:

/o/
\iHQ@/w.!(]?h$WK[?

I also had a solution where I used the tape as a lookup table, storing at each index X whether X had already been seen in the sequence, but it ended up being a byte longer (it's conceptually easier, but moving the tape head to position X from an arbitrary positive position requires five bytes with q&[&]).

Martin Ender

Posted 2017-07-30T20:19:21.207

Reputation: 184 808

0

Python 3, 47 bytes

f=lambda l,i=0:l[i]if l[i]in l[:i]else f(l,i+1)

Try it online!

pizzapants184

Posted 2017-07-30T20:19:21.207

Reputation: 3 174

0

Haskell, 34 bytes

import Data.List
f x=head$x\\nub x

Try it online! For an input x = [2,3,3,1,5,2], nub x removes duplicates [2,3,1,5] and x\\nub x removes the elements of nub x from x, thus keeping the duplicates [3,2]. head returns the first element of hat list.


Point-free is the same byte count: head.((\\)<*>nub).

Laikoni

Posted 2017-07-30T20:19:21.207

Reputation: 23 676

0

Add++, 69 bytes

D,k,@@*,BF€=B]ßEB*MVcGA$p
D,w,@@,BF€=s1<
D,l,@~,$
L~,AÞwB]dVbUG€k»lbU

Try it online!

How it works

Oddly enough, despite Add++ having a deduplicate command, this doesn't use it. This exits with an error code of 1 when there is no duplicated element.

We start by removing any elements without more than one occurrence, in order to leave the stack with an array containing the original array, preserving order, without any elements which only occur once. This is done by the use of filtering by the dyadic function w:

D,w,@@,BF€=s1<
L~,AÞw

Here, the lambda is implicitly called with the argument. The ~ tells it to unpack its argument to the stack beforehand, then the A pushes the argument to the stack. Thesefore, if the input looks like [a b c a c], the stack would look like

[a b c a c [a b c a c]]

We want this structure, called dyad-binding, due to the way the filter-keep quick, Þ, works in regard to non-monadic arguments. Here, its functional argument is w, a dyadic (two argument) function. This means that, instead of filtering over each element in the stack using w, it pops the top element of the stack, the list [a b c a c] in this case, and uses that as the right argument when filtering every other element.

So, for one iteration of w, the stack may look like this at the start of execution:

[[a b c a c] a]

Then BF flattens the stack, and then we come to another dyadic quick: . Again, the popping behaviour is simulated, and a is used as the left argument to the succeeding function, the equality operator in this case. This compares a with the elements of [a b c a c], yielding an array of 1s and 0s. By now, the stack looks something like this

[1 0 0 1 0]

Finally, s takes the sum, and 1< asserts that it is greater than 1. This essentailly counts the occurences of each element of the input in the input itself, and removes them if the count is only 1 i.e. the element isn't duplicated at some point.

After applying Þw to the input, the stack results in

[a c a c]

We'll call this array A. The rest of the code is determining which of these remaining elements occurs for the second time first i.e. the actual task in the challenge.

Next, we want to perform k over the remaining list. In order to do this, with k being dyadic and taking A as its left argument. Again, we want to create the dyad-binding structure, but using the elements of A instead of the arguments. In a general case, if the stack looks like [a b c d e], where a - e are arbitrary pieces of data, the following code will convert that into a dyad-binding structure:

B]dVbUG

So, this makes our stack look like [a c a c [a c a c]], before calling k over ach of the elements, using the array as the left argument.

D,k,@@*,BF€=B]ßEB*MVcGA$p

k is our main function to isolate the first deduplicated element. Here, we have our two arguments, I, the element in the array being iterated over, and A, our array containing the elements that occur more than once. The first part of the code, BF€=, identifies which elements of A are equal to I. Now, we generate the truthy indices - the indices of elements in A that are equal to I. There is a bug in ßE, causing it to start from 0 (corrected after the challenge was posted). However, as this means the first occurence if I will always be set to 0 because of this bug, and the offset of 1 doesn't change between elements, this means that we can avoid the lengthier dbLBc which is bug free. Let's use a as an example value for I. Now, our stack resembles

[[0 1] [1 0] [2 1] [3 0]]

The first element is the 0-based index i, the second whether or not I = A[i]. Next, we remove the indexes where I ≠ A[i], by taking the product of each pair with B*, then taking the maximum value with MVcG. Finally, we push I to the stack and pair them as a list. With I as a, the final value returned is:

[2 a]

This process happens over each element of A, eventually leading to a series of paired lists of the highest index of the element of A in A itself. Finally we want to find the element which has the lowest first element, the element whose duplcicate appears first. Here, as Add++ doesn't have a builtin to get the first or last element of a list, we use our third helper function l:

D,l,@~,$
L~,…»l…

While Add++ doesn't have a builtin for head of an array, it does have a minimum-by quick, ». We take the list which has the minimum return value when passed through the function l. This helper function unpacks its argument to the stack before performing any commands with the ~ command, then $ swaps them, so the index comes first and is the value returned. Essentially, we return the element with the smallest duplicated element.

Unfortunately, this returns the entire array, both the index and the element, rather than just the element, so we append a bU to unpack this array to the stack, returning only the last element of the pair - the first duplicated element.

user80218

Posted 2017-07-30T20:19:21.207

Reputation:

0

C (gcc), 50 bytes

g;main(i){scanf("%d",&i);return i[&g]++?i:main();}

Try it online!

C (gcc), 51 bytes

g;main(i){for(;scanf("%d",&i),i[&g]^=1;);return i;}

Try it online!

C (gcc), 56 bytes

g;main(i){scanf("%d",&i);i[&g]++?printf("%d",i):main();}

Try it online!

l4m2

Posted 2017-07-30T20:19:21.207

Reputation: 5 985