# Type uniqchars!

Given a string consisting of printable ASCII chars, produce an output consisting of its unique chars in the original order. In other words, the output is the same as the input except that a char is removed if it has appeared previously.

No built-ins for finding unique elements in an array can be used (for example, MATLAB has a unique function that does that). The idea is to do it manually.

Further details:

• Either functions or programs are allowed.
• Input and output can be in the form of function arguments, stdin/stdout (even for functions), or a mix of those.
• If stdin or stdout are used, a string is understood as just the sequence of chars. If function arguments are used, the sequence of chars may need to be enclosed in quotation marks or equivalent symbols that the programming language of choice uses for defining strings.
• The output should be a string containing only the unique characters of the input. So no extra linebreaks, spaces etc. The only exception is: if the output is displayed in stdout, most displaying functions add a trailing \n (to separate the string from what will come next). So one trailing \n is acceptable in stdout.
• If possible, post a link to an online interpreter/compiler so that others can try your code.

This is code golf, so shortest code in bytes wins.

Some examples, assuming stdin and stdout:

1. Input string:

Type unique chars!


Output string:

Type uniqchars!

2. Input string

"I think it's dark and it looks like rain", you said


Output string

"I think'sdarloe,yu

3. Input string

3.1415926535897932384626433832795


Output string

3.14592687

• Just to double check: Does the no builtins rule mean that set objects are disallowed? – Sp3000 Oct 4 '15 at 14:51
• @Sp3000 Set objects are allowed. Just don't use a function or method (if it exists) that gives you its unique elements. And input/output should be strings, not set tobjects – Luis Mendo Oct 4 '15 at 14:54
• I think only my answer uses sets currently, and I wouldn't mind if you changed it. However, I'm not really sure a bonus like that would change much, e.g. I doubt CJam would be doable in < 6 bytes without sets. Also, I'm not sure where the line is between a builtin which finds unique elements, and constructing a set from a number of elements... – Sp3000 Oct 4 '15 at 15:13
• @Sp3000 Yes, it's a blurred border. I hadn't anticipated set functions. I think I'll leave the challenge as it is now – Luis Mendo Oct 4 '15 at 15:16
• -1 Disallowing built-ins serves no purpose other than making interesting answers. This is code-golf, not popularity contests. – MilkyWay90 Apr 6 '19 at 2:26

# Simplex v.0.7, 22 10 bytes

s^oR^l^Ryg
s          ~~ string input
^o        ~~ convert to tuple
R       ~~ go right
^l     ~~ unicode tuple
^R   ~~ take intersection
yg ~~ convert to string and output


sigh Minkolang is kicking Simplex's butt.

s^[oZ%_Q]n?[^_s^~M^=]]
s                      ~~ string input
^[     ]              ~~ postfixes each of the inner with a ^
o                   ~~ convert to tuple
Z                ] ~~ fold
%                 ~~ tuple w/out current character + increment
_                ~~ current character
Q               ~~ membership
n?[        ]  ~~ if current character not in tuple
^_s^~M^=   ~~ print that character


• What a coup for Simplex! – El'endia Starman Oct 28 '15 at 2:51

# AutoIt, 107

Func _($0)$1=''
For $2 In StringSplit($0,'',3)
$1&=StringInStr($1,$2,1)?'':$2
Next
Return $1 EndFunc  Call it like any function: ConsoleWrite(_("Type unique chars!"))  # CJam, 9 Lq{1$-+}/


This doesn't convert a string to a set, but it performs a kind of set difference to determine whether a character is found in a string. Try it online

Explanation:

L       push an empty array/string
{…}/    for each character in the input
1$copy the previous string - subtract from the character (set difference), resulting in the character or empty string + append the result to the string  ### Another version, 13 bytes: Lq{_2$#)!*+}/


This doesn't do anything related to sets. Try it online

Explanation:

L       push an empty array/string
{…}/    for each character in the input
_     duplicate the character
2$copy the previous string #) find the index of the character in the string and increment it ! negate, resulting in 0 if the character was in the string and 1 if not * repeat the character that many times + append the result to the string  # Haskell, 50 f=concat.(tail>>=zipWith(\x y->[last x]\\y)).inits  • inits is in Data.List, so you need an import, which is usually added to the byte count. – nimi Oct 4 '15 at 20:46 # Matlab, 46 bytes It uses an anonymous function, with function arguments as input and output: @(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))')  (I couldn't get this to work in an Octave online interpreter.) Example use: >> @(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))') ans = @(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))') >> ans('Type unique chars!') ans = Type uniqchars!  • that would have been my idea as well :) - you don't need the ,1 with any, btw. – Jonas Oct 4 '15 at 20:57 • @Jonas Thanks! Alrhough it's hard to see through that mess of parentheses, the 1 is for triu (I need to remove the diagonal), not for any – Luis Mendo Oct 4 '15 at 22:36 # Delphi, 111 bytes procedure u(var s:string);var i:word;begin for i:=length(s) downto 1 do if pos(s[i],s)<i then delete(s,i,1)end;  Using the procedure to alter the passed in string - saves a few bytes in comparison to declaring the function. Moving backwards through the string, delete the current character if it is not the first location of that character # JavaScript (ES6) 46 f=s=>[...s].map(c=>s[c]?'':s[c]=c,s=[]).join  Unexpectedly, this time the flag array is one byte shorter than the indexOf approach. # SED, 61 bytes s/^/\a/ : s/\a$$\(.$$.*\)\2/\a\1/ t s/\a$$.$$/\1\a/ t s/\a//  • 2 characters shorter: s/\a$$.$$$$.*$$\1/\a\1\2/s/\a$$\(.$$.*\)\2/\a\1/. If you have GNU sed you can remove the parenthesis escaping at the price of +1 for the -r switch. – manatwork Oct 6 '15 at 13:43 • @manatwork: Nice, changed. (I could also shrink all \a sequences into a single unprintable BEL character, though I'm not sure it's really worth it) – Hasturkun Oct 6 '15 at 14:08 # Perl 5.10+, 21 bytes perl -pe '1while s/(.).*\K\1//'  20 bytes + 1 byte for -p. Note that Perl 5.10 or above is required for \K. Takes input from stdin: $ echo 'Type unique chars!' | perl -pe '1while s/(.).*\K\1//'
Type uniqchars!

$echo \"I think it\'s dark and it looks like rain\", you said | perl -pe '1while s/(.).*\K\1//' "I think'sdarloe,yu$ echo 3.1415926535897932384626433832795 | perl -pe '1while s/(.).*\K\1//'
3.14592687


Online demo

Inspired by NinjaBearMonkey's Retina answer. Perl may not have a compact way to re-run a substitution until nothing changes, but it does have \K, which causes the regex engine to "keep" everything to its left. This allows you to drop a set of parentheses on the LHS and a capture variable on the RHS:

s/(.).*\K\1//   # 13 bytes


vs.

s/((.).*)\2/$1/ # 15 bytes  • Save 1 byte using s/(.).*\K\1//&&redo – Ton Hospel Sep 28 '16 at 11:50 ## Minkolang 0.10, 13 bytes This language was made after this challenge but not for this challenge. Much thanks to Sp3000 for pointing me the way to this much shorter solution. od?.dd0q?Od0p  Try it here. ### Explanation od Read character from input and duplicate it (for the conditional) ?. Stop if 0 (i.e., input is empty) dd Duplicate twice (for q and for possible output) 0q Gets value stored in (character,0) in the codebox (0 if empty) ?O Outputs character if it's unique (i.e. the previous value was 0) d0p Puts the value of the character at (value,0) in the codebox  # AppleScript, 143 142 Bytes set x to(display dialog""default answer"")'s text returned's characters set o to"" repeat with i in x if not i is in o then set o to o&i end o Not a language for golfing, but it's very readable. # Octave, 25 bytes @(s)s(sum(triu(s'==s))<2)  # Javascript (ES6), 47 bytes a=>[...a].filter((b,c)=>a.indexOf(b)==c).join  Test it here Some code is added to have a better input and to write to the console the result. d=document,g=d.getElementById.bind(d);g("s").onclick=e=>console.log((a=>[...a].filter((b,c)=>a.indexOf(b)==c).join)(g("t").value)) <input id="t"><button id="s">Convert</button> # Vim, 23 keystrokes qq:s/\v(.).*\zs\1<cr>@qq@q  Explanation: qq " Start recording into register 'q' :s/ " Search and replace: \v " Enable 'magic', which just makes regexes a littl shorter (.) " Any symbol, captured in group one .* " Anything \zs\1 " Start selection, group one " Replace with nothing <cr> " Globally @q " Call macro q. Since we are still recording, this will not do anything the first time, and create a loop the next time q " Stop recording. @q " Start the loop. This will run until there is no match.  Since V is backwards compatible, you can Try it online! # Ruby, 19 + 1 = 20 bytes Uses the -p flag. Uses set operations like the GolfScript answer, which is totally not a built-in like uniq. (Performing set or on a list and an empty list purges the list of duplicates, just like calling and against a copy of itself.) $_=($_.chars|[])*""  # Python 3, 26 bytes lambda s:[*dict(zip(s,s))]  Try it online! Reviving an ancient question with a new idea, inspired by Noodle9's solution to "Special String reformatting" and my further refinement. Because Python 3's dictionaries automatically remove duplicate keys beyond the first appearance while keeping them in order, we convert the the input string to a dictionary as keys. We then convert the dictionary back to a list with iterable unpacking, which extracts its keys. (The challenge seems to be fine with a list of characters in lieu of a string, asking for a "sequence of chars".) While we could make the dictionary via a comprehension like {c:1for c in s}, it's one byte shorter to use the dict constructor as dict(zip(s,s)), which each character is both the key and the values. A same-length alternative is {}.fromkeys(s). Note that while set does also remove duplicates, it fails to keep them in order, and is also disallowed by the challenge. • Great explanation. I could follow it perfectly with my limited Python knowledge. Yes, any sequence of chars is fine, not necessarily a string. By the way, set operations are allowed, and in fact some answers use them. (In retrospect, forbidding builtins was not a great idea anyway. It was my first challenge, and I guess in 2015 we were more permissive with that) – Luis Mendo Jun 9 at 23:05 # Scala, 118114 bytes def f(a:String):String=a.zipWithIndex.groupBy(_._1.toLower).map(_._2.head).toList.sortBy(_._2).map(_._1).mkString  # Python 2, 79 def S(s): s=s[::-1] for c in s:s=s.replace(c,'',s.count(c)-1) return s[::-1]  It reverses the input string, cycles through it, replaces any extra characters with null ones and returns the reverse of that. The reverse is so the last characters are removed, not the first. >>> S('''"I think it's dark and it looks like rain", you said''') '"I think\'sdarloe,yu' >>> S("3.1415926535897932384626433832795") '3.14592687' >>> S("Type unique chars!") 'Type uniqchars!'  • 68 bytes – nope Jun 10 at 11:48 ## Haskell, 33 bytes foldl(\r c->r++[c|notElem c r])[]  Uses foldl to iterate through the string appending characters that are not in the current result, starting with the empty string (list). # MUMPS, 54 bytes f(s) f i=1:1:$L(s) s c=$E(s,i) s:t'[c o=o_c,t=t_c q o  Not terribly exciting - it just keeps a running list of already-viewed characters and only appends to the output string if the current character isn't in that list. # Powershell, 30 $args-replace'(.)(?<=\1.+)',''


I feel there's likely to be a better regex than this, and I can't work out what it is

# Rust, 318 Bytes

not really a competitor, but rust needs a bit more love. As always, comments and advice welcome.

use std::io;fn main(){let mut s=io::stdin();let mut b=String::new();s.read_line(&mut b).unwrap();let mut n: Vec<char>=b.chars().collect();for i in 0..n.len()-2{let mut j=i+1;let mut p = true;while j<n.len(){if j<n.len(){if n[i]==n[j]{n.remove(j);p=false;}}if p{j+=1;}p=true;}}for i in 0..n.len()-2{print!("{}",n[i]);}}


Try it online here (first compile, then execute, then click into the proper area to enter user input)

ungolfed:

use std::io;
fn main() {
let mut s = io::stdin();
let mut b=String::new();
let mut chars: Vec<char> = b.chars().collect();
for i in 0..chars.len()-2 {
let mut j=i+1;
let mut inc = true;
while j<chars.len() {
if j<chars.len()
{
if chars[i]==chars[j] {
chars.remove(j);
inc = false;
}
}
if inc {
j+=1;
}
inc = true;
}
}
for i in 0..chars.len()-2 {
print!("{}",chars[i]);
}
}


# Python 2, 62 bytes

s=set();print filter(lambda i:not(i in s or s.add(i)),input())


# Python 3, 132109 105 bytes

u=[]
def t(l):
if l in u:return''
else:
u.append(l);return l
print(''.join([t(l)for l in input()]))


Ungolfed:

used_chars = []
def test(letter):
if letter in used_chars:
return '' # skip
else:
used_chars.append(letter)
return letter
print(''.join([test(letter) for letter in input()]))

• Shouldn't the r(l) in the last line be t(l)? – user4768 Oct 5 '15 at 9:16
• Also, you can use print if you end the line with a comma: print ('%s') % (''.join([r(l)for l in i])), then import sys won't be necessary. – user4768 Oct 5 '15 at 9:19
• Following Thomas Kwa's suggestion, one trailing \n is acceptable in stdout (in fact it's implicit in many functions used for displaying into stdout). I've made this explicit in the challenge rules. You may perhaps use that to reduce your code length – Luis Mendo Oct 5 '15 at 9:54

# Scala, 79, 66 bytes

Inspired by the Haskell version using foldLeft

def f(s:String)=s.foldLeft("")((a,c)=>if(a.contains(c))a else a+c)


Previous version using zipWithIndex and collect

def f(s:String)=s.zipWithIndex.collect{case(c,i)if s.indexOf(c)==i=>c}.mkString


## Perl 6, 32 bytes

The way you would normally write this would be:

$*IN.comb.unique.print # it would have been 22  Which would have had the benefit of being obviously correct. Instead I have to write something like the following print$*IN.comb.grep:{!.{$^a}++} # 32  # Gema, 18 characters ?=${?;$0}@set{$0;}


Sample run:

bash-4.3$gema '?=${?;$0}@set{$0;}' <<< 'hello world'
helo wrd


## R, 52 bytes

cat(union(a<-strsplit(readline(),"")[[1]],a),sep="")


Test examples:

Type uniqchars!
"I think'sdarloe,yu
3.14592687


# RProgN, 85 Bytes, Non Competing

S i 'a' = s 'n' = a L while a pop 'b' = n b hasvalue ! if n b push end a L end n i ++


# Explanation

S i                     # Take the implicit string input, convert it to a stack such that the first letter is at the bottom, invert the stack such that the first letter is at the top.
'a' =                   # Associate it with 'a'
s 'n' =                 # Create a new stack, associate it with 'n'
a L                     # Push the size of a
while                   # While the top of the stack contains a truthy value
a pop 'b' =         # Pop the top of a, associate it with 'b'
n b hasvalue !      # Push if the stack 'n' does not contain b
if                  # If the top of the stack is truthy
n b push        # Push b to the stack n
end                 #
a L                 # Push the length of a
end                     # loop
n i ++                  # Push the n, inverts it, sums it, which acts to concatenate it, implicitly print the result.


Non-Competing as the 'Not' and 'HasValue' functions were both not implemented prior to this challenge.

## REXX, 79 bytes

a=arg(1)
o=
do while a>''
parse var a b+1 a
if pos(b,o)=0 then o=o||b
end
say o