# Find the highest unique digit

Surprisingly we haven't had a simple "find the highest digit" challenge yet, but I think that's a little too trivial.

Given input of a non-negative integer, return the highest unique (ie not repeated) digit found in the integer. If there are no unique digits, your program can do anything (undefined behaviour), other than the numbers that are non unique in the input of course.

The input can be taken as a single integer, a string, or a list of digits.

## Test cases

12         -> 2
0          -> 0
485902     -> 9
495902     -> 5
999999     -> Anything
999099     -> 0
1948710498 -> 7


This is so fewest bytes in each language wins!

• Can we take input as a string instead? Jun 28, 2017 at 8:13
• Given the last test case, I think we are forced to take input as a string... (leading zeroes can't be represented in integers)
– Leo
Jun 28, 2017 at 8:14
• @Leo that was my bad actually, basically mashed the numbers on my keyboard, didn't notice the leading zero. But yes, input can be taken as a string Jun 28, 2017 at 8:17
• @Adám "undefined behaviour" generally means you can do anything, including summoning nameless horrors from the void if that saves bytes. Jun 28, 2017 at 8:22
• @MartinEnder in fact I'll happily knock off 50% of your bytes if your code successfully summons cthulhu upon there being no unique digits ;) Jun 28, 2017 at 8:31

# Pyth, 6 bytes

eS.m/Q


Test suite

Explanation:

eS.m/Q
eS.m/QbQ    Implicit variable introduction
.m   Q    Find all minimal elements of the input by the following function:
/Qb     Number of appearances in the input
eS          Take the maximum element remaining.


for$x(split//,<>){$d[$x]++};for($x=11;--$d[--$x];){}print$x  Try it online! • Shortened to 40 bytes: Try it online!. (you can look up -F flag on perlrun if needed) – Dada Jul 27, 2017 at 11:51 # Pyth, 87 6 bytes 1 byte thanks to isaacg. 1 byte thanks to FryAmTheEggman. e{I#.g  # Octave, 31 bytes @(a)find(hist(a,0:9)==1)(end)-1  Try it online! # Python 2, 41 bytes lambda s:max(s,key=lambda o:s.count(o)<2)  Accepts input as string or list of strings # Pyth -- 8 bytes eSf!t/QT  And also eS-Q.-Q{  Explanation: eSf!t/QT # Takes string f # Filter characters T of implicit input /QT # by counting occurrences of that character in the input !t # keeping only characters that occur once (i.e., !(# occurrences - 1) S # Sort (puts them in ascending order e # Take the last (highest)  And eS-Q.-Q{ # Takes list of digits { # Deduplicate the list .-Q # Take the original list, and remove each element in the deduplicated list once (so only duplicated digits are left) -Q # Remove these duplicated digits from the list eS # As before, sort and take the last element  # Perl 6, 33 25 bytes {max keys .comb∖.comb.repeated}  input is either an Int or Str. Test it {max keys$_∖.repeated}


input is a list of digits.

Test it

## Expanded:

{ # bare block lambda with implicit parameter ｢$_｣ max # the maximum from keys # the keys (digits) out of the following Set$_             # the Input list of digits
∖                # Set minus (not ｢\｣)
.repeated      # the repeated digits (implicit method call on ｢$_｣) }  # APL (Dyalog), 11 bytes ⌈/{⍺×2-≢⍵}⌸  Try it online! # Java, 70 bytes Input is taken as a List of digits, as per question parameters. n->n.stream().reduce(0,(p,q)->p>q||n.indexOf(q)!=n.lastIndexOf(q)?p:q)  The power of Streams in the palm of your hand! The secret here is the beautiful reduce function. Starting with a 0, we walk through our list of digits and perform a retaining algorithm, keeping the one we've got (?p:q) if it's bigger than the new one (p>q) or if the new one isn't unique (n.indexOf(q)!=n.lastIndexOf(q)) • You can save a byte by changing || to |. Nov 13, 2017 at 15:23 # Ruby, 42 bytes Same byte count as the other Ruby answer, but different approach. ->x{x.chars.group_by{|d|x.count d}[1].max}  Crashes when there are no unique digits. Try it online! # CJam, 13 bytes 9A,sqfe=W%X#-  Try it Online 9 e# Push 9 to stack A,s e# Push "0123456789" to stack q e# Push input to stack ("1948710498") fe= e# Create array containing number of occurences of each digit in input number ([1,2,0,0,2,0,0,1,2,2]) W% e# Reverse that array ([2,2,1,0,0,2,0,0,2,1]) X# e# Get index of 1 in that array (2) - e# Calculate 9 - returned index to get highest unique digit (7)  # C# (Visual C# Interactive Compiler), 38 bytes n=>n.Max(x=>n.Count(a=>a==x)<2?x:0)-48  Try it online! # J, 16 12 bytes 0{\:~-.}./.~  Try it online! • This is really nice, and since "The input can be taken as a single integer, a string, or a list of digits." you can actually do 0{\:~-.}./.~ for 12: Try it online! Jun 2, 2019 at 1:29 # Julia 1.0, 41 bytes s->maximum(c for c=s if count(==(c),s)<2)  Try it online! # Wolfram Language (Mathematica), 4329 28 bytes Max@*Cases[{d_,1}->d]@*Tally  Try it online! • Removed 14 bytes by skipping IntegerDigits: according to the comments, the function can be given a list of digits instead of a number. Jun 5, 2019 at 10:27 • Removed 1 byte by using the operator form of Cases. Jun 8, 2019 at 12:34 # Husk, 8 bytes ▲fȯ¬←LgO  Try it online! Input is list of digits. ▲fȯ¬←LgO ▲ # maximum value of f # filter list to retain only truthy values gO # list: sort digits and group equal values together ȯ # filter condition: combine functions: ←L # length minus one (so length 1 = FALSE) ¬ # NOT (so length 1 = TRUE)  • 5 bytes I think Nov 5, 2020 at 3:55 • 3 bytes but this one's very different Nov 5, 2020 at 3:57 • @Razetime - That's much, much, better than mine! Post it! Nov 5, 2020 at 7:09 # Vyxal, 7 bytes '?$Oṅ;G


Try it Online!

Takes input as a string.

### Explained

'?$Oṅ;G ' ; # From the input, keep only items where: ?$O    #   The count of the item in the input
ṅ   #   Is <= 1
G # Get the biggest digit from the remaining items.

• Try it Online! for 8 Oct 12 at 6:53
• @lyxal Erm if you want, you're welcome to edit my answer to add in the explanation! :3 Oct 12 at 6:54
• Try it Online! for 7 Oct 12 at 6:56
• Try it Online for 6 using G flag. Oct 12 at 13:10
• @Pacmanboss256 That can be 5 removing the trailing ;. Oct 12 at 17:28

## Clojure, 52 bytes

#(last(sort(for[c % :when(=((frequencies %)c)1)]c)))


Input is a string, returns a char, or nil if all digits are repeated.

╗1╤rR⌠$╜c⌡M1@í9-  Try it online! # C (gcc), 76 bytes d[58],i;main(){while((i=getchar())>0)++d[i];for(i=58;--d[--i];);putchar(i);}  Try it online! • Suggest d[58];main(i) instead of d[58],i;main(). Also, suggest (~(i=getchar())) instead of ((i=getchar())>0) Aug 21, 2018 at 1:02 # PHP, 79 76 bytes Try it online! foreach(array_count_values(str_split($n))as$x=>$i){$h=($i==1&&$x>$h)?$x:$h;}


Use with $n = 495902; it will print 5. # PowerShell v3+, 58 bytes $i|% ToCharA*|sort|group|? count -lt 2|select -l 1 -exp N*


Assumes $i contains a string of digits. Try it online! # F#, 67 bytes let f s=Seq.countBy id s|>Seq.filter(snd>>(=)1)|>Seq.maxBy fst|>fst  Try it online! # Kotlin, 53 Bytes val f={a:String->a.filter{a.count{b->it==b}<2}.max()}  Declares a lambda, f that takes in a string; same algorithm as the python answer. it is the implicit iterator of a.filter, and b is the explicitly declared iterator of a.count (because we can't use it again). Try it online! # Pip, 11 bytes MX:_Na=1FIa  Takes input as a command-line argument. Try it online! ### Explanation  a 1st cmdline arg FI Filter digits by this function: _Na Count of digit in a =1 equals 1 (i.e. keep only digits that appear exactly once) MX: Max of resulting list (using : to lower precedence) Autoprint (implicit)  ## CJam, 15 bytes r$e{0=1=},e~W=


Explanation:

r    e# Read token:          "2515"
7

bash-4.4$jq -Rr '[./""|group_by(.)[]|select(length<2)[]]|max' <<< 999999 null  Try on jq‣play # Braingolf, 15 bytes k&gG{!L1-?$_|}X


Try it online!

Takes input as a list of digits

## Explanation

k&gG{!L1-?$_|}X Implicit input from commandline args k Sort in descending numerical order &g Combine into single integer G Split into digit runs {........} Foreach loop.. !L1-? ..If length of item is greater than 1..$_     ....Remove item
|    ..Endif
X  Select highest value
Implicit output


To help visualize it a little, here's a run through showing the stack with input 122355567679

k&gG{!L1-?$_|}X [1,2,2,3,5,5,5,6,7,6,7,9] k [9,7,7,6,6,5,5,5,3,2,2,1] &g [977665553221] G [9,77,66,555,3,22,1] {!L1-?$_|}   [9,3,1]
X  [9]


# x86 Machine Code (32-bit, requires built-in FPU), 35 bytes

C8 10 00 00 D9 EE DD 14 24 DD 5C 24 08 8B 01 FE 04 04
83 C1 04 4A 75 F5 6A 0A 58 48 FE 0C 04 75 FA C9 C3


The above code defines a function in 32-bit x86 machine code that finds the unique highest digit in an array of integer values. (The question says we can take the input as a "list of digits", and assembly language is like C in that it lacks a built-in list/array type, but rather represents them as a pointer and length. Therefore, the function is prototyped in C as follows:

int __fastcall FindHighestUniqueDigit(const int * ptrDigits, int count);


As the prototype suggests, this function is written to follow Microsoft's fastcall calling convention, which passes arguments in registers. The first parameter (ptrDigits) is passed in ECX, and the second argument (count) is passed in EDX. The return value is, as always, returned in EAX.

Try it online!

Here are the ungolfed assembly mnemonics:

FindHighestUniqueDigit:
enter  16, 0                  ; reserve 16 bytes of space on the stack for a table
fldz                          ; load 0 in the first x87 FPU register (st0)
fst    QWORD PTR [esp+0]      ; store value in st0 on the stack, at offset 0
fstp   QWORD PTR [esp+8]      ; store value in st0 on the stack, at offset 0, and pop st0
mov    eax, DWORD PTR [ecx]   ; read next digit from array
add    ecx, 4                 ; increment pointer to reference next digit (ints are 4-bytes long)
inc    BYTE PTR [esp + eax]   ; increment value in table for this digit
dec    edx                    ; decrement counter (length of array)
jne    ReadDigits             ; keep looping as long as there are more digits to read
push   10
pop    eax                    ; space-efficient way to put '10' in EAX so we start with highest digit
ProcessDigits:
dec    eax                    ; decrement EAX
dec    BYTE PTR [esp + eax]   ; decrement value in table for this digit
jnz    ProcessDigits          ; if that table value is now zero, we found a match; otherwise, keep looping
leave                         ; undo effects of ENTER instruction
ret                           ; return, with result in EAX (digit ID)


I suppose the code requires a bit of explanation…

Basically, what we do is create a table in memory, with enough space to store a unique count for each of the 9 possible digits (0 through 9).

| esp+0 | esp+1 | esp+2 | esp+3 | esp+4 | esp+5 | esp+6 | esp+7 | esp+8 | esp+9 | unused |
|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|--------|
|   9   |   8   |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |   ??   |


The first ENTER instruction is responsible for allocating this space on the stack. We allocate 16 bytes because it's good practice to keep this a power of 2 for alignment purposes, 8 bytes isn't enough, and it doesn't hurt or cost anymore code bytes to allocate more than we need. The next three instructions are responsible for zeroing out all entries in this array. It's basically equivalent to memset in C, but shorter. We could have used the x86's REP STOSD string instruction, but that requires some setup (getting the right values in the right registers), and it turned out that (ab)using the x87 FPU to do 8-byte stores was shorter (required fewer bytes of code). All we do is load 0 at the top of the x87 FPU stack, which is pseudo-register st0. Then, we store that value across the first 8 bytes of the table, and finally, we store that value across the next 8 bytes of the table, popping it off of the x87 FPU stack at the same time.

The next section of the code is ReadDigits. This just iterates through the array of digits that we were passed, one digit at a time, and increments the unique counter for that digit in our table. You should be able to figure out exactly how this works by reading the comments for each of the instructions.

Finally, we come to the final phase, ProcessDigits. Actually, the PUSH+POP instructions right above this label are conceptually part of this phase, too. They just initialize EAX with 10 so that we'll start processing the table values for the highest possible digit, 9. Inside of the ProcessDigits loop, we eagerly decrement EAX, and then decrement the value in the table for the corresponding digit. If the resulting table value/counter is 0, then we've found our match, and we exit the loop. Otherwise, we keep looping and trying smaller digits. (Note that we could have done a comparison here—e.g., cmp BYTE PTR [esp + eax], 1+jnz—and in fact that's what we're logically doing, but the decrement was shorter to encode.)

Notice that if we never find a matching digit, then the code exhibits undefined behavior: it just keeps looping through memory, decrementing values and waiting until one is non-zero. When it finally finds one, it will terminate and return the ID, but the ID will be meaningless, and more importantly, it will have stomped all over the stack, decrementing values aimlessly!

The very last two instructions just clean up the stack (LEAVE) and return, with the return value (the highest unique digit that we found) left in EAX.

# k, 12 bytes

|/@&:1=#:'=:


Example:

k)F:|/@&:1=#:'=:
k)F "1948710498"
"7"
k)F "99999"
"\000"
k)F "mississippi"
"m"


The translation to q as explanation

max where 1 = count each group@


Interpreter available here

• I think this can be simplified to |/&1=#:'=: (provided it's run as k4 code). Nov 4, 2020 at 21:40