| Bytes | Lang | Time | Link |
|---|---|---|---|
| 019 | ARBLE | 240905T004250Z | ATaco |
| 033 | F# .NET Core | 240904T222022Z | dtanku |
| 003 | Pyth | 240820T085825Z | adrianus |
| 035 | AWK | 240808T211310Z | wobtax |
| 033 | JavaScript Node.js | 240812T093345Z | l4m2 |
| 002 | 05AB1E | 240812T074834Z | Kevin Cr |
| 005 | J | 240805T023006Z | south |
| 003 | Stack control | 240803T205004Z | Швеев Ал |
| 014 | K ngn/k | 240804T212950Z | Fmbalbue |
| 022 | R | 240801T160236Z | Giuseppe |
| 015 | Ruby | 240731T180311Z | int 21h |
| 026 | Desmos | 240801T020454Z | Aiden Ch |
| 019 | Kotlin 2.0.0 | 240731T143136Z | colmmurp |
| 022 | Perl 5 + 0513pF | 240728T204448Z | Dom Hast |
| 015 | Perl 5 MListUtil=uniq pF | 240729T152917Z | Xcali |
| 035 | Java 21 | 240729T143539Z | David Co |
| 021 | R 4.4.0 | 240729T090246Z | SamR |
| 065 | Setanta | 240728T205010Z | bb94 |
| 038 | JavaScript Node.js | 240728T104100Z | Andrew B |
| 001 | Japt v2.0a0 h | 240728T183907Z | Shaggy |
| 022 | Excel ms365 | 240728T181455Z | JvdV |
| 003 | MATL | 240728T173544Z | Suever |
| 002 | Brachylog | 240728T154156Z | Unrelate |
| 002 | Jelly | 240728T154153Z | Jonathan |
| 036 | Google Sheets | 240728T102209Z | doubleun |
| 008 | Charcoal | 240728T135554Z | Neil |
| 005 | Haskell + hgl | 240728T134833Z | Wheat Wi |
| 008 | Retina 0.8.2 | 240728T134116Z | Neil |
| 004 | K ngn/k | 240728T133436Z | akamayu |
| 027 | PowerShell | 240728T121823Z | user3141 |
| 036 | Python 3 | 240728T115156Z | matteo_c |
| 015 | Arturo | 240728T112337Z | chunes |
| 003 | Uiua SBCS | 240728T105800Z | chunes |
| 026 | Python | 240728T102653Z | xnor |
| 024 | JavaScript ES6 | 240728T101535Z | Arnauld |
| 057 | C tcc | 240728T101650Z | ovs |
| 002 | Vyxal 3 | 240728T101335Z | RubenVer |
| 002 | APL Dyalog Vision | 240728T095611Z | Adá |
| 002 | Vyxal | 240728T095024Z | emanresu |
ARBLE, 19 bytes
index(-unique(l),1)
Per the challenge spec, takes a list of non-negative integers.
For 28 bytes, can take a string instead
index(-unique(split(s,1)),1)
F# (.NET Core), 33 bytes
let f s=s|>Seq.distinct|>Seq.last
Shame the lambda solution is the same length, would have been an easy golf.
AWK, 39 35 bytes
awk -F '' '{for(;i++<NF;)s[$i]++?z:l=$i;$0=l}1'
Explanation:
-F ''makes each character into its own field.for(;i++<NF;): Iterate down the fields.s[$1]++?z:: If the current field has been seen before, do nothing.l=$iOtherwise, setlto the current field.
$0=l: Set$0to the current value ofl.1: Print$0, i.e., printl.
Thanks to @Marius_Couet for shaving off several bytes.
05AB1E, 2 bytes
Ùθ
Explanation:
Ù # Uniquify the characters of the (implicit) input-string
θ # Pop and keep the last unique character
# (which is output implicitly as result)
Stack control, 3 characters:
∪⟄⟸
Explanation:
∪ - union (removes all duplicates)
⟄ - pop last element from array
⟸ - hard shift (removes original array)
K (ngn/k), 14 bytes
{x@|/x?!1+|/x}
Explanation
{x@|/x?!1+|/x}
{ } function
!1+ enumerate from 0 to
|/x the max element of the list
x? find every element index
|/ pick the newest element index
x@ index
R, 22 bytes
\(x)x[max(match(x,x))]
A 1 byte longer solution than SamR's, but not implementation-dependent.
Ruby, 15 bytes
This version works with a list (conform to the rules):
->a{a.uniq[-1]}
Ruby, 25 bytes
And this 25-bytes anonymous function takes a string as its input, splits in characters and outputs the last unique element:
->a{a.split('').uniq[-1]}
Kotlin 2.0.0, 26 19 Bytes
{LinkedHashSet(it).last()}
A trivial port of David Conrad's Java solution. Expects a List<Char> and outputs a Char
{it.toSet().last()}
Saves 7 Bytes by using a Set instead of a LinkedHashSet. Sequence.toSet() preserves the original iteration order according to the docs
Java 21, 35 bytes
s->new LinkedHashSet<>().getLast()
A Function<List<T>, T> for some T. Requires Java 21 which does not seem to be available yet on Try It Online or Attempt This Online.
R 4.4.0, 21 bytes
\(x)tail(unique(x),1)
Takes as input a vector of utf-8 code points. Really not fancy, basically just a port of Arnauld's JS answer (and several others as well).
Although R's base::unique() is not documented to guarantee insertion order, the implementation will do so. It loops through every value of a vector in order and checks if it has been seen before, appending to a new vector any which have not been. While I suppose it's possible this implementation will not remain forever, it will work in R 4.4.0. Also, the git blame indicates this has been part of the R source for 26 years - I don't imagine it would be changed lightly in future versions.
Setanta, 65 bytes
gniomh(s){le i idir(fad@s-1,-1)ma i<=aimsigh@s(s[i]) toradh s[i]}
MATL, 3 bytes
uJ)
Explanation
% Implicitly fetch input
u % Find unique elements
J) % Get the last element
% Print implicitly
Jelly, 2 bytes
QṪ
A monadic Link that accepts a list and yields the newest element.
How?
QṪ - Link: list, A
Q - deduplicate {A}
Ṫ - tail {that}
Google Sheets, 36 bytes
=chooserows(unique(tocol(A:A,1)),-1)
64 bytes:
=+let(β,A:A,γ,sort(row(β)),sort(β,1=countifs(β,β,γ,"<="&γ),,γ,))
...or:
=chooserows(filter(A:A,1=map(A:A,lambda(β,countif(A1:β,β)))),-1)
Put the array in column A1:A and the formula in cell B1.

Charcoal, 8 bytes
§θ⌈Eθ⌕θι
Try it online! Link is to verbose version of code. Explanation: Turned out to be a port of @xnor's answer.
θ Input string
E Map over characters
⌕ Index of
ι Current character
θ In input string
⌈ Take the maximum
§ Index into
θ Input string
Implicitly print
Haskell + hgl, 5 bytes
gj<nb
Explanation
Nub and get the last element.
Parser, 16 bytes
gk$(h'>~nxy)<*h'
Since this challenge is pretty trivial to do using the normal library, I thought I'd try a parser only version.
Explanation
We create a parser which matches all characters that are not preceded by a copy of themselves.
h': Get some prefix.nxy: Parse a character not present in the prefix.h': Parse some number of characters.gk: Get the highest priority parse.
The priority here is determined by h' with the longest parse having the highest priority.
Reflection
The normal version of this can't reasonably be improved. Improvements can be made based on the parser version, but it will never be on par with the other version for this task.
gkgets the first complete parse. There should be a parser consumer which just gets the first parse. This would make the<*h'unnecessary and save a bunch of bytes here.(h'*>)and(<*h')could probably use shortcuts. I use the former here. This would be superseded here by the above improvement, but would probably be useful in the long term.- I use
(h'>~)here and here and the very similar(h_>~)here and here (the latter is now superseded by(h_<~)). There is some sort of common pattern here that seems likely to continue to pop up. I should have shortcuts for a bunch of these variants.
There are also some things I noticed which wouldn't save bytes here but should be done.
nχandnxycould use versions precomposed withmyandso.
Retina 0.8.2, 8 bytes
D`.
!`.$
Try it online! Takes input as a string. Explanation:
D`.
Keep only the first of each duplicated character.
!`.$
Keep the last remaining character.
PowerShell, 27 bytes
($args|% *ay|select -u)[-1]
Ungolfed:
($args | ForEach-Object -Member ToCharArray | Select-Object -Unique)[-1]
Converts the input string to a char array by calling the string's member "ToCharArray", then selecting only unique characters, and picking the last char.
Arturo, 15 bytes
$=>[last∪<=&]
Explanation
$=>[] ; a function where input is assigned to &
last ; last element of...
∪ ; union between...
<=& ; input and itself
This is two bytes shorter than last unique&, but requires the latest version for ∪, hence it won't work online yet.
Uiua SBCS, 3 bytes
⊢⇌◴
⊢⇌◴
◴ # deduplicate
⊢⇌ # last
Python, 26 bytes
lambda s:max(s,key=s.find)
Takes a string as input. s.find(c) outputs the first index in s where the character c appears, so using s.find as a key for max returns the character whose first occurrence in s comes latest.
JavaScript (ES6), 24 bytes
Note that it works because Set is guaranteed to maintain the insertion order of its elements.
s=>[...new Set(s)].pop()
Commented
s => // s = input string
[... // turn into an array ...
new Set(s) // ... the set generated from s
// e.g. "BANANA" -> Set {'B','A','N'}
] //
.pop() // return the last element

