Get a random n digit number with distinct digits and first not a 0

22

4

I read this question and thought it would make a nice challenge.

Task

Give an input 0<n<10 generate a random number with

  • exactly n digits
  • the first not a 0
    • so f(n)>10**(n-1)-1
  • distinct digits

Winning criteria

This is so shortest code wins.

Random

I mean evenly distributed random. So from the view of the program each possible number has the same chance. If the language you're writing in has a weird random number generator, it's okay to use that one.

Example

The list of values to randomly select from for n=2 is:

[10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98]

Roman Gräf

Posted 2017-04-24T19:49:07.350

Reputation: 2 915

4

Requiring randomness without specifying a distribution should be avoided.

– flawr – 2017-04-24T19:50:58.237

return as an integer, not a string, yes? – Giuseppe – 2017-04-24T20:46:53.087

@Giuseppe generate a random number – mbomb007 – 2017-04-24T20:57:24.063

When you say distinct digits you mean a number like 375 is acceptable but 337 is not? – Albert Renshaw – 2017-04-24T23:43:36.387

Is pseudo-random allowed? For example I can use current UTC time as a "seed" for a scrambling function so it's not true random because the output can be easily predicted but if you run the program multiple times (seconds apart each time) the output will differ. I guess what I'm asking is, does output have to be RANDOM or just non-static – Albert Renshaw – 2017-04-24T23:50:43.393

4

I think of this every single time someone makes a random number question https://xkcd.com/221/

– Thunda – 2017-04-25T04:56:16.690

In chat recently it came up that this challenge is a bit unclear at the lower end. What output is expected for n=0? Is 0 a valid output for n=1? It'd be easiest to set the minimum n to 2 to avoid having to define these corner cases (especially as they may cost quite a few bytes for many of the solutions). – None – 2017-04-25T13:17:51.010

1@ais523 "Give an input 0<n<10 generate a random number with" – cleblanc – 2017-04-25T13:46:29.420

I agree with ais523, though. I'd like to know if we can output zero for n=1. My answer currently can. – mbomb007 – 2017-04-25T14:11:40.133

@ais523 no you don't have to handle n=0. In the Task section it says 0<n<10. no 0 isn't a valid output for n=1 since 10**(1-1)-1=0 and 0 is not greater than 0 – Roman Gräf – 2017-04-25T14:45:49.427

<joke> Is it acceptabel if the first number is a 0 if it's only 10% of the cases? </joke> – Martijn – 2017-04-26T09:01:43.417

Answers

17

Python 2, 77 bytes

from random import*
r=range(10)
while[1]>r:shuffle(r)
print`r`[1:input()*3:3]

Try it online!

Shuffles the list of 10 digits until it doesn't start with 0, then makes a number with the first n digits listed.

xnor

Posted 2017-04-24T19:49:07.350

Reputation: 115 687

Definitely runs faster and with less memory for input of 9 or 10. – mbomb007 – 2017-04-24T21:15:12.933

Neat solution! Could you explain how the [1::3] works to convert it from a list to a string? I've never seen that before. – Julian Wolf – 2017-04-24T21:15:31.947

@JulianWolf It only works if each element of the list is the same length. It actually takes the string representation of the list, then slices it taking every 3rd character after skipping the first [. – mbomb007 – 2017-04-24T21:16:13.920

@JulianWolf [1::3] gets the character at index 1, then every third. For [1, 2, 3], that gives 123, skipping the brackets, commas, and spaces. – Dennis – 2017-04-24T21:16:42.743

Shoot, okay—that makes sense. I was forgetting that [1, 2, 3] had already been stringified and that commas and spaces needed skipping. Thanks! – Julian Wolf – 2017-04-24T21:53:51.867

10

Brachylog, 9 10 bytes

{~lℕ₁≜≠}ᶠṛ

Try it online!

As usual for Brachylog, this is a function submission. The TIO link above has been given a command-line argument to make the function into a full program.

I had to add an extra byte from the first version of this, changing to ℕ₁, to disallow the output 0 (something that's now been clarified).

Explanation

{~lℕ₁≜≠}ᶠṛ
{      }ᶠṛ  Pick a random value with these properties:
 ~l           it has length equal to the input;
   ℕ₁         it's a positive integer;
     ≜        it's a specific value (not a constraint);
      ≠       all its elements (digits in this case) are different.

Fairly inefficient, because the interpreter generates a list of all possible values and then picks one at random (that's what ᶠṛ means; Brachylog didn't have a "pick a random solution" option at the time this question was asked).

Some comments on the labelization here: if the is omitted, the section within the braces only produces one value, a constraint representing numbers with the property we want; picking a random result therefore gives us the constraint, and the interpreter outputs the minimum absolute value that meets the constraint (1, 10, 102, 1023, 10234, etc.), which is not what we want. We thus have to force it to construct the list via an explicit labelization.

Most Prolog implementations I've seen have a builtin to find a random result matching a constraint, but typically not with uniform probability; Brachylog didn't have one, though (one got added in response to this challenge, but obviously I can't use it due to loophole rules). If it did, and if it happened to give uniform probability on this problem, this program would just be ~lℕ₁≠ followed by that builtin, for a likely length of 6 bytes.

Brachylog, 8 bytes, in collaboration with @Fatalize

~lℕ₁≠≜ᶠṛ

Try it online!

This is the sort of genius low-level trick that only makes sense with the way Prolog does things, and doesn't make much sense when described mathematically.

As before, ~lℕ₁≠ builds up a value that describes a constraint ("length equal to the input, natural number, all elements different"). Then ≜ᶠ generates all possible values that meet the constraint. The point here is that with Brachylog's evaluation sequence, no actual choices are made until the appears, so the "find all solutions" operation need apply to nothing but the "specific value that fulfils a constraint" operation . That means there's no need for a {…} to select its scope, saving 2 bytes.

user62131

Posted 2017-04-24T19:49:07.350

Reputation:

I was going to post a solution with ≜₁ before I realized that it was added because of this challenge – Unrelated String – 2019-05-16T10:12:29.967

8

Jelly, 9 bytes

⁵*ṖQL$€MX

Try it online! (won't work at TIO for n > 6 due to the inefficiency of the implementation)

or an alternative implementation of the same thing:

⁵*ṖQL$ÐṀX

How?

This is pretty sneaky, and very inefficient! Jelly does some useful things implicitly when an atom expects a list but receives an integer (this is by design).
This code uses a couple of these useful implicit actions:

  • The monadic atom , "pop", when called with an integer input implicitly makes a range from which to pop, so an input of n first makes [1, 2, ..., n], then pops, yielding [1, 2, ..., n-1].

  • The monadic atom Q, "de-duplicate" or "unique", when called with an integer input implicitly makes a decimal list to de-duplicate, so an input of n where:
    n = dk-1×10k-1 + dk-2×10k-2 + ... + d1×10 + d0
    first makes
    [dk-1, dk-2, ... ,d1, d0]
    and then yields the unique values by first appearance.
    So, for example, n = 5835518 would yield [5, 8, 3, 1].

Furthermore the monadic atom M, "maximal element indexes", returns the indexes of the maximal items from a list, this saves two bytes over the far more obvious alternative of testing for equality with the input and finding truthy indexes, ⁵*ṖQL$€=⁸TX, or ⁵*ṖðQL⁼ð€TX

⁵*ṖQL$€MX - Main link: n                       e.g. 2
⁵         - literal 10
 *        - exponentiate: 10^n                      100
  Ṗ       - pop (make range 1 to 10^n, then pop)    [1  ,2  ,...,21   ,22 ,23   ,...,97   ,98   ,99]
     $€   - last two links as a monad for €ach:
   Q      -   unique (makes a decimal list first)   [[1],[2],...,[2,1],[2],[2,3],...,[9,7],[9,8],[9]]
    L     -   length                                [1  ,1  ,...,2    ,1  ,2    ,...,2    ,2    ,1  ]
       M  - indexes of maximal elements             [        ...,21       ,23,   ...,97   ,98       ]
          -                                         - i.e. all n-digit numbers with n-distinct digits.
        X - pick a random element from that list

This is all quite quite inefficient, both in time and memory: first a list of 10n integers is made and one is discarded, then for each of these a list of n integers (not some fancy 4-bit object or enum) is made and then de-duplicated. This de-duplication has a completely list-based implementation (no sets, sorted-sets, or dictionaries are involved under-the-hood, each digit is checked for existence in the list that eventually gets output).
Offline n = 7 uses ~0.5GB and takes ~25 seconds, while n = 8 uses ~4GB and takes ~5 minutes - I have not bothered running n = 9 as I only have 16GB ram (I guess it would take ~45 minutes).

The alternative implementation just uses the built-in ÐṀ quick to filter-keep minimal (which here just adds a little overhead in management for the same byte-count).

Jonathan Allan

Posted 2017-04-24T19:49:07.350

Reputation: 67 804

Oh wow. I was trying something very like this but missed the trick of storing the values to return in the list indexes (via suitably padding out the list), rather than trying to store them separately. This is a trick that comes in useful in Jelly fairly often and I always seem to miss it. – None – 2017-04-25T03:28:51.037

7

JavaScript (ES6), 72 71 70 69 bytes

f=(x,y="")=>x?!y.match(z=Math.random()*10|0)&&y|z?f(x-1,y+z):f(x,y):y

This is a recursive function that takes in the number of digits x. The second parameter y, initially set to the empty string, keeps track of the number as we generate it digit by digit.

First we generate a random digit z with Math.random()*10|0. Now, we want to check that the y does not contain z, and that y and z are not both 0.

We can calculate the first condition with !y.match(z). y.match(z) returns an array (always truthy) if y contains z, null (falsy) otherwise; the ! converts this to a boolean and inverts it.

The second condition is checked with y|z. Although y is a string, JS implicitly converts it to an integer when using |. This is a positive integer if y already contains digits, 0 otherwise. The net result is that y|z returns 0 iff y is empty and z is 0, or a positive integer otherwise.

If both of these conditions are true, then we append the digit to y, decrement x, and start the process over again. Otherwise, we simply return to the beginning and hope that the next random digit works. When x reaches 0, we simply return the empty string to end the recursion.


Previous version:

f=(x,y)=>x?~y>>(z=Math.random()*10|0)&1&&y|z?z+f(x-1,y|1<<z):f(x,y):""

This is a recursive function that takes in the number of digits. The initially undefined second parameter, y, is a 10-bit lookup table telling us which digits we already have, conveniently stored as an integer.

First we generate a random digit z with Math.random()*10|0. Now, we want to check that the z'th least significant bit of y is not set, and that y and z are not both 0.

We can calculate the first condition with ~y>>z&1; invert y, shift it z bits to the right, and take only the least significant bit. This gives 1 if we have not yet generated the digit in question, or 0 otherwise.

The second condition was initially pretty difficult to figure out (I tried using y/z at first to generate NaN if they're both 0), but at some point I realized that simply y|z would do the trick. The result is 0 iff both y and z are 0; a positive integer otherwise.

If both of these conditions are true (~y>>z&1&&y|z), then we generate the rest of the number and prepend z. The rest of the number is generated by calling the function again with x-1 and y|1<<z (y, but with the bit at index z set to 1). When x reaches 0, we simply return the empty string to end the recursion.

ETHproductions

Posted 2017-04-24T19:49:07.350

Reputation: 47 880

7

Jelly, 11 bytes

9Xœ|⁵ḶẊ¤ḣ¹Ḍ

Try it online!

How it works

9Xœ|⁵ḶẊ¤ḣ¹Ḍ  Main link. Argument: n

9            Set the return value to 9.
 X           Pick; pseudo-randomly select an integer from [1, ..., 9].
       ¤     Combine the three preceding links into a niladic chain.
    ⁵          Yield 10.
     Ḷ         Unlength; yield [0, ..., 9].
      Ẋ        Shuffle; pseudo-randomly select a permutation of [0, ..., 9].
  œ|         Multiset OR; prepend the selected integer to the selected permutation
             and remove the second occurrence of the first element.
         ¹   Identity; yield n.
        ḣ    Head; keep the first n digits of the permutation.
          Ḍ  Undecimal; convert from base 10 to integer.

Dennis

Posted 2017-04-24T19:49:07.350

Reputation: 196 637

That's a very clever way to remove the duplicate... – Leaky Nun – 2017-04-25T03:43:21.713

5

Python 2, 89 81 80 bytes

from random import*
lambda n:choice([i for i in range(10**n)if`set(`i`)`[5*n:]])

Try it online

mbomb007

Posted 2017-04-24T19:49:07.350

Reputation: 21 944

I don't think you need a start value for the range. – Dennis – 2017-04-24T21:21:05.940

Nice! That'll slow it down. :D Too bad I can't use a generator instead of a list. – mbomb007 – 2017-04-24T21:22:43.170

Only by 11%. Drop in a bucket for code golf. – Dennis – 2017-04-24T21:26:09.940

Yeah, I should use 99**n, just to be sure I get them all. :D – mbomb007 – 2017-04-24T21:27:10.600

I looked at doing it this way too, but got 80, by using if`set(`i`)`[5*n:]]. – Jonathan Allan – 2017-04-26T05:38:25.107

5

R, 45 Bytes

k=0
i=scan()
while(!k[1])k=sample(0:9)[1:i]
k

Neil

Posted 2017-04-24T19:49:07.350

Reputation: 2 417

I think you can just set k=0 since it's an implicit vector of length one, and you can use i=scan() to take input from stdin as a number.

I'm also not sure that a list of digits is a "correct" submission, but I'm not the judge. – Giuseppe – 2017-04-25T14:47:12.253

@Giuseppe Thanks for the input, updated both of your suggestion (on both posts), thanks. – Neil – 2017-04-25T16:08:48.750

Would while(!k[1]) work to save 2 bytes? – BLT – 2017-04-26T19:37:16.260

@BLT Updated, thanks. – Neil – 2017-04-26T21:08:04.143

5

ClojureScript, 81 79 bytes

#(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))

This is an anonymous function, so you have to use it like this:

(#(...) {arguments})

Where you replace {arguments} with your arguments.

You can try the code here (ClojureScript REPL).

Thanks @cliffroot for shaving off 2 bytes!


Expanded code:

(defn random-digits [n]
  (let [num-vector
        (subvec
          (shuffle (range 10))
          0 n)]
    (if (= (num-vector 0) 0)
      (recur n)
      (int (apply str num-vector)))))

Explanation:

I'm going to go through the lines one by one, using an example input of 8.


(defn random-digits [n] ...)

Pretty simple, this defines the function random-digits with one argument, called n. In my answer I used an anonymous function (#(...)), to save bytes.


(let [num-vector ...] ...)

Let's examine inside the let, from inside out:

(shuffle (range 10))

In ClojureScript (and Clojure), (range n) is similar to Python's range(n): it gives you a list with every number from 0 to n - 1 (9 in this case).

shuffle takes a list, and returns a vector (which is slightly different from a list) with all of its elements shuffled. So, using our example, we get something like this:

[1 0 8 3 6 7 9 2 4 5]

(subvec {see above} 0 n)

(subvec vector start end) takes a vector (only a vector), and returns a vector which has all the elements from index start to end. In this case, we're taking elements from the 0th element to the argument given to random-digits. If we apply that to our example, we get:

[1 0 8 3 6 7 9 2]

(if (= (num-vector 0) 0)
  (recur n)
  (int (apply str num-vector)))

This if statement checks if the first element of num-vector is a 0.

If it is 0, then we call the function again, with the argument n, using recur.

If it isn't 0:


(int (apply str num-vector))

(apply function list) takes a list, and spits them into the function as arguments. For example:

(apply + [2 3 4])

Turns into:

(+ 2 3 4)

Which equals 9.

(str items) turns every item in items into a string, and then concatenates them. int converts anything to an integer. So if we apply this to our example, we get:

   (int (apply str [1 0 8 3 6 7 9 2]))
=> (int (str 1 0 8 3 6 7 9 2))
=> (int "10836792")
=> 10836792

Which is our final answer.

clismique

Posted 2017-04-24T19:49:07.350

Reputation: 6 600

2Gotta love ClojureScript for allowing (int string) instead of (Integer/parseInt string) :) – cliffroot – 2017-04-25T07:52:32.293

1@cliffroot I mean, you can do read-string in Clojure, but it's not much better... – clismique – 2017-04-25T07:53:45.727

2 bytes saved #(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a)))) moves apply str part to the end, allows to compare to 0 instead of \0 and uses subvec instead of take allows to use vector as a function and thus to remove first – cliffroot – 2017-04-25T08:30:47.673

@cliffroot Huh, did not know that shuffle turned the collection into a vec. Thanks! Will have to write a new explanation, though... – clismique – 2017-04-25T10:03:39.650

3

Bash + GNU utils, 46

seq 1e$[$1-1] 1e$1|egrep -v '(.).*\1'|shuf -n1

Try it online.

This takes a long time for larger n - about 30s for n=7, and increasing 10 times for each increment, so probably 8-9 hours for n=10.

Digital Trauma

Posted 2017-04-24T19:49:07.350

Reputation: 64 644

per the question, n=10 doesn't need to even work, much less be fast – ysth – 2017-04-25T11:45:36.383

3

Java 7, 150 147 145 134 bytes

String c(int n){String r="";for(int l,x;(l=r.length())<n;)if(l<1&(x=(int)(Math.random()*10))>0|(l>0&!r.contains(""+x)))r+=x;return r;}

-2 bytes thanks to @TheLethalCoder

(old) Explanation:

String c(int n){                           // Method with integer parameter and String return-type
  String r="";                             //  Result-String
  for(int l=0,x;l<n;l=r.length()){         //  Loop until the length of the result-String is equal to the parameter integer
    x=new java.util.Random().nextInt(10);  //   Random digit
    if((l<1&x>0)                           //   If the length is zero and the random digit is not zero
       |(l>0&!r.contains(""+x)))           //     or the length is at least 1, and the result-String does not contain this random digit yet
      r+=x;                                //    Append the random digit to the result-String
  }                                        //  End of for-loop
  return r;                                //  Return result-String
}                                          // End of method

Test code:

Try it here.

class M{
  String c(int n){String r="";for(int l,x;(l=r.length())<n;)if(l<1&(x=(int)(Math.random()*10))>0|(l>0&!r.contains(""+x)))r+=x;return r;}

  public static void main(String[] a){
    M m = new M();
    System.out.println(m.c(4));
    System.out.println(m.c(10));
  }
}

Example output:

7194
8672953041

Kevin Cruijssen

Posted 2017-04-24T19:49:07.350

Reputation: 67 575

Can you not use a lambda expression here? i.e. n->... or is that Java 8+?

– TheLethalCoder – 2017-04-25T09:54:20.367

1You can also borrow the trick I just used in my answer, set the length in the comparison check i.e. for(int l,x;(l=r.length())<n;) and you should save a byte. – TheLethalCoder – 2017-04-25T09:59:02.840

1@TheLethalCoder Ah of course, thanks. Great teamwork! ;) And yes, n->... is Java 8. Personally I prefer to codegolf in Java 7, even though 8 is always shorter. – Kevin Cruijssen – 2017-04-25T11:35:50.110

2

PHP, 67 Bytes

Online Version

All versions based of shuffle the digits from 0-9

for($a=range(0,9);!$a[0];)shuffle($a);for(;$i<$argn;)echo$a[+$i++];

71 Bytes

for($s="0123456789";!$s[0];)$s=str_shuffle($s);echo substr($s,0,$argn);

73 Bytes

for($a=range(0,9);!$a[0];)shuffle($a);echo join(array_slice($a,0,$argn));

Jörg Hülsermann

Posted 2017-04-24T19:49:07.350

Reputation: 13 026

2

Perl 6, 44 bytes

{(->{+[~] (^10).pick($_)}...*>9 x$_-1).tail}

Try it

Expanded:

{  # bare block with implicit parameter 「$_」
  (

    ->{  # pointy block lambda with no parameters

      +                # turn the following into a numeric
      [~]              # concatenate the following

        (^10).pick($_) # grab $_ digits at random from 0..9
    }

    ...                # keep doing that until

    * > 9 x $_-1       # one of them is big enough

  ).tail # return the last one (only valid one)
}

Brad Gilbert b2gills

Posted 2017-04-24T19:49:07.350

Reputation: 12 713

2

MATL, 15 bytes

`4Y2GZr1)48=]8M

Try it at MATL Online!

Explanation

`        % Do...while
  4Y2    %   Push predefined literal '0123456789'
  G      %   Push input n
  Zr     %   Random sample of n unique characters from that string
  1)     %   Pick the first
  48=    %   Is it 48? This is the loop condition
]        % End. If top of the stack evaluates to true: next iteration
8M       % Push the latest random sample. Implicitly display

Luis Mendo

Posted 2017-04-24T19:49:07.350

Reputation: 87 464

2

Jelly, 12 bytes

9×!X+!Œ?’ḣƓḌ

Currently one byte behind my other Jelly answer, but I really like this one.

Try it online!

How it works

9×!X+!Œ?’ḣƓḌ  Main link. No arguments.

9             Set the argument and the return value to 9.
  !           Yield 9!
 ×            Compute 9 × 9!.
   X          Pick; pseudo-randomly select an integer j from [1, ..., 9 × 9!].
     !        Yield 9!
    +         Compute k := j + 9!.
              The result will belong to [9! + 1, 10!].
      Œ?      Get the permutation P of R := [1, ..., r], with minimal r, such that
              P is the lexicographically k-th permutation of R.
              Since k belongs to [9! + 1, 10!], r = 10 and this generates a per-
              mutation between [2,1,3,4,5,6,7,8,9,10] and [10,9,8,7,6,5,4,3,2,1].
        ’     Subtract 1 from all integers in P.
          Ɠ   Read an integer n from STDIN and yield it.
         ḣ    Head; keep the first n digits of the permutation.
           Ḍ  Undecimal; convert from base 10 to integer.

Dennis

Posted 2017-04-24T19:49:07.350

Reputation: 196 637

2

APL (Dyalog), 27 19 17 bytes

Requires ⎕IO←0 which is default on many systems.

10⊥⊢↑{?⍨10}⍣{×⊃⍺}

Try it online!

Shuffles the digits until valid:

10⊥ decode from base-10 digits to regular number,

 the n

 first elements of

{}⍣{} repeating the function…
?⍨10 shuffle the first ten positive integers
until…
⊃⍺ the first digit of the last attempt
× is positive

Adám

Posted 2017-04-24T19:49:07.350

Reputation: 37 779

1

Python 2, 100 93 92 90 bytes

Thanks to @mbomb007 for shaving off 2 bytes

from random import*
def f(n):k=randint(10**~-n,10**n-1);return(n==len(set(`k`)))*k or f(n)

Tries numbers in the required until one is found with unique digits. I'll bet there's a much cleaner way to do this, but none's coming to mind.

Julian Wolf

Posted 2017-04-24T19:49:07.350

Reputation: 1 139

return(n==len(set(\k`)))*k or f(n)`. Try it online – mbomb007 – 2017-04-24T21:19:24.337

1

Pyth, 11 bytes

jk<{+OS9.ST
jk<{+OS9.STQ implicit Q

       9     9
      S      [1,2,3,4,5,6,7,8,9]
     O       random element

          T  10
        .S   random permutation of [0,1,2,3,4,5,6,7,8,9]

    +        add the results from the previous two paragraphs together
   {         deduplicate
  <        Q first (input) elements
jk           join by empty string

Uses the same algorithm as Dennis' answer.

Try it online!

Leaky Nun

Posted 2017-04-24T19:49:07.350

Reputation: 45 011

1

Perl, 48 bytes

1until$_=1+int rand 10**$n-1,/.{$n}/&&!/(.).*\1/

Explanation:

Repeatedly generate random integers from 1 to 10**$n-1, rejecting them until there is one of the correct length (so at least 10**($n-1)) with no repeated digits.

ysth

Posted 2017-04-24T19:49:07.350

Reputation: 111

1

C#, 127 132 128 126 125 bytes

n=>{var s="";for(int l,r;(l=s.Length)<n;)if((l<1&(r=new System.Random().Next(10))>0)|(l>0&!s.Contains(r+"")))s+=r;return s;};

Try It Online!

Borrowed the idea from @KevinCruijssen's answer to initialise the random, r, in the if statement to save 2 bytes.

Pretty sure this can be golfed further but I don't have time at the moment.


Old version using a while loop:

n=>{var s="";while(s.Length<n){int r=new System.Random().Next(10);if(s.Length<1&r>0)s+=r;else if(!s.Contains(r+""))s+=r;}return s;};

TheLethalCoder

Posted 2017-04-24T19:49:07.350

Reputation: 6 930

I don't think this is correct. Let's say the first random integer is 0, it would first try if(s.Length<1&r>0) which is false, but then it will do if(!s.Contains(r+"")) which is true and still append "0" to s as first digit. – Kevin Cruijssen – 2017-04-25T08:38:17.910

@KevinCruijssen Fixed and golfed further – TheLethalCoder – 2017-04-25T08:48:50.773

I was about to post a Java answer which is exactly the same as your new answer. :) The only difference (and you can also golf this), is int l=0,r; instead of int l=0,r=0;. So it becomes n=>{var s="";for(int l=0,r;l<n;l=s.Length){r=new System.Random().Next(10)if((l<1&r>0)|(l>0&!s.Contains(r+"")))s+=r;}return s;}; (127 bytes) – Kevin Cruijssen – 2017-04-25T09:21:05.913

@KevinCruijssen I can only seem to get that at 128 bytes still, not sure why. And if you haven't already feel free to post your answer :) – TheLethalCoder – 2017-04-25T09:29:29.763

1@KevinCruijssen Ah I've worked it out, in your example you don't end the .Next(10)... with a ;. So no further improvements there, but good idea. – TheLethalCoder – 2017-04-25T09:31:29.230

1I have just posted it. And oops, you're right I missed that semi-colon.. You can still golf it like this though: n=>{var s="";for(int l=0,r;l<n;l=s.Length)if((l<1&(r=new System.Random().Next(10))>0)|(l>0&!s.Contains(r+"")))r+=x;return s;}; :) – Kevin Cruijssen – 2017-04-25T09:34:54.217

1@KevinCruijssen I just borrowed the idea from your answer as you was writing that comment! Nice improvement thanks – TheLethalCoder – 2017-04-25T09:37:18.250

Let us continue this discussion in chat.

– TheLethalCoder – 2017-04-26T09:23:19.417

1

Batch, 156 bytes

@set/af=9,r=x=0
@for /l %%i in (1,1,%1)do @call:c
@echo %r%
@exit/b
:c
@set/a"d=9-%random%%%f,e=x>>d&1
@if %e%==1 goto c
@set/a"r=r*10+d,f=10,x|=1<<d

x maintains a bitmask of used digits. f indicates the number of available digits (counting down from 9). Random digits are generated until an unused digit is found. n=10 could be supported for 165 bytes:

@set/af=9,r=x=0
@for /l %%i in (1,1,%1)do @call:c
@echo %r:~1%
@exit/b
:c
@set/a"d=9-%random%%%f,e=x>>d&1
@if %e%==1 goto c
@set r=%r%%d%
@set/a"f=10,x|=1<<d

(r contains an extra leading zero because it's golfier that way.) Previous approach for 165 bytes special-cased the first digit, and also happened to work with n=10 (the numeric version actually took 166 bytes!):

@set/ar=%random%%%9+1,x=0
@for /l %%i in (2,1,%1)do @set/a"x|=1<<d"&call:c
@echo %r%
@exit/b
:c
@set/a"d=%random%%%10,e=x>>d&1
@if %e%==1 goto c
@set r=%r%%d%

Original approach for 170 bytes also worked for n=10:

@set/ar=%random%%%9+1
@for /l %%i in (2,1,%1)do @call:c
@echo %r%
@exit/b
:c
@set/ad=%random%%%10
@call set s=%%r:%d%=%%
@if not "%s%"=="%r%" goto c
@set r=%r%%d%

Uses string manipulation to detect duplicate digits.

Neil

Posted 2017-04-24T19:49:07.350

Reputation: 95 035

1

C (gcc), 123 122 100 95 104 103 99 97 bytes

This one generating an actual random number

j;f(n){for(int i,k=n,s[10]={j=0};n;s[i+=i?0:k==n]=!s[i]?j+=i*pow(10,--n):1)i=rand()%10;return j;}

Try it online!

C (gcc), 87 85 bytes

Here it is printing a string of digits.

f(n){for(int i,k=n,s[10]={0};n;s[i+=i?0:k==n]=!s[i]?--n,putchar(48+i):1)i=rand()%10;}

Try it online!

cleblanc

Posted 2017-04-24T19:49:07.350

Reputation: 3 360

1

Bash, 66 bytes

a=0;while [[ $a == 0* ]];do a=`shuf -i0-9 -n$1|xargs`;done;echo $a

Try it online!

Straight forward, usues shuf, xargs is used to join lines and continues to try while the combination starts with 0.

Cant beat 46 char from other answer but thus is fast!

marcosm

Posted 2017-04-24T19:49:07.350

Reputation: 986

1

PHP, 65 63 bytes

while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x;

takes input from STDIN; run with -nR.

create random number between 1 and 10^N inclusive;
repeat while count of distinct characters is < N.

Titus

Posted 2017-04-24T19:49:07.350

Reputation: 13 814

1while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x; -2 Bytes – Jörg Hülsermann – 2017-04-27T01:56:50.737

1

Pyth, 15 28 bytes

=+YhO9VtQ#KOTI!hxYK=+YKB;jkY

Try it here

Maria

Posted 2017-04-24T19:49:07.350

Reputation: 644

1Welcome to PPCG, and great job using a golfing language right off the bat :-) I see 2 small issues: 1) it seems that the second digit is always 0, so I think you'll want to change ^TttQ to ^TtQ (-1 byte, bonus!). 2) all digits in the output must unique, so you'll have to force that to happen somehow. – ETHproductions – 2017-04-25T19:38:14.420

@ETHproductions Arg!! Thanks for pointing that out. I've fixed it. – Maria – 2017-04-25T20:16:57.933

0

Mathematica 65 60 Bytes

0For[a=11,Max@DigitCount@a>1,a=RandomInteger[10^{#-1,#}]]+a&

Here is a faster version but adds 9 bytes:

FromDigits@Join[f=(s=RandomSample)[r=Range@9,1],s[r/.f[[1]]->0,#-1]]&

Kelly Lowder

Posted 2017-04-24T19:49:07.350

Reputation: 3 225

0

C, 96 93 bytes

f(n){char d[11],i=0,r;for(;i++^10;d[i-1]=d[r=rand()%i],d[r]=47+i);*d^48?d[n]=0,puts(d):f(n);}

Fisher-Yates shuffle initialization until the first digit isn't zero.

Is uniform, assuming rand()%i is uniform. (Since for most i RAND_MAX/i leaves a small remainder, there is a very small bias. This bias grows smaller as RAND_MAX grows larger.)

See it work online.

See it generate correct numbers for when n equals 2, as shown in the question.

2501

Posted 2017-04-24T19:49:07.350

Reputation: 748

0

Java 9 JShell, 86 bytes

n->new Random().longs(0,10).limit(n-1).reduce(new Random().nextInt(9)+1,(a,b)->a*10+b)

Try it online!

Note: I'm not counting the imports as those packages are imported by default in JShell, but there's no Try-it-online link that I know of for JShell, so I've provided one for Java 9 with header and footer code to make it work in that context. In JShell you can just do:

jshell> Function<Integer,Long> f =
   ...> n->new Random().longs(0,10).limit(n-1).reduce(new Random().nextInt(9)+1,(a,b)->a*10+b)
f ==> $Lambda$27/633070006@5702b3b1

And then:

jshell> f.apply(6)
$26 ==> 746202

How it works:

We define a function from Integer to Long and create an infinite stream of random longs in the range from 0-9, limit it to the first n-1 items, then reduce it with a random int from 1-9 as the initial value and a function that multiplies the value by 10 and adds the next value from the stream.

I used longs so this should work for up to about 18 digits (n = 18).

David Conrad

Posted 2017-04-24T19:49:07.350

Reputation: 1 037

0

Ruby, 53 52 bytes

Shuffle until the first digit is not 0, then combine the digits and convert to an integer.

->n{a=*0..9;a.shuffle!while a[0]==0;eval a[0,n]*''}

Try it online!

Value Ink

Posted 2017-04-24T19:49:07.350

Reputation: 10 608

0

Axiom, 191 bytes

g(a:NNI):Complex INT==(a<1 or a>9=>%i;r:List NNI:=[];b:=a;repeat(a=0=>break;d:=random()$INT rem 10;a=b and d=0=>0;~member?(d,r)=>(a:=a-1;r:=cons(d,r)));reduce(+,[r.i*10^(i-1)for i in 1..#r]))

ungolf it, test result

-- Return one number of 'a' different random digits if 0<a<10
f(a:NNI):Complex INT==
    a<1 or a>9=>%i
    r:List NNI:=[];b:=a
    repeat
       a=0=>break
       d:=random()$INT rem 10
       a=b and d=0  =>0
       ~member?(d,r)=>(a:=a-1;r:=cons(d,r))
    reduce(+,[r.i*10^(i-1)for i in 1..#r])

(4) -> [[i,g(i)] for i in 0..10]
   (4)
   [[0,%i], [1,9], [2,76], [3,135], [4,6810], [5,48675], [6,415768],
    [7,7461539], [8,98421537], [9,825046739], [10,%i]]
                                          Type: List List Complex Integer
(5) -> [[i,g(i)] for i in [3,3,3,3,3,3,3,3,3]]
   (5)
   [[3,653],[3,128],[3,254],[3,268],[3,914],[3,594],[3,276],[3,240],[3,398]]

RosLuP

Posted 2017-04-24T19:49:07.350

Reputation: 3 036

0

Jellyfish, 17 bytes

p
d^u ?
 j?r10
10

Try it online!

Fork of Dennis' Jelly answer.

Leaky Nun

Posted 2017-04-24T19:49:07.350

Reputation: 45 011

0

C, 77 bytes

r;a;n;d(i){for(a=n=0;r=rand()%10,i-=n&1<<r?0:!!(a=a*10+r);n|=1<<r);return a;}

See it work online.

See it generate correct numbers for when n equals 2, as shown in the question.

2501

Posted 2017-04-24T19:49:07.350

Reputation: 748