52
\$\begingroup\$

In this question at Code Review they tried to find the fastest way to return the unique element in an array where all the elements are the same except one. But what is the shortest code that accomplish the same thing?

Goal

Find the unique element in an array and return it.

Rules

  • The input array will contain only integer, strictly positive numbers, so you can use 0 as the end of the input if your language needs it.
  • The size of the array will be at least 3 and will have a finite size. You can limit the size of the array to any limit your language has.
  • Every element in the array will be the same, except for one which will be different.
  • You must output the value (not the position) of the unique element in any standard format. You can output leading or trailing spaces or newlines.
  • You can take the input array in any accepted format.

Examples

Input                   Output
------------------------------
[ 1, 1, 1, 2, 1, 1 ]      2
[ 3, 5, 5, 5, 5 ]         3
[ 9, 2, 9, 9, 9, 9, 9 ]   2
[ 4, 4, 4, 6 ]            6
[ 5, 8, 8 ]               5
[ 8, 5, 8 ]               5
[ 8, 8, 5 ]               5

Winner

This is , so may the shortest code for each language win!

\$\endgroup\$
7
  • \$\begingroup\$ Do we assume the input array contains a unique element and others are the same? \$\endgroup\$
    – Amessihel
    Commented Jul 28, 2020 at 14:52
  • \$\begingroup\$ @Amessihel yes, you don't need to check that, it is assumed. \$\endgroup\$
    – Charlie
    Commented Jul 28, 2020 at 14:54
  • 8
    \$\begingroup\$ The title feels too long for such a simple operation. Suggested: Odd one out \$\endgroup\$
    – Luis Mendo
    Commented Jul 28, 2020 at 15:05
  • 7
    \$\begingroup\$ @LuisMendo nice title, the thing is that I just wanted to use the same title as the original question at Code Review but changing "fastest" with "shortest". :-) \$\endgroup\$
    – Charlie
    Commented Jul 28, 2020 at 15:08
  • 1
    \$\begingroup\$ Suggest adding testcases [8, 8, 5] and [5, 8, 8] since there isn't one were the last element is unique and 3 element arrays are a corner cases in themselves. \$\endgroup\$
    – Noodle9
    Commented Jul 28, 2020 at 19:19

92 Answers 92

2
\$\begingroup\$

JavaScript (61 60 bytes)

My first attempt in this community, so there's room for improvement:
x=>{[a,b,c]=x.filter((e,i)=>x[i-1]!=e);return !c&&x[1]-a?a:b}

x=>{[a,b,c]=x.filter((e,i)=>x[i-1]!=e);return!c&&x[1]-a?a:b}

Try it online!

Explanation:

x.filter((e,i)=>x[i-1]!=e)

The array is filtered to remove any element that is the same as array[index - 1]. These are then unpacked into variables [a,b,c].
The three scenarios are 1) [same, unique, same] 2) [unique, same] 3) [same, unique]

return !c&&x[1]-a?a:b

If c is undefined, i.e. the unique element was on the end of the array - and if 'a' (which is by now either array[0] or array[last element - 1]) is not equal to array[1], then a is the unique element. Otherwise, we have scenario 1 or 3, either way - return 'b'

\$\endgroup\$
3
  • \$\begingroup\$ Welcome to the wonderful world of code golf! I look forward to seeing more of your posts! \$\endgroup\$
    – lyxal
    Commented Aug 13, 2020 at 23:56
  • \$\begingroup\$ Also, -1 byte by removing the space between return and ! \$\endgroup\$
    – lyxal
    Commented Aug 13, 2020 at 23:57
  • \$\begingroup\$ Thanks, not sure how I missed that whitespace lol. \$\endgroup\$
    – Scott
    Commented Aug 15, 2020 at 1:22
2
\$\begingroup\$

jq, 11 bytes

.-[sort[1]]

Try it online!

Explanation

.           # The input
 -          # With all occurances of ... removed:
  [sort     #    The sorted input
       [1]] #    's second item
\$\endgroup\$
2
  • \$\begingroup\$ For input [9, 6, 6] it fails to return 9. \$\endgroup\$
    – Charlie
    Commented Jan 1, 2021 at 10:07
  • 1
    \$\begingroup\$ @Charlie I hope it is fixed now. \$\endgroup\$
    – user99151
    Commented Jan 1, 2021 at 12:36
2
\$\begingroup\$

Wolfram Language (Mathematica) 17 29 28 bytes

Code corrected due to comment by @att:

SortBy[Tally[#],Last][[1,1]]&

theorist managed to shave off one byte with this:

Cases[Tally@#,{_,1}][[1,1]]&
\$\endgroup\$
3
  • 3
    \$\begingroup\$ Fails when the unique element is the first element. \$\endgroup\$
    – att
    Commented Jul 28, 2020 at 19:22
  • \$\begingroup\$ Yes, Good catch! (I corrected the code.) \$\endgroup\$
    – DavidC
    Commented Jul 29, 2020 at 15:04
  • \$\begingroup\$ Also (saves 1 byte): Cases[Tally@#,{_,1}][[1,1]]& \$\endgroup\$
    – theorist
    Commented Jun 20, 2021 at 21:55
2
\$\begingroup\$

Factor, 28 23 bytes

[ histogram keys last ]

Try it online!

Get the last (second) key in the histogram of the input, which will always have the smaller count.

\$\endgroup\$
2
\$\begingroup\$

Raku, 25 bytes

{.BagHash.invert.Hash{1}}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Scala, 85 bytes

Try it online!

def f(x:Seq[Int])=x.groupBy(identity).mapValues(_.length).filter(_._2 == 1).keys.head

This Scala code defines a function f that takes a sequence of integers x as input, and returns the unique element in the sequence.

Here's a breakdown of what the function does:

  • x.groupBy(identity) groups the elements in the sequence x by their identity (i.e., their value), returning a map where the keys are the distinct values in x, and the values are arrays of elements in x with that value.
  • .mapValues(_.length) transforms the values in the map to their length, i.e., the number of elements in x with that value.
  • .filter(_._2 == 1) filters the key-value pairs in the map to keep only those where the value (i.e., the count of elements with that value in x) is equal to 1.
  • .keys returns the keys (i.e., the distinct values in x) of the filtered map as a set.
  • .head returns the first (and only) element of the set, which is the unique element in x.

So the entire function finds the unique element in x by grouping its elements by their value, counting the elements with each value, filtering for the value with count 1, and returning it.

\$\endgroup\$
2
\$\begingroup\$

Vyxal 3, 4 bytes

SġⁿL

Try it Online!

Sorts the array, groups by adjacent items and takes the minimum by length

\$\endgroup\$
2
\$\begingroup\$

TI-BASIC, 10 9 bytes

min(Ans)max(Ans)/median(Ans

Takes input in Ans.

\$\endgroup\$
2
\$\begingroup\$

Perl 5 -p, 30 bytes

s/\d+//;$_=s/\b$&\b//g?$_+0:$&

Try it online!

Perl 5 -a, 31 bytes

//,(1-grep$_==$',@F)||say for@F

Try it online!

Perl 5 -a, 33 bytes

1-(@b="@F"=~/\b$_\b/g)||say for@F

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Note that in the input every element must be the same except one, so [1 2 3 4 4 3 1 1] would not be a valid input. \$\endgroup\$
    – Charlie
    Commented Jul 28, 2020 at 14:26
  • \$\begingroup\$ Changed my test case, but it doesn't really matter to the code. It finds the unique element either way. \$\endgroup\$
    – Xcali
    Commented Jul 28, 2020 at 14:34
2
\$\begingroup\$

HBL, 10.5 bytes

+(1.)('1.)(<(1.2
)(%.

Try it!

Port of Arnauld's answer.

-3 bytes thanks to @DLosc!

Explanation:

Helper function:

+(1.)('1.)(<(1.2­⁡​‎‎⁡⁠⁡‏⁠⁠⁠‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁢‏⁠‎⁡⁠⁣‏⁠‎⁡⁠⁤‏⁠‎⁡⁠⁢⁡‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁢⁢‏⁠‎⁡⁠⁢⁣‏⁠‎⁡⁠⁢⁤‏⁠‎⁡⁠⁣⁡‏⁠‎⁡⁠⁣⁢‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁣⁣‏⁠‎⁡⁠⁣⁤‏‏​⁡⁠⁡‌⁢⁡​‎⁠⁠‎⁡⁠⁤⁡‏⁠‎⁡⁠⁤⁢‏⁠‎⁡⁠⁤⁣‏⁠‎⁡⁠⁤⁤‏‏​⁡⁠⁡‌­
+                 # ‎⁡Add:
 (1.)             # ‎⁢The first element of arg1
     ('1.)        # ‎⁣The last element of arg1
          (<      # ‎⁤Negate below:
            (1.2  # ‎⁢⁡The second element of arg1

Main function:

)(%.­⁡​‎‎⁡⁠⁢‏⁠‎⁡⁠⁣‏⁠‎⁡⁠⁤‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁡‏‏​⁡⁠⁡‌­
 (%.  # ‎⁡Sort arg1
)     # ‎⁢Call the function above
💎

Created with the help of Luminespire.

\$\endgroup\$
1
  • \$\begingroup\$ @DLosc Thanks! Also, I've added the explanation. \$\endgroup\$
    – Fmbalbuena
    Commented Feb 29 at 23:21
1
\$\begingroup\$

Japt -m, 4 bytes

ü l1

Try it

ü       sort and group
  l1    take lenght 1 result
\$\endgroup\$
1
\$\begingroup\$

Retina, 24 bytes

N`
L0`^(\d+)(?!¶\1)|\d+$

Try it online!

This works by sorting the input (one number per line) and then outputting the first number if it is different from the second, and otherwise outputting the last number.

The test case code was taken from Neil's Retina answer which uses an arithmetic method to determine the answer after sorting.

\$\endgroup\$
1
  • \$\begingroup\$ You inspired me to write an answer which could be backported to Retina 0.8.2, and was shorter to boot! \$\endgroup\$
    – Neil
    Commented Jul 29, 2020 at 1:51
1
\$\begingroup\$

Google Sheets, 28

Closing parens already discounted.

  • Column A is input.
  • B1 - =SORT(A:A)
  • B2 - =FILTER(B:B,B:B<>B2)

Excel 2016, 35

  • Column A is input.
  • B1 - =MAX(A:A)
  • B2 - =IF(MODE(A:A)-B1,B1,MIN(A:A))

If the mode is the same as the max, then it's the min, otherwise max.

\$\endgroup\$
1
\$\begingroup\$

Burlesque, 8 bytes

psf:<][~

Try it online!

Explanation:

ps       # Parse input string as a block
  f:     # Frequency list - returns block of blocks with format {frequency value}
    <]   # Take the minimum block, in this case calculated based on the first element (frequency)
      [~ # Take the last element (value)
         # Implicitly output
\$\endgroup\$
1
\$\begingroup\$

C# 42 Bytes

r.GroupBy(a=>a).First(a=>a.Count()==1).Key
\$\endgroup\$
3
  • \$\begingroup\$ Welcome to the site. Are you sure C# requires all that whitespace? If it doesn't, removing it could be a easy way to shorten this. \$\endgroup\$
    – Wheat Wizard
    Commented Jul 30, 2020 at 2:36
  • \$\begingroup\$ @AdHocGarfHunter Thanks! You're right. Have edited it further \$\endgroup\$
    – primmslim
    Commented Jul 30, 2020 at 2:56
  • 1
    \$\begingroup\$ Also if I understand the code correctly groups can't be size zero? So <2 should be a shorter way of checking ==1. If you want tips for golfing in C# from someone who actually knows C# we have a tips page for the language. \$\endgroup\$
    – Wheat Wizard
    Commented Jul 30, 2020 at 3:00
1
\$\begingroup\$

Pyth - 6 bytes

I'm not quite sure why this doesn't return an array.

f!t/QT

Explanation

f!t/QT
f!t/QTQ implicit Q added
f     Q filter on each element T of input for 
   /QT  number of times t appears in input
  t     minus 1
 !      is equal to zero
\$\endgroup\$
1
  • \$\begingroup\$ Made me chuckle a bit. \$\endgroup\$
    – Razetime
    Commented Aug 3, 2020 at 14:28
1
\$\begingroup\$

Postgresql, 51 bytes

SELECT unnest($1::int[])GROUP BY 1HAVING count(*)=1

Takes input as an integer array. Outputs as a row containing the unique value. If there is more than one unique value, it returns all of them in unspecified order.

If the type is specified in the extended query protocol or a function parameter, it can be reduced to 44 bytes

SELECT $1.unnest GROUP BY 1HAVING count(*)=1
\$\endgroup\$
1
\$\begingroup\$

[Python 3], 39 bytes

lambda x:x[[*map(x.count, x)].index(1)]
\$\endgroup\$
3
  • \$\begingroup\$ Guessing by the header, it looks like you copied the post from TIO then removed the link. I suggest to fix the post by copying the whole content back. \$\endgroup\$
    – Bubbler
    Commented Aug 5, 2020 at 7:10
  • \$\begingroup\$ I had taken the format from codegolf.stackexchange.com/a/207741/97553 but it is different from my code. \$\endgroup\$ Commented Aug 10, 2020 at 11:26
  • \$\begingroup\$ Well yes, as Bubbler said you deleted the link and didn't replace it with anything can you at least fix the header and optionally add a link to somewhere you can test this, such as TIO? \$\endgroup\$
    – Jo King
    Commented Aug 15, 2020 at 2:16
1
\$\begingroup\$

GolfScript, 6 bytes

~$.1=-

Try it online!

~        # Parse the input to an array
 $       # Sort the array
  .1=    # Get the second number in the array, this will always be the repeated number
     -   # Remove all copies of the repeated number
\$\endgroup\$
1
\$\begingroup\$

Scala, 28 27 bytes

a=>a.minBy(x=>a.count(x==))

It finds the minimum number in the list according to the number of occurrences in that same list, since the odd one out will only have 1 occurrence.

Try it in Scastie

\$\endgroup\$
1
\$\begingroup\$

Pyt, 3 bytes

ĐṀ\

Try it online!

Đ        implicit input (S); duplicate on top of stack
 Ṁ       get median (m) (I never got around to fixing a bug in the mode operator, but they do the same thing here)
  \      take the set difference between S and m; implicit print
\$\endgroup\$
1
\$\begingroup\$

Arturo, 33 bytes

$=>[t:tally&|select[k,v]->v=1t\0]

Try it

\$\endgroup\$
1
\$\begingroup\$

><> (Fish), 29 bytes

!!vr:r@:&=&$?$n;
 ~>:@$:@=0$.

Try it

\$\endgroup\$
1
\$\begingroup\$

Go, 105 bytes

func(N[]int)int{m,o:=make(map[int]int),0
for _,n:=range N{m[n]++}
for k,v:=range m{if v<2{o=k}}
return o}

Attempt This Online!

\$\endgroup\$
1
\$\begingroup\$

Java (JDK), 65 bytes

Not the best Java answer, but still really close using a Stream approach.

l->l.stream().reduce(0,(a,b)->l.indexOf(b)!=l.lastIndexOf(b)?a:b)

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Labyrinth, 34 bytes

? }:=
? $ :
: } {
} : +;=$!@
${?"=

Try it online!

Examines windows of size 3 until a window with two different numbers is found, and then XORs the three numbers to get the answer.

Given a window of a b c, the test is done by checking if (a^b) + (b^c) is nonzero. It is trivially zero if a == b == c, and we can be sure that it is strictly positive (and therefore nonzero) when a != b (i.e. (a^b) != 0) or b != c (i.e. (b^c) != 0) since all the input values are positive.

Also, a redundant work is saved by keeping an XORed value in the stack across iterations.

Intro:  ??:}${
??   take two numbers from input [a b]
:}   copy 2nd input to aux.stack [a b | b]
$    XOR                         [a^b | b]
{    pull 2nd input back         [a^b b]

Loop:  ?:}$}:=:{+=   [a^b b] -> [b^c c]
?      take next number from input [a^b b c]
:}     backup c                    [a^b b c | c]
$      XOR                         [a^b b^c | c]
}:     move b^c and copy a^b       [a^b a^b | b^c c]
=:{    swap tops, copy, pull       [a^b b^c b^c a^b | c]
+      add; keep going if zero     [a^b b^c a^b+b^c | c]
=      swap tops                   [... b^c c | ...]

End:  ;=$!@  [a^b b^c a^b+b^c | c]
;=    drop and swap tops   [a^b c | ...]
$!@   print a^b^c and halt
\$\endgroup\$
1
\$\begingroup\$

Kotlin, 40 24 bytes

{minBy{r->count{r==it}}}

Try it online!

It doesn't seem to have a count function where you can simply pass the lambda parameter.

-16 bytes thanks to Seggan

\$\endgroup\$
1
  • 1
    \$\begingroup\$ you can omit the IntArray part as lambdas on CGCC can have types inderred if needed \$\endgroup\$
    – Seggan
    Commented Feb 29 at 20:19
1
\$\begingroup\$

Scala 3, 28 bytes

l=>l.minBy(x=>l.count(_==x))

Attempt This Online!

\$\endgroup\$
1
\$\begingroup\$

YASEPL, 46 32 30 bytes

=a=1'±" "=d¥0,1`1!+=e¥a,1}3,d<

enter in numbers seperated by a space and nothing else (like 4 4 4 6 4 4)

explanation

=a=1'±" "=d¥0,1`1!+=e¥a,1}3,d<           packed
=a                                       declare increment variable "a"
  =1'                                    get user input and set it to "1"
     ±" "                                split "1" by every space
         =d¥0,1                          get the first item from "1"
               `1        }3,d            while e == d...
                 !+                      increment a by one
                   =e¥a,1                get item at "1" index "a" and set it to "e"
                             <           print variable "e" when finished
\$\endgroup\$
0
\$\begingroup\$

SmileBASIC 4, 43 bytes

1  RSORT I:IF I[0]-I[1]GOTO@0
2  ?MIN(I)@0?MAX(I)

Receives array input through I[]. The first value printed is the answer, other printed values are to be ignored. Works by reverse-sorting the list of integers (from largest to smallest values) and comparing the zeroth and first elements. If their difference is non-zero, then the odd one out is the larger value (MAX(I)); otherwise, the odd one out is the smaller value (MIN(I)).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.