Determina se tutte le cifre decimali sono univoche


37

Le domande cancellate su Stack Overflow a volte rendono ottimo il materiale da golf.

Scrivi una funzione che accetta come input un numero intero non negativo e restituisce true se tutte le cifre nella rappresentazione di base 10 di quel numero sono univoche. Esempio:

48778584 -> false
17308459 -> true

Il conteggio dei caratteri include solo la funzione.

Se si sceglie di rispondere in C o C ++: nessuna macro, nessun comportamento indefinito; il comportamento definito dall'implementazione e gli avvisi del compilatore vanno bene.


Sarei comunque interessato ad altre soluzioni C o C ++ secondo la domanda che ha ispirato questa.
Thomas,

1
Perché nessuna macro C o C ++ o comportamento indefinito? Questo è stranamente limitante a solo due lingue.
Dfeuer

Risposte:


31

Golfscript, 8 7 caratteri:

{`..&=}
  • ` - Stringi l'argomento
  • .. - clona due volte
  • & - intersecarsi con se stesso (rimuovere i duplicati)
  • = - verifica l'uguaglianza.

se la funzione deve essere denominata (109 caratteri ):

{`..&=}:a

se un programma è sufficiente (54 caratteri ):

..&=

5
La parte difficile di sfide come questa è essere il primo a vederlo.
primo

1
@primo, in qualche modo, ottengono ancora +6 punti in mezza giornata.
John Dvorak,

1
@JanDvorak La legge della banalità del lavoro al lavoro
Claudiu,

2
@Claudiu Puoi capire la legge. Renditi conto di esserne sottoposto. Quindi vota comunque la risposta.
Cruncher,

1
@NathanChe cosa intendi? l'ultima (e unica) volta in cui è stata suggerita la scappatoia è scesa a -3 prima di essere cancellata dal suggeritore la mattina successiva. Se non ti piacciono le risposte di golfscript, non votarle.
John Dvorak,

24

Python 2 (28) (32)

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

I backtick prendono la rappresentazione di stringa. La conversione in un set rimuove i duplicati e controlliamo se ciò riduce la lunghezza confrontandola con 10 ^ d, che è maggiore di tutti i numeri di cifre d ma nessun numero di cifre (d + 1).

Vecchio codice:

lambda n:len(set(`n`))==len(`n`)


1
Ah, avevo già pronta la stessa identica risposta, basta sostituirla nconi
Claudiu,

1
@Claudiu anche io.f=lambda _:len(`_`)==len(set(`_`))
Oberon,

Sì, con queste sfide di dimensioni ridotte, tutti convergeranno praticamente sulla stessa cosa. Stavo anche provando lambda n:max(map('n'.count,'n'))<2(le virgolette singole sono backtick), ma è più lungo di due caratteri.
xnor

16

APL (6)

≡∘∪⍨∘⍕

Una delle poche volte in cui lo stile tacito è più breve anche in APL.

Sono 8 caratteri a dargli un nome,

f←≡∘∪⍨∘⍕

ma non è necessario usarlo:

      ≡∘∪⍨∘⍕ 199
0
      ≡∘∪⍨∘⍕ 198
1
      f←≡∘∪⍨∘⍕
      f¨ 198 199 200 201
1 0 0 1
      ≡∘∪⍨∘⍕¨ 198 199 200 201
1 0 0 1

1
Penso che il secondo jot possa essere rimosso per renderlo 5. Sarebbe comunque una funzione valida da solo (anche se richiederebbe il raggruppamento di parentesi per usarlo con ciascun operatore nell'ultimo esempio).
user46915

11

Perl, 19 caratteri

print<>!~/(\d).*\1/

supponendo che l'output possa essere trattato come vero e nessun output può essere trattato come falso, la logica è invertita. Dovresti tornare vero se non c'è ripetizione.
John Dvorak,

@JanDvorak Sembra giusto. Lo aggiusterò.
Tal,

Non-partita operator: <>!~/(\d).*\1/.
primo

@primo Grazie! Tanto da imparare :)
Tal

3
L'input è specificato come un numero intero non negativo, quindi non credo che sia necessario verificarlo. Se davvero non lo fai, puoi passare \da ..
hvd,

9

Rebmμ (10 caratteri)

e? AtsAuqA

Il trucco "mushing" di Rebmu è che non fa distinzione tra maiuscole e minuscole, quindi i personaggi vengono eseguiti insieme. Ogni volta che viene effettuata una transizione tra maiuscole e minuscole , questa si divide nel token successivo. Usando le transizioni anziché un tipo di cosa CamelCase, la scelta unica di iniziare con una corsa maiuscola significa che viene fatta una "parola-set". (Mentre le parole set possono essere utilizzate per altri scopi nella programmazione simbolica, vengono valutate come assegnazioni di default).

Quindi, questo "si risolve" per:

e? a: ts a uq a

Lo spazio è necessario perché una volta che hai iniziato una serie di sequenze di casi alternati, non puoi usare quel trucco per ottenere una parola dopo la prima a meno che non inizi una nuova corsa. Quindi ti e?AtsAuqAavrei presoe? a ts a uq a ... nessun incarico.

(Nota: per quella che potrebbe non essere una ragione particolarmente buona, tendo a preferire ripensare le soluzioni in modo che non ci siano spazi, se il conteggio dei caratteri è uguale. Poiché parentesi, parentesi e stringhe finiscono implicitamente un simbolo ... ci sono spesso una fiera numero di opportunità per questo.)

In ogni caso, quando mappato sul Rebol che abbrevia:

equal? a: to-string a unique a

Inserendo alcune parentesi per ottenere l'essenza dell'ordine di valutazione:

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

Quindi l'operatore di uguaglianza prefisso viene applicato a due argomenti: il primo il risultato dell'assegnazione adella versione stringa di se stesso e il secondo il risultato diunique dell'esecuzione contro quella stringa. Accade così che unique ti restituisca gli elementi nello stesso ordine in cui li hai passati ... così unico di "31214" è "3124" per esempio.

Eseguilo con:

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

Ci sono anche alcune statistiche e informazioni di debug:

>> 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

Se il requisito è che si deve definire una funzione nominata / riutilizzabile, è possibile creare una "funzione A" che accetta implicitamente un parametro chiamato a con a|. (Una funzione B verrebbe creata con b|e prendere un parametro chiamato A quindi uno chiamato B). In modo da aggiungere altri cinque caratteri ... diciamo che si chiama la funzione "f"

Fa|[e? AtsAugA]

"Ridi! Hanno riso di Einstein! O aspettate ... vero? Io ... non lo so."


Pensavo che la lingua fosse pronunciata come Reb moo, ma ora non sono sicuro se dovrebbe essere Rebum mewo Reb mewo qualcos'altro.
Giustino,

2
Dopo aver giocato a Nethack, ho letto Fa|[e? AtsAugA]comeFalse? SomeGibberish
Justin

@Quincunx sdecade davvero [in Nethack?
John Dvorak,

@JanDvorak Ho visto alcune lettere decadere in [dopo qualche tempo
Justin

@Quincunx Sta solo giocando con il logo. Penso che REBmuprobabilmente sia migliore. Ad ogni modo, la barba è stretta ... pizzica. Immagino che ottieni quello per cui paghi.
Dr. Rebmu,

7

FRACTRAN - 53 38 frazioni

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

Utilizza la divisione per contare il numero di occorrenze di ciascuna cifra. Chiamare inserendo n nel registro 2 e impostando il registro da 5 a 1, fornisce l'output nel registro 3 (0 se falso, 1 se vero). Inoltre, assicurati che il resto del programma utilizzi solo registri> 71.


Modifica il 25/12/14: sono passati 7 mesi e da allora abbiamo ottenuto frammenti di stack, quindi eccone uno per testare il codice (usando il mio interprete potrebbe essere migliore qui ).

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>

Sostituisci 142857con un altro numero. L'output dovrebbe essere 3^1se vero, 1 = 3^0se falso. Ci vuole un po 'di tempo per numeri più grandi (beh, questo è FRACTRAN ...).


6

JavaScript - 23 caratteri

Come funzione (ECMAScript 6):

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

O prendendo input da un prompt (25 caratteri)

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

6

C # 73 60 59

Primo golf per me ...

Scrivi una funzione che accetta come input un numero intero non negativo

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

Potrei spogliare un altro personaggio convertendolo uintin int, ma preferisco prendere il compito in modo troppo letterale rispetto al contrario. Eccoci qui ...


1
Alcune opzioni:i => (i + "").Distinct().SequenceEqual(i + "");
NPSF3000,

@ NPSF3000 Grazie! Modificato la mia risposta. Avevo in mente qualcosa del genere, ma vabbè ... mi ero completamente dimenticato di +""chiamare ToString()sotto il cofano.
Num Lock,

Un'interpretazione più letterale di "numero intero non negativo" suggerisce che un numero intero con segno verrà passato, ma non sarà mai negativo.
Shaz,

Beh, immagino che andrà bene allora ...
Num Lock,

Usa C # 6 e puoi usare: bool f (int i) => (i + ""). Distinct (). SequenceEqual (i + ""); (53 byte)
Stephan Schinkel,

5

Ruby (24 byte)

Usa un'espressione regolare per abbinare "un certo carattere, seguito da zero o più caratteri, quindi dallo stesso carattere".

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

Se vengono accettati valori di verità o falsità, anziché letterali trueo false, vengono visualizzati 20 caratteri:

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

5

C (87)

Dal momento che non posso vincere, cercherò l'efficienza.

Codice funzione:

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, e dato che non posso ancora commentare i post di altre persone, vorrei dire che questa è stata una soluzione pulita, anche se imprecisa quando "trabocca".
DreamWarrior,

5

Mathematica, 35 25 caratteri

(27 se la funzione necessita di un nome.)

Unequal@@IntegerDigits@#&

EDIT: salvato 8 personaggi grazie a belisarius!


Unequal @@ IntegerDigits@# &potrei fare, credo
dottor Belisarius

@belisarius oh bello, stavo cercando qualcosa del genere ma non riuscivo a trovarlo (e non pensavo che incatenato avrebbe confrontato elementi non adiacenti). Grazie, questo accorcia molto questo!
Martin Ender

Non devi dargli un nome, giusto? Unequal@@IntegerDigits@#&ha 25 caratteri.
akater

@Akater vero, non riesco a vedere un requisito per il nome nella sfida. Grazie!
Martin Ender,

5

R, 53 51 48 34 byte

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

Provalo online!

Converti in una stringa e dividi. Converti in una tabella di conteggi meno 1, somma e annulla

Ispirato dalla risposta al numero più comune di Alex e dal suggerimento di Hugh.

Un paio salvato, grazie a @plannapus Ancora uno da @Gregor E un paio dal renderlo una funzione anonima

Ora con meravigliosa bontà regex grazie a @ J.Doe. Questo cerca un singolo carattere nel numero che corrisponde a se stesso nella stringa. Il greplcomando restituisce una logica che viene quindi restituita. Le regex in stile Perl sono impostate su True.


Puoi anche convertire in stringa usando paste0invece di toStringe salvando 2 caratteri.
plannapus,

Puoi usare pasteinvece di paste0salvare un altro personaggio.
Gregor,


@J.Doe: ancora meglio! :)
digEmAll

Usato un approccio diverso. 35 byte con regex.
J.Doe,

4

J (9)

Suppone che il valore da testare sia variabile b (so che può essere trasformato in una funzione, ma non ho idea di come . J è confuso. Qualsiasi aiuto su questo è apprezzato) Grazie Marinus!

(-:~.)@":

Verifica se la lunghezza della ripetizione stringa del numero con tutti i duplicati rimossi è uguale alla lunghezza della ripetizione stringa normale.


Per una funzione che puoi fare (-:~.)@":.
Marinus

@marinus Oh wow, è ancora più breve di quanto pensassi. Grazie!
ɐɔıʇǝɥʇuʎs

Ciao, ho trovato e pubblicato una soluzione J più breve: -: ~. &. ":
Galen Ivanov,

4

R ( 70 , 60 , 53 , 52)

Grazie a tutti per i commenti utili! I tuoi commenti sono incorporati nella risposta.

### 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, hai ragione. Mi sono confuso sulla "rappresentazione di base 10".
djhurio,

1
L'uso della tabella e il confronto con 0 anziché duplicati potrebbero salvare alcuni personaggi
Dason,

1
E penso che potresti lasciare il parametro split senza nome. Sono solo sul mio telefono, quindi non posso controllare facilmente, ma credo che sia il secondo parametro di strsplit, quindi potresti usare argomenti posizionali anziché nominati per salvare i personaggi
Dason,

1
E dal momento che prendi già il primo elemento del risultato del strsplitperché non costringere x ad un personaggio usando c(x,"")? f=function(x)all(table(strsplit(c(x,""),"")[[1]])<2)è più corto di 1 carattere :)
plannapus

3

Matematica (20 19)

(22 21 se la funzione ha bisogno di un nome)

Max@DigitCount@#<2&

o

Max@DigitCount@#|1&

dove | è inserito come [Esc] divide [Esc]


Bello. Ho dimenticato che DigitCount esisteva e ho scritto una soluzione basata sulla conversione in stringhe. Il tuo è molto meglio.
Michael Stern,


2

C99, 59 caratteri

a(x){int r=1,f[10]={};for(;x;x/=10)r&=!f[x%10]++;return r;}

C99 non ha int implicito, tecnicamente.
Patrick B

1
Non solo "tecnicamente", è stato rimosso in modo specifico e intenzionale. Questo è un errore di sintassi in C99 e, a parte una diagnostica richiesta, gli errori di sintassi sono nella stessa categoria del comportamento indefinito (esplicitamente vietato nella domanda): se un'implementazione lo accetta, lo standard non richiede alcun requisito sul comportamento del programma.
hvd,

2

Groovy (36 caratteri)

f={s="$it" as List;s==s.unique(!1)}

Testato usando:

println f(args[0].toInteger())

'false' può essere giocato tramite '1 == 0' o forse qualcosa di più intelligente. Buona risposta
Michael Easter,

@MichaelEaster 0>1 is shorter.
pastebin.com slash 0mr8spkT

1
@ace Yes, though !1 works too...
Michael Easter

@ace, MichaelEaster, thx for the help :-)
Will Lp

@WillP as suggested by MichaelEaster, use !1 instead.
pastebin.com slash 0mr8spkT

2

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
Flonk

You didnt use pl... main = interact $ show . ap (==) nub . show
kazagistar


2

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))

1
You could use anyDuplicated rather than sum and duplicated for 2 more
MickyT

2

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...
pastebin.com slash 0mr8spkT

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

Please see my comment in the edit summary.
2501

I voted to reject the edit, but I agree that the counts look wrong. I make them 67 and 63 (61).
Peter Taylor

My edit was rejected by other users. Please re-evaluate it.
2501


1

Javascript 73 chars

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

1

Befunge 98, 17 bytes

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

~:1g1`j@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.



1

Perl 6 (19 bytes)

{.comb.uniq==.comb}

.comb splits a string into characters (for example, 42.comb gives "4", "2"). .uniq removes all non-unique characters. .comb characters in string (originally I used .chars, but .comb is shorter). == converts lists into number of elements in it, and compares the numbers. When . is used without object before, $_ which is default function parameter is assumed. {} are function literals.


1

C, 76

This is no where near winning, but I'll post it anyway just to show an alternative approach.

c;i;a[99];main(){while(~(c=getchar()))a[c]++;for(;i<99;)a[i++]>1&&puts("");}

Prints a new line if false, prints nothing if true.


This program has an undefined behavior. The correct signatures for main are int main(int, char **) or int main(void). int main(int) is not valid.
Konrad Borowski

@xfix I assume main() is ok then?
pastebin.com slash 0mr8spkT

Yes, it's fine. It means the same thing as main(void) (when used in definition, in declaration it declares a function with unknown parameter list).
Konrad Borowski

1

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
Digital Trauma

@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

Ah I was using bash. So I guess its longer if you want POSIX conformance.
Digital Trauma

1

Java ( 131 59 57)

57 characters:

removed ^ and $ as @n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ suggested

boolean u(int n){return !(n+"").matches(".*(.).*\\1.*");}

59 characters (works also with negative numbers!):

boolean u(int n){return !(n+"").matches("^.*(.).*\\1.*$");}

79 78 characters (thanks @n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ ):

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;}

with comments:

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()
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

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.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

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.
Kevin Cruijssen
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.