Determine if all decimal digits are unique

Deleted questions on Stack Overflow sometimes make for great golf material.

Write a function that takes a nonnegative integer as input, and returns true if all the digits in the base 10 representation of that number are unique. Example:

48778584 -> false
17308459 -> true

Character count includes only the function.

If you choose to answer in C or C++: no macros, no undefined behaviour; implementation-defined behaviour and compiler warnings are fine.

• I'd still be interested in other C or C++ solutions as per the question that inspired this one. May 21, 2014 at 19:59
• Why no C or C++ macros or undefined behavior? That's oddly limiting to just two languages. Apr 14, 2019 at 2:05

Golfscript, 8 7 characters:

{..&=}
•  - stringify the argument
• .. - clone twice
• & - intersect with itself (remove duplicates)
• = - check for equality.

if the function needs to be named (10 9 characters):

{..&=}:a

if a program suffices (5 4 characters):

..&=
• The hard part about challenges like this is being the first to see it. May 22, 2014 at 2:11
• @primo yet, somehow, they still get +6 score within half a day. May 22, 2014 at 7:16
• @JanDvorak Parkinson's law of triviality at work May 22, 2014 at 20:43
• @Claudiu You can understand the law. Realise you're being subjected to it. Then upvote the answer anyway. May 23, 2014 at 17:16
• @NathanChere what do you mean? the last (and only) time that loophole was suggested it dropped to -3 before getting deleted by the suggester the next morning. If you don't like golfscript answers, don't upvote them. Nov 25, 2014 at 11:49

Python 2 (28) (32)

lambda n:10**len(set(n))>n

The backticks take the string representation. Converting to a set removes duplicates, and we check whether this decreases the length by comparing to 10^d, which is bigger than all d-digit number but no (d+1)-digit numbers.

Old code:

lambda n:len(set(n))==len(n)
• Ha I had this exact same answer ready, just replace n with i May 21, 2014 at 19:57
• @Claudiu so did I. f=lambda _:len(_)==len(set(_)) May 21, 2014 at 19:59
• Yeah, with these bite-size challenges, everyone is going to converge on pretty much the same thing. I was also trying lambda n:max(map('n'.count,'n'))<2 (the single quotes are backticks), but it's two chars longer.
– xnor
May 21, 2014 at 20:49

APL (6)

≡∘∪⍨∘⍕

One of the few times where tacit style is shorter in APL too.

It's 8 characters to give it a name,

f←≡∘∪⍨∘⍕

but that's not necessary to use it:

≡∘∪⍨∘⍕ 199
0
≡∘∪⍨∘⍕ 198
1
f←≡∘∪⍨∘⍕
f¨ 198 199 200 201
1 0 0 1
≡∘∪⍨∘⍕¨ 198 199 200 201
1 0 0 1
• I think the second jot can be removed to make it 5. It would still be a valid function by itself (though it would require grouping parens to use it with each operator in the last example). Nov 9, 2015 at 9:44

Perl, 19 characters

print<>!~/(\d).*\1/
• assuming output can be treated as true and no-output can be treated as false, your logic is reversed. You should return true if there's no repetition. May 21, 2014 at 19:45
• @JanDvorak Sounds about right. I'll fix that.
– Tal
May 21, 2014 at 19:48
• Not-match operator: <>!~/(\d).*\1/. May 22, 2014 at 4:17
• @primo Thanks! So much to learn :)
– Tal
May 22, 2014 at 4:25
• The input is specified as being a non-negative integer, so I don't think you need to verify that. If you indeed don't, you can change \d to ..
– hvd
May 22, 2014 at 7:06

Rebmμ (10 characters)

e? AtsAuqA

Rebmu's "mushing" trick is that it's case-insensitive, so characters are run together. Whenever a case transition is hit, that splits to the next token. By using transitions instead of a CamelCase kind of thing, the unique choice to start with a capital run means a "set-word" is made. (While set-words can be used for other purposes in symbolic programming, they are evaluated as assignments by default).

So this "unmushes" to:

e? a: ts a uq a

The space is needed because once you've begun a series of runs of alternating cases, you can't use that trick to get a set-word after the first unless you begin a new run. So e?AtsAuqA would have gotten you e? a ts a uq a...no assignment.

(Note: For what may be no particularly good reason, I tend to prefer rethinking solutions so that there are no spaces, if character counts are equal. Since brackets, parentheses, and strings implicitly end a symbol...there are often a fair number of opportunities for this.)

In any case, when mapped to the Rebol that it abbreviates:

equal? a: to-string a unique a

Throwing in some parentheses to help get the gist of the evaluation order:

equal? (a: (to-string a)) (unique a)

So the prefix equality operator is applied to two arguments--the first the result of assigning to a of the string version of itself, and the second the result of unique being run against that string. It so happens that unique will give you back the elements in the same order you passed them...so unique of "31214" is "3124" for instance.

Run it with:

>> rebmu/args "e? AtsAuqA" 17308459
== true

There's also some stats and debug information:

>> rebmu/args/stats/debug "e? AtsAuqA" 48778584
Original Rebmu string was: 10 characters.
Rebmu as mushed Rebol block molds to: 10 characters.
Unmushed Rebmu molds to: 15 characters.
Executing: [e? a: ts a uq a]
== false

If the requirement is that one must define a named/reusable function you can make an "A-function" which implicitly takes a parameter named a with a|. (A B-function would be created with b| and take a parameter named A then one named B). So that would add five more characters...let's say you call the function "f"

Fa|[e? AtsAugA]

"You laugh! They laughed at Einstein! Or wait...did they? I...don't know."

• I used to think the language was pronounced like Reb moo, but now I'm not sure if it's supposed to be Rebum mew or Reb mew or something else. May 23, 2014 at 1:48
• After playing Nethack, I read Fa|[e? AtsAugA] as False? SomeGibberish May 23, 2014 at 1:49
• @Quincunx does s really decay to [ in Nethack? May 25, 2014 at 11:08
• @JanDvorak I've seen some letters do decay into [ after some time May 28, 2014 at 4:18
• @Quincunx Just playing with the logo. I think REBmu is probably better. Either way, the beard is tight..it pinches. Guess you get what you pay for. May 28, 2014 at 5:05

FRACTRAN - 53 38 fractions

47/10 3/5 106/47 3599/54272 53/61 2881/27136 2479/13568 2077/6784 1943/3392 1541/1696 1273/848 1139/424 871/212 737/106 469/53 142/3953 67/71 5/67 1/147 1/363 1/507 1/867 1/1083 1/1587 1/2523 1/2883 1/4107 1/5547 1/7 1/11 1/13 1/17 1/19 1/23 1/29 1/31 1/37 1/43

Uses division to count the number of occurrences of each digit. Call by putting n in register 2 and setting register 5 to 1, gives output in register 3 (0 if false, 1 if true). Also, make sure the rest of your program uses only registers > 71.

Edit 25/12/14: It's been 7 months and we've since gotten Stack Snippets, so here's one to test the code (using my could-be-better interpreter here).

var ITERS_PER_SEC=1E5;var TIMEOUT_MILLISECS=5E3;var ERROR_INPUT="Invalid input";var ERROR_PARSE="Parse error: ";var ERROR_TIMEOUT="Timeout";var ERROR_INTERRUPT="Interrupted by user";var running,instructions,registers,timeout,start_time,iterations;function clear_output(){document.getElementById("output").value="";document.getElementById("stderr").innerHTML=""};function stop(){running=false;document.getElementById("run").disabled=false;document.getElementById("stop").disabled=true;document.getElementById("clear").disabled=false}function interrupt(){error(ERROR_INTERRUPT)}function error(msg){document.getElementById("stderr").innerHTML=msg;stop()}function factorise(n){var factorisation={};var divisor=2;while(n>1){if(n%divisor==0){var power=0;while(n%divisor==0){n/=divisor;power+=1}if(power!=0)factorisation[divisor]=power}divisor+=1}return factorisation};function fact_accumulate(fact1,fact2){for(var reg in fact2)if(reg in fact1)fact1[reg]+=fact2[reg];else fact1[reg]=fact2[reg];return fact1};function exp_to_fact(expression){expression=expression.trim().split(/\s*\*\s*/);var factorisation={};for(var i=0;i<expression.length;++i){var term=expression[i].trim().split(/\s*\^\s*/);if(term.length>2)throw"error";term[0]=parseInt(term[0]);if(isNaN(term[0]))throw"error";if(term.length==2){term[1]=parseInt(term[1]);if(isNaN(term[1]))throw"error";}if(term[0]<=1)continue;var fact_term=factorise(term[0]);if(term.length==2)for(var reg in fact_term)fact_term[reg]*=term[1];factorisation=fact_accumulate(factorisation,fact_term)}return factorisation}function to_instruction(n,d){instruction=[];divisor=2;while(n>1||d>1){if(n%divisor==0||d%divisor==0){reg_offset=0;while(n%divisor==0){reg_offset+=1;n/=divisor}while(d%divisor==0){reg_offset-=1;d/=divisor}if(reg_offset!=0)instruction.push(Array(divisor,reg_offset))}divisor+=1}return instruction};function run(){clear_output();document.getElementById("run").disabled=true;document.getElementById("stop").disabled=false;document.getElementById("clear").disabled=true;timeout=document.getElementById("timeout").checked;var code=document.getElementById("code").value;var input=document.getElementById("input").value;instructions=[];code=code.trim().split(/[\s,]+/);for(i=0;i<code.length;++i){fraction=code[i];split_fraction=fraction.split("/");if(split_fraction.length!=2){error(ERROR_PARSE+fraction);return}numerator=parseInt(split_fraction[0]);denominator=parseInt(split_fraction[1]);if(isNaN(numerator)||isNaN(denominator)){error(ERROR_PARSE+fraction);return}instructions.push(to_instruction(numerator,denominator))}try{registers=exp_to_fact(input)}catch(err){error(ERROR_INPUT);return}running=true;iterations=0;start_time=Date.now();fractran_iter(1)};function regs_to_string(regs){reg_list=Object.keys(regs);reg_list.sort(function(a,b){return a-b});out_str=[];for(var i=0;i<reg_list.length;++i)if(regs[reg_list[i]]!=0)out_str.push(reg_list[i]+"^"+regs[reg_list[i]]);out_str=out_str.join(" * ");if(out_str=="")out_str="1";return out_str};function fractran_iter(niters){if(!running){stop();return}var iter_start_time=Date.now();for(var i=0;i<niters;++i){program_complete=true;for(var instr_ptr=0;instr_ptr<instructions.length;++instr_ptr){instruction=instructions[instr_ptr];perform_instr=true;for(var j=0;j<instruction.length;++j){var reg=instruction[j][0];var offset=instruction[j][1];if(registers[reg]==undefined)registers[reg]=0;if(offset<0&&registers[reg]<-offset){perform_instr=false;break}}if(perform_instr){for(var j=0;j<instruction.length;++j){var reg=instruction[j][0];var offset=instruction[j][1];registers[reg]+=offset}program_complete=false;break}}if(program_complete){document.getElementById("output").value+=regs_to_string(registers);stop();return}iterations++;if(timeout&&Date.now()-start_time>TIMEOUT_MILLISECS){error(ERROR_TIMEOUT);return}}setTimeout(function(){fractran_iter(ITERS_PER_SEC*(Date.now()-iter_start_time)/1E3)},0)};
<div style="font-size:12px;font-family:Verdana, Geneva, sans-serif;"><div style="float:left; width:50%;">Code:<br><textarea id="code" rows="4" style="overflow:scroll;overflow-x:hidden;width:90%;">47/10 3/5 106/47 3599/54272 53/61 2881/27136 2479/13568 2077/6784 1943/3392 1541/1696 1273/848 1139/424 871/212 737/106 469/53 142/3953 67/71 5/67 1/147 1/363 1/507 1/867 1/1083 1/1587 1/2523 1/2883 1/4107 1/5547 1/7 1/11 1/13 1/17 1/19 1/23 1/29 1/31 1/37 1/43</textarea><br>Input:<br><textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;">2^142857 * 5</textarea><p>Timeout:<input id="timeout" type="checkbox" checked="true"></input></p></div><div style="float:left; width:50%;">Output:<br><textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea><p><input id="run" type="button" value="Run" onclick="run()"></input><input id="stop" type="button" value="Stop" onclick="interrupt()" disabled="true"></input><input id="clear" type="button" value="Clear" onclick="clear_output()"></input>&nbsp;<span id="stderr" style="color:red"></span></p></div></div>

Replace 142857 with another number. Output should be 3^1 if true, 1 = 3^0 if false. Takes a while for larger numbers (well, this is FRACTRAN...).

• See this answer for a 15-fraction solution. Apr 21 at 23:08

JavaScript - 23 Characters

As a function (ECMAScript 6):

f=x=>!/(.).*\1/.test(x)

Or taking input from a prompt (25 characters)

!/(.).*\1/.test(prompt())

C# 7360 59

First golfing for me ...

Write a function that takes a nonnegative integer as input

bool f(int i){return(i+"").Distinct().SequenceEqual(i+"");}

Could strip another character by converting uint to int, but I rather take the task too literally than the other way around. Here we go ...

• Some options: i => (i + "").Distinct().SequenceEqual(i + ""); May 22, 2014 at 10:14
• @NPSF3000 Thanks! Edited my answer. I had something like this on my mind, but oh well ... I totally forgot about +"" calling ToString() under the hood. May 22, 2014 at 10:46
• A more literal interpretation of "nonnegative integer" suggests that a signed integer will be passed in, but it will never be negative.
– Shaz
May 22, 2014 at 14:49
• Well, I guess it will be ok then ... May 23, 2014 at 4:46
• Use C# 6 and you can use: bool f(int i)=>(i+"").Distinct().SequenceEqual(i+""); (53 bytes) Dec 2, 2015 at 11:23

Ruby (24 bytes)

Use a regular expression to match "some character, followed by zero or more characters, then the same character".

->(s){!!(s !~/(.).*\1/)}

If truthy or falsy values are accepted, rather than literal true or false, then we get 20 characters:

->(s){s !~/(.).*\1/}
• -2 bytes by omitting the parentheses around the function parameter. Also, presumably your 20 byte version used to not return literal true / false in a previous version of Ruby, but in modern Ruby it does: Try it online! Jun 30 at 20:07

C (87)

Since I can't win, I'll go for efficiency.

Function code:

int u(uint32_t d){short s=0,f;while(d){f=1<<d%10;if(s&f)return 0;s|=f;d/=10;}return 1;}
• Oh, and since I still can't comment on other people's posts -- I'd like to say that this was a neat solution, even if inaccurate when it "overflows". May 22, 2014 at 23:08
• 70 bytes Jun 30 at 16:46

Mathematica, 35 25 characters

(27 if the function needs a name.)

Unequal@@IntegerDigits@#&

EDIT: Saved 8 characters thanks to belisarius!

• Unequal @@ IntegerDigits@# & could do, I think May 21, 2014 at 21:23
• @belisarius oh nice, I was looking for something like that but couldn't find it (and didn't think that chained would compare non-adjacent elements). Thanks, that shortens this a lot! May 21, 2014 at 22:20
• You don't have to give it a name, right? Unequal@@IntegerDigits@#& is 25 characters. May 23, 2014 at 21:39
• @Akater true, I can't see a requirement for the name in the challenge. Thanks! May 23, 2014 at 21:44

R, 535148 34 Bytes

function(n)!grepl("(.).*\\1",n,,T)

Try it online!

Convert to a string and split. Convert to a table of counts minus 1, sum and negate

Inspired by Most common number answer by Alex and suggestion by Hugh.

A couple saved, thanks to @plannapus One more from @Gregor And a couple from making it an anonymous function

Now with wonderful regex goodness thanks to @J.Doe. This looks for any single char in the number that matches itself else where in the string. The grepl command returns a logical that is then returned. Perl style regexes is set to True.

• You can also convert to string using paste0 instead of toString and save 2 characters. Dec 24, 2014 at 17:11
• You can use paste instead of paste0 to save one more character. Nov 2, 2017 at 18:57
• 45 bytes using utf8ToInt Sep 4, 2018 at 13:35
• @J.Doe: even better ! :) Sep 4, 2018 at 14:44
• Used a different approach. 35 bytes with regex. Sep 4, 2018 at 15:36

J (9)

Assumes the value to be tested is in variable b (I know this can be made into a function, but don't have a clue on how. J is confusing. Any help on this is appreciated) Thanks Marinus!

(-:~.)@":

Checks if the lenght of the string rep of the number with all the duplicates removed is the same as the lenght of the regular string rep.

• For a function you can do (-:~.)@":. May 21, 2014 at 20:22
• @marinus Oh wow, that's even shorter than I thought. Thanks! May 21, 2014 at 20:24
• HI, I found and posted a shorter J solution: -:~.&.": Nov 2, 2017 at 17:25

R (70, 60, 53, 52)

### Version 70 chars
f=function(x)!any(duplicated(strsplit(as.character(x),split="")[[1]]))

### Version 60 chars
f=function(x)all(table(strsplit(as.character(x),"")[[1]])<2)

### Version 53 chars
f=function(x)all(table(strsplit(paste(x),"")[[1]])<2)

### Version 52 chars
f=function(x)all(table(strsplit(c(x,""),"")[[1]])<2)

f(48778584)
f(17308459)
• @plannapus, you are right. I got confused about "base 10 representation". May 22, 2014 at 11:33
• Using table and comparing against 0 instead of duplicated might save some characters May 22, 2014 at 21:26
• And I think you could leave the split parameter unnamed. I'm just on my phone so can't check easily but I believe it is the second parameter of strsplit so you could use positional instead of named arguments to save characters May 22, 2014 at 21:29
• And since you already take the first element of the result of strsplit why not coercing x to a character using c(x,"")? f=function(x)all(table(strsplit(c(x,""),"")[[1]])<2) is 1 character shorter :) May 23, 2014 at 8:38

Mathematica (20 19)

(22 21 if function needs a name)

Max@DigitCount@#<2&

or

Max@DigitCount@#|1&

where | ist entered as [Esc]divides[Esc]

• Nice. I forgot DigitCount existed, and wrote a solution based on conversion to strings. Yours is much better. Dec 25, 2014 at 17:24

import Data.List
((==)=<<nub).show

Try it online!

Try it online!

FRACTRAN, 15 fractions, 83 (or 32) bytes

This beats Sp3000's 38-fraction solution.

$$\frac25,\frac{875}{88},\frac78,\frac{25{\cdot}17^c}{92},\frac14,\frac{15}{38},\frac{69}{2},\frac{23}{17},\frac{19}{3^b},\frac43,\frac{7}{23},\frac{26}{19},\frac{11}{7^c},\frac{1}{91},\frac{8}{11}$$

The initial state is $$\3^n\cdot 13\cdot 23\$$. It halts at $$\1\$$ if every digit in the base-$$\b\$$ representation of $$\n\$$ occurs fewer than $$\c\$$ times, and at some other value otherwise. Plug in $$\b=10, c=2\$$ to get the answer to the challenge as posed.

The final state is actually $$\13^{k - \mathrm{wt}_c\left(\sum c^{d_i}\right)}\$$, where $$\d_1\cdots d_k\$$ are the base-$$\b\$$ digits of $$\n\$$, and $$\\mathrm{wt}_c\$$ is the base-$$\c\$$ digit sum. Adding a power of $$\c\$$ increases the digit sum by $$\1\$$ if there is no carry, and doesn't increase it if there is a carry, so the final state is $$\1\$$ iff each digit occurs fewer than $$\c\$$ times.

The length of the $$\b=10, c=2\$$ version is 83 bytes in the decimal coding (2/5,875/88,...) that seems to be standard here. With a more efficient coding (Elias δ), it's 32 bytes.

There's a fast online interpreter here. I see no way to encode a program in the URL, so you'll have to copy-paste this:

2%5 875%88 7%8 25*17^2%92 1%4 15%38 69%2 23%17 19%3^10 4%3 7%23 26%19 11%7^2 1%91 8%11

Then enter, e.g., [3,48778584],[13,1],[23,1] as the input.

C99, 59 chars

a(x){int r=1,f[10]={};for(;x;x/=10)r&=!f[x%10]++;return r;}
• C99 doesn't have implicit int, technically. May 21, 2014 at 20:55
• Not just "technically", it was specifically and intentionally removed. This is a syntax error in C99, and aside from a required diagnostic, syntax errors are in the same category as undefined behaviour (explicitly disallowed in the question): if an implementation accepts this, the standard makes no requirements whatsoever about the program's behaviour.
– hvd
May 22, 2014 at 7:09
• 58 bytes Jun 30 at 16:39

Groovy (36 chars)

f={s="$it" as List;s==s.unique(!1)} Tested it using: println f(args[0].toInteger()) • 'false' can be golfed via '1==0' or possibly something more clever. Good answer May 22, 2014 at 1:57 • @MichaelEaster 0>1 is shorter. May 22, 2014 at 10:14 • @ace Yes, though !1 works too... May 22, 2014 at 10:16 • @ace, MichaelEaster, thx for the help :-) May 22, 2014 at 12:06 • @WillP as suggested by MichaelEaster, use !1 instead. May 22, 2014 at 12:14 Haskell: import Data.List all ((== 1) . length) . group . sort . show • A little late to the party, but since you're importing Data.List anyway I'd suggest nub, which removes duplicates from a List. (\x->nub x==x).show May 30, 2014 at 18:07 • You didnt use pl... main = interact$ show . ap (==) nub . show Jun 15, 2014 at 20:26

POSIX sh and egrep (47, 43, 40)

f()([ ! echo $1|egrep '([0-9]).*\1' ]) • [-1 char]: Use ! instead of -z with test - Thanks DigitalTrauma • [-1 char]: Use CODE instead of$(CODE) - Thanks DigitalTrauma
• [-2 chars]: Use fold -1 instead of grep -o .1 - Thanks DigitalTrauma.
• [-3 chars]: Check for repeated digits with a backreferenced regular expression.

If POSIX compliance is not important echo PARAM | can be replaced by <<<PARAM, reducing the functions length to 37:

f()([ ! egrep '([0-9]).*\1'<<<$1 ]) Usage:$ if f 48778584; then echo true; else echo false; fi
false
$if f 17308459; then echo true; else echo false; fi true 1 The fold -N notation is deprecated in some versions of fold. • f()(! [ fold -1<<<$1|sort|uniq -d ]) down to 38 by my count May 29, 2014 at 23:39
• @DigitalTrauma: Good stuff thanks for sharing. I find that the tested command must be quoted, otherwise test croaks on it when uniq -d returns more than one line. So the shortest non-POSIX version is 40 characters. I know about the [ ! notation, but I am suprised that ! [ also works, do you know why that is?
– Thor
May 30, 2014 at 19:40
• Ah I was using bash. So I guess its longer if you want POSIX conformance. May 30, 2014 at 19:42

Java ( 13159 57)

79 78 characters (thanks @n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ ):

Use for loop to save a few charachers and use int as a boolean array.

Use & instead of && to save 1 character (It turns out that java allows it).

boolean u(int n){for(int x=0;n>0&(x>>n%10&1)==0;n/=10)x|=1<<n%10;return n==0;}

131 characters (returns true for negative numbers):

boolean u(int n){int[] p=new int[]{2,3,5,7,11,13,17,19,32,29};double a=9001312320D;while(n>0){a/=p[n%10];n/=10;}return (long)a==a;}

boolean unique(int n){
int[] p=new int[]{2,3,5,7,11,13,17,19,32,29};//list of 10 first primes
double a=9001312320D;//10 first primes multiplied
while(n>0){
a/=p[n%10];//divide by (n%10+1)th prime
n/=10;//divide n by 10, next digit
}
return (long)a==a;//if a is integer then n has all digits unique
}

And answer that is technically correct (character count includes only the function, not global variables), but I think it's cheating, 29 characters:

boolean u(int i){return m[i];}

m[] is boolean array that contains correct answers for all 32-bit integers.

• "^.*(.).*\\1.*$" You can drop ^ and$. They are implied by matches() Jun 15, 2014 at 13:34
• The 2nd approach can be done by using 10 bits in an int as a boolean array, which will eliminate the need for the prime table. Jun 15, 2014 at 13:39
• I know it's been three years, but if you remove the space between return! in the shortest answer, you can get to 56 bytes. Nov 3, 2017 at 14:20
• -1 byte Jun 30 at 18:48

J (8)

Competely sepertae from my previous answer.

*/@~:@":

R, 66 65 characters

f=function(x)!sum(duplicated((x%%10^(i<-1:nchar(x)))%/%10^(i-1)))

Separate the digits using integer division and modulo, then check if they are duplicates.

Usage:

> f(48778584)
[1] FALSE
> f(17308459)
[1] TRUE

Or, as @MickyT suggested, for 63 characters:

f=function(x)!anyDuplicated((x%%10^(i<-1:nchar(x)))%/%10^(i-1))
• You could use anyDuplicated rather than sum and duplicated for 2 more Dec 21, 2014 at 19:54

C, 58 bytes

f;a(x){for(f=0;x;x/=10)f+=1<<x%10*3;return!(f&920350134);}

Can keep a tally of up to 7 identical digits before rolling over.

in test program (it's easier to see how it works with the constant in octal)

a(x){int f=0;for(;x;x/=10)f+=1<<x%10*3;return!(f&06666666666);}

main(){
scanf("%d",&r);
printf("%o\n",a(r));}

If you happen to have a large power of 2 handy the constant can be calculated like f&(1<<30)/7*6

• I think the comment by @xfix was intended for my post instead of yours? You didn't actually used int main(int) in your answer... May 22, 2014 at 13:25
• Having external information that doesn't count towards the code byte/char count is obviously not allowed. I suggest you remove the first version (53 bytes).
– 2501
Apr 27, 2017 at 12:13
• Please see my comment in the edit summary.
– 2501
Apr 27, 2017 at 12:24
• I voted to reject the edit, but I agree that the counts look wrong. I make them 67 and 63 (61). Apr 27, 2017 at 12:39
• My edit was rejected by other users. Please re-evaluate it.
– 2501
Apr 27, 2017 at 13:09

J, 8 bytes

-:~.&.":

Explanation:

": - converts the integer to a string
&.   - "under" conjuction - uses the result from ": as operand to ~.
then applies the inverse to the result, so converts the string back to integer
~.      - removes duplicates
-:        - matches the operands

So, it first converts the number to a string, removes the duplicates and converts the resulting string to a number. Then the original number is matched against the transformed one. In fact it is a hook of two verbs: -: and ~.&.":

┌──┬──────────┐
│-:│┌──┬──┬──┐│
│  ││~.│&.│":││
│  │└──┴──┴──┘│
└──┴──────────┘

Try it online!

L,BDdq=

Try it online!

Javascript 73 chars

function f(n){return !~(n+'').split('').sort().join('').search(/(\d)\1/)}

Befunge 98, 17 bytes

This is a non-competing answer because Befunge does not have functions.

~:1g1j@1\1p3j@.1

Prints a 1 if the number's digits are all unique; otherwise, it just ends.

This works by accessing a cell in the Funge space whose x coordinate is the ASCII value of the character inputted (takes input character by character) and whose y coordinate is 1. If the digit has not been seen before, the value of the cell is 32 (space character). If that is so, I set the value to 1.

As a bonus, this works for non-numbers as well.