Dapatkan nomor n digit acak dengan digit berbeda dan pertama bukan 0


22

Saya membaca pertanyaan ini dan berpikir itu akan menjadi tantangan yang menyenangkan.

Tugas

Berikan input 0<n<10dengan angka acak

  • tepatnya n digit
  • yang pertama bukan 0
    • begitu f(n)>10**(n-1)-1
  • digit berbeda

Kriteria menang

Ini adalah sehingga kode terpendek menang.

Acak

Maksud saya merata secara acak. Jadi dari pandangan program, setiap angka yang mungkin memiliki peluang yang sama. Jika bahasa yang Anda gunakan memiliki penghasil angka acak yang aneh, tidak masalah untuk menggunakannya.

Contoh

Daftar nilai yang dipilih secara acak n=2adalah:

[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]
code-golf  number  random  grid  game  king-of-the-hill  javascript  code-golf  arithmetic  statistics  code-golf  math  code-golf  math  code-golf  string  palindrome  code-golf  string  interactive  code-golf  quine  polyglot  code-golf  string  stack-exchange-api  code-golf  number-theory  decision-problem  code-golf  tips  code-golf  string  internet  code-golf  graphical-output  image-processing  fractal  code-golf  ascii-art  geometry  hexagonal-grid  code-golf  string  restricted-source  hello-world  code-golf  game  code-golf  cipher  code-golf  permutations  cops-and-robbers  permutations  cops-and-robbers  code-golf  internet  stack-exchange-api  code-golf  ascii-art  random  code-golf  tips  code-golf  ascii-art  code-golf  code-golf  kolmogorov-complexity  code-golf  string  unicode  code-golf  number  sequence  primes  palindrome  code-golf  game  decision-problem  code-golf  math  geometry  code-golf  graphical-output  interactive  code-golf  set-partitions  code-golf  number  arithmetic  restricted-source  code-golf  decision-problem  python  recursion  code-golf  ascii-art  code-golf  source-layout  code-golf  function  recursion  functional-programming  code-golf  game  combinatorics  permutations  code-golf  string  file-system  code-golf  string  hashing  code-golf  stack-exchange-api  code-golf  string  code-golf  math  number  arithmetic  polyglot 

4
Mengharuskan keacakan tanpa menentukan distribusi harus dihindari.
flawr

kembali sebagai bilangan bulat, bukan string, ya?
Giuseppe

@Giuseppe menghasilkan angka acak
mbomb007

4
Saya memikirkan hal ini setiap kali seseorang membuat pertanyaan nomor acak xkcd.com/221
Thunda

1
@ ais523 "Berikan input 0 <n <10 menghasilkan angka acak dengan"
cleblanc

Jawaban:


17

Python 2 , 77 byte

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

Cobalah online!

Kocok daftar 10 digit hingga tidak dimulai dengan 0, lalu buat angka dengan nangka pertama yang tercantum.


Jelas berjalan lebih cepat dan dengan memori lebih sedikit untuk input 9atau 10.
mbomb007

Solusi rapi! Bisakah Anda menjelaskan cara [1::3]kerjanya untuk mengubahnya dari daftar ke string? Saya belum pernah melihat itu sebelumnya.
Julian Wolf

@JulianWolf Hanya berfungsi jika setiap elemen dari daftar memiliki panjang yang sama. Ini benar-benar mengambil representasi string dari daftar, lalu mengirisnya mengambil setiap karakter ke-3 setelah melewatkan yang pertama [.
mbomb007

@JulianWolf [1::3]mendapatkan karakter di indeks 1, lalu setiap ketiga. Sebab [1, 2, 3], itu memberi 123, melewatkan tanda kurung, koma, dan spasi.
Dennis

Tembak, oke — itu masuk akal. Saya lupa yang [1, 2, 3]sudah dirangkai dan bahwa koma dan ruang perlu dilewati. Terima kasih!
Julian Wolf

10

Brachylog , 9 10 byte

{~lℕ₁≜≠}ᶠṛ

Cobalah online!

Seperti biasa untuk Brachylog, ini adalah pengiriman fungsi. TIO link di atas telah diberikan argumen command-line untuk membuat fungsi menjadi program penuh.

Saya harus menambahkan byte tambahan dari versi pertama ini, berubah menjadi ℕ₁, untuk melarang output 0 (sesuatu yang sekarang telah diklarifikasi).

Penjelasan

{~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.

Cukup tidak efisien, karena penerjemah menghasilkan daftar semua nilai yang mungkin dan kemudian mengambilnya secara acak (itulah ᶠṛartinya; Brachylog tidak memiliki opsi "pilih solusi acak" pada saat pertanyaan ini diajukan).

Beberapa komentar pada pelabelan di sini: jika dihilangkan, bagian dalam kurung hanya menghasilkan satu nilai, kendala yang mewakili angka dengan properti yang kita inginkan; Oleh karena itu, memilih hasil acak memberi kita batasan, dan penerjemah mengeluarkan nilai absolut minimum yang memenuhi kendala (1, 10, 102, 1023, 10234, dll.), yang bukan yang kita inginkan. Karena itu kami harus memaksanya untuk membuat daftar melalui labelisasi eksplisit.

Sebagian besar implementasi Prolog yang saya lihat memiliki builtin untuk menemukan hasil acak yang cocok dengan kendala, tetapi biasanya tidak dengan probabilitas yang seragam; Brachylog tidak memilikinya, (ada yang ditambahkan dalam menanggapi tantangan ini, tapi jelas saya tidak bisa menggunakannya karena aturan celah). Jika ya, dan jika kebetulan memberikan probabilitas yang seragam pada masalah ini, program ini hanya akan ~lℕ₁≠diikuti oleh builtin itu, untuk kemungkinan panjang 6 byte.

Brachylog , 8 byte, bekerja sama dengan @Fatalize

~lℕ₁≠≜ᶠṛ

Cobalah online!

Ini adalah jenis trik tingkat rendah jenius yang hanya masuk akal dengan cara Prolog melakukan sesuatu, dan tidak masuk akal ketika dijelaskan secara matematis.

Seperti sebelumnya, ~lℕ₁≠membangun nilai yang menggambarkan kendala ("panjang sama dengan input, bilangan alami, semua elemen berbeda"). Kemudian ≜ᶠmenghasilkan semua nilai yang mungkin yang memenuhi kendala. Intinya di sini adalah bahwa dengan urutan evaluasi Brachylog, tidak ada pilihan aktual yang dibuat sampai muncul, sehingga operasi "temukan semua solusi" tidak perlu berlaku apa pun selain operasi "nilai spesifik yang memenuhi kendala" . Itu berarti tidak perlu bagi {…}untuk memilih ruang lingkupnya, menghemat 2 byte.


Saya akan memposting solusi ≜₁sebelum saya menyadari bahwa itu ditambahkan karena tantangan ini
String yang tidak terkait

8

Jelly , 9 byte

⁵*ṖQL$€MX

Cobalah online! (tidak akan bekerja di TIO untuk n> 6 karena ketidakefisienan implementasi)

atau implementasi alternatif dari hal yang sama:

⁵*ṖQL$ÐṀX

Bagaimana?

Ini sangat licik, dan sangat tidak efisien! Jelly melakukan beberapa hal berguna secara implisit ketika atom mengharapkan daftar tetapi menerima bilangan bulat (ini adalah desain).
Kode ini menggunakan beberapa tindakan implisit yang berguna ini:

  • Atom monadik , "pop", ketika dipanggil dengan input integer secara implisit membuat rentang dari mana untuk pop, sehingga input dari n membuat pertama [1, 2, ..., n] , kemudian muncul, menghasilkan [1, 2 , ..., n-1] .

  • Atom monadik Q, "de-duplikat" atau "unik", ketika dipanggil dengan input integer secara implisit membuat daftar desimal untuk menduplikat, jadi input dari n di mana:
    n = d k-1 × 10 k-1 + d k-2 × 10 k-2 + ... + d 1 × 10 + d 0
    pertama membuat
    [d k-1 , d k-2 , ..., d 1 , d 0 ]
    dan kemudian menghasilkan nilai unik dengan penampilan pertama.
    Jadi, misalnya, n = 5835518 akan menghasilkan [5, 8, 3, 1] .

Lebih lanjut, atom monadik M, "indeks elemen maksimal", mengembalikan indeks item maksimal dari daftar, ini menghemat dua byte dari alternatif pengujian kesetaraan yang jauh lebih jelas dengan input dan menemukan indeks kebenaran ⁵*ṖQL$€=⁸TX,, atau⁵*Ṗð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

Ini semua sangat tidak efisien, baik dalam waktu maupun memori: pertama daftar 10 n bilangan bulat dibuat dan satu dibuang, kemudian untuk masing-masing ini daftar n bilangan bulat (bukan objek 4-bit atau enum) dibuat dan kemudian diduplikasi. De-duplikasi ini memiliki implementasi yang sepenuhnya berbasis daftar (tidak ada set, diurutkan-set, atau kamus yang terlibat di bawah-the-hood, setiap digit diperiksa untuk keberadaan dalam daftar yang akhirnya mendapatkan output).
Offline n = 7 menggunakan ~ 0.5GB dan membutuhkan ~ 25 detik, sementara n = 8 menggunakan ~ 4GB dan membutuhkan ~ 5 menit - Saya tidak pernah repot menjalankan n = 9 karena saya hanya memiliki ram 16GB (saya kira itu akan memakan waktu ~ 45 menit ).

Implementasi alternatif hanya menggunakan built-in ÐṀquick to filter-keep minimal (yang di sini hanya menambahkan sedikit overhead dalam manajemen untuk byte-count yang sama).


Oh wow. Saya mencoba sesuatu yang sangat seperti ini tetapi melewatkan trik menyimpan nilai untuk kembali dalam daftar indeks (melalui padding keluar daftar), daripada mencoba untuk menyimpannya secara terpisah. Ini adalah trik yang berguna dalam Jelly cukup sering dan saya sepertinya selalu melewatkannya.

7

Jelly , 11 byte

9Xœ|⁵ḶẊ¤ḣ¹Ḍ

Cobalah online!

Bagaimana itu bekerja

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.

Itu cara yang sangat cerdas untuk menghapus duplikat ...
Leaky Nun

7

JavaScript (ES6), 72 71 70 69 byte

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

Ini adalah fungsi rekursif yang mengambil jumlah digit x . Parameter kedua y , awalnya diatur ke string kosong, melacak nomor ketika kita menghasilkan digit demi digit.

Pertama kita menghasilkan angka acak z dengan Math.random()*10|0. Sekarang, kami ingin memeriksa bahwa y tidak mengandung z , dan bahwa y dan z tidak keduanya 0 .

Kami dapat menghitung kondisi pertama dengan !y.match(z). y.match(z)mengembalikan array (selalu benar) jika y berisi z , null (falsy) sebaliknya; yang !mengkonversi ini menjadi boolean dan membalikkannya.

Kondisi kedua diperiksa dengan y|z. Meskipun y adalah string, JS secara implisit mengkonversinya menjadi integer saat menggunakan |. Ini adalah bilangan bulat positif jika y sudah berisi angka, 0 sebaliknya. Hasil akhirnya adalah y|zmengembalikan 0 jika y kosong dan z adalah 0 , atau bilangan bulat positif sebaliknya.

Jika kedua kondisi ini benar, maka kami menambahkan digit ke y , mengurangi x , dan memulai proses dari awal lagi. Kalau tidak, kita cukup kembali ke awal dan berharap digit acak berikutnya berfungsi. Ketika x mencapai 0 , kita cukup mengembalikan string kosong untuk mengakhiri rekursi.


Versi sebelumnya:

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

Ini adalah fungsi rekursif yang mengambil jumlah digit. Parameter kedua yang awalnya tidak ditentukan, y , adalah tabel pencarian 10-bit yang memberitahu kita digit mana yang sudah kita miliki, disimpan dengan nyaman sebagai integer.

Pertama kita menghasilkan angka acak z dengan Math.random()*10|0. Sekarang, kita ingin memeriksa bahwa z 'th bit paling signifikan y tidak diatur, dan bahwa y dan z tidak baik 0 .

Kami dapat menghitung kondisi pertama dengan ~y>>z&1; balik y , pindahkan z bit ke kanan, dan ambil hanya bit yang paling tidak signifikan. Ini memberi 1 jika kita belum menghasilkan digit yang dimaksud, atau 0 sebaliknya.

Kondisi kedua pada awalnya cukup sulit untuk diketahui (saya mencoba menggunakan y/zpada awalnya untuk menghasilkan NaNjika keduanya 0), tetapi pada beberapa titik saya menyadari bahwa hanya y|zakan melakukan trik. Hasilnya adalah 0 iff baik y dan z adalah 0 ; bilangan bulat positif sebaliknya.

Jika kedua kondisi ini benar ( ~y>>z&1&&y|z), maka kami menghasilkan sisa bilangan dan ditambahkan dengan z . Sisa nomor dihasilkan dengan memanggil fungsi lagi dengan x-1dan y|1<<z( y , tetapi dengan bit pada indeks z diatur ke 1 ). Ketika x mencapai 0 , kita cukup mengembalikan string kosong untuk mengakhiri rekursi.


5

ClojureScript, 81 79 byte

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

Ini adalah fungsi anonim, jadi Anda harus menggunakannya seperti ini:

(#(...) {arguments})

Tempat Anda mengganti {arguments}dengan argumen Anda.

Anda dapat mencoba kode di sini (ClojureScript REPL).

Terima kasih @cliffroottelah mencukur 2 byte!


Kode yang diperluas:

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

Penjelasan:

Saya akan pergi melalui baris satu per satu, menggunakan contoh input 8.


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

Cukup sederhana, ini mendefinisikan fungsi random-digitsdengan satu argumen, yang disebut n. Dalam jawaban saya, saya menggunakan fungsi anonim ( #(...)), untuk menyimpan byte.


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

Mari kita periksa di dalam let, dari dalam ke luar:

(shuffle (range 10))

Dalam ClojureScript (dan Clojure), (range n)mirip dengan Python range(n): ini memberi Anda daftar dengan setiap angka dari 0hingga n - 1( 9dalam hal ini).

shufflemengambil daftar, dan mengembalikan vektor (yang sedikit berbeda dari daftar) dengan semua elemennya dikocok. Jadi, menggunakan contoh kita, kita mendapatkan sesuatu seperti ini:

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

(subvec {see above} 0 n)

(subvec vector start end)mengambil vektor (hanya vektor), dan mengembalikan vektor yang memiliki semua elemen dari indeks startke end. Dalam hal ini, kami mengambil elemen dari 0elemen ke argumen yang diberikan random-digits. Jika kita menerapkan itu pada contoh kita, kita mendapatkan:

[1 0 8 3 6 7 9 2]

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

ifPernyataan ini memeriksa apakah elemen pertama num-vectoradalah a 0.

Jika ya 0, maka kita memanggil fungsi lagi, dengan argumen n, menggunakan recur.

Jika tidak 0:


(int (apply str num-vector))

(apply function list)mengambil daftar, dan meludahkannya ke dalam fungsi sebagai argumen. Sebagai contoh:

(apply + [2 3 4])

Berubah menjadi:

(+ 2 3 4)

Yang sama dengan 9.

(str items)mengubah setiap item itemsmenjadi string, dan kemudian menggabungkannya. intmengubah apa pun menjadi bilangan bulat. Jadi jika kita menerapkan ini pada contoh kita, kita mendapatkan:

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

Yang merupakan jawaban terakhir kami.


2
Harus menyukai ClojureScript karena mengizinkan (int string)alih-alih (Integer/parseInt string):)
cliffroot

1
@cliffroot Maksudku, Anda bisa melakukannya read-stringdi Clojure, tapi itu tidak jauh lebih baik ...
clismique

2 byte yang disimpan #(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))bergerak apply strsebagian hingga akhir, memungkinkan untuk membandingkan 0alih-alih \0dan menggunakan subvecalih-alih takememungkinkan untuk menggunakan vektor sebagai fungsi dan dengan demikian menghapusfirst
cliffroot

@cliffroot Huh, tidak tahu yang shufflemengubah koleksi menjadi vec. Terima kasih! Akan harus menulis penjelasan baru, meskipun ...
clismique

5

Python 2, 89 81 80 byte

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

Cobalah online


Saya tidak berpikir Anda membutuhkan nilai awal untuk rentang tersebut.
Dennis

Bagus! Itu akan memperlambatnya. : D Sayang sekali saya tidak bisa menggunakan generator, bukan daftar.
mbomb007

Hanya sebesar 11%. Masukkan ember untuk kode golf.
Dennis

Ya, saya harus menggunakan 99**n, hanya untuk memastikan saya mendapatkan semuanya. : D
mbomb007

Saya melihat melakukannya dengan cara ini juga, tetapi mendapat 80, dengan menggunakan if`set(`i`)`[5*n:]].
Jonathan Allan

5

R, 45 Bytes

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

Saya pikir Anda bisa mengatur k=0karena ini adalah vektor implisit dengan panjang satu, dan Anda dapat menggunakan i = scan () untuk mengambil input dari stdin sebagai angka. Saya juga tidak yakin bahwa daftar angka adalah pengiriman yang "benar", tetapi saya bukan hakim.
Giuseppe

@ Giuseppe Terima kasih atas masukannya, perbarui kedua saran Anda (di kedua posting), terima kasih.
Neil

Apakah while(!k[1])berhasil menghemat 2 byte?
BLT

@ BLT Diperbarui, terima kasih.
Neil

3

Utilitas Bash + GNU, 46

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

Cobalah online .

Ini membutuhkan waktu lama untuk n yang lebih besar - sekitar 30 detik untuk n = 7, dan meningkat 10 kali untuk setiap kenaikan, jadi mungkin 8-9 jam untuk n = 10.


per pertanyaan, n = 10 bahkan tidak perlu bekerja, apalagi harus cepat
ysth

3

Java 7, 150 147 145 134 byte

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 byte terima kasih kepada @TheLethalCoder

(lama) Penjelasan:

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

Kode uji:

Coba di sini.

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

Contoh output:

7194
8672953041

Tidak bisakah Anda menggunakan ekspresi lambda di sini? yaitu n->...atau apakah itu Java 8+?
TheLethalCoder

1
Anda juga dapat meminjam trik yang baru saja saya gunakan dalam jawaban saya, atur panjangnya di cek perbandingan yaitu for(int l,x;(l=r.length())<n;)dan Anda harus menyimpan byte.
TheLethalCoder

1
@TheLethalCoder Ah tentu saja, terima kasih. Kerja tim yang hebat! ;) Dan ya, n->...adalah Java 8. Secara pribadi saya lebih suka codegolf di Java 7, meskipun 8 selalu lebih pendek.
Kevin Cruijssen

2

Perl 6 , 44 byte

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

Cobalah

Diperluas:

{  # 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)
}

2

PHP, 67 Bytes

Versi Online

Semua versi berdasarkan pengocokan angka 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));

2

MATL , 15 byte

`4Y2GZr1)48=]8M

Cobalah di MATL Online!

Penjelasan

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

2

Jelly , 12 byte

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

Saat ini satu byte di belakang jawaban Jelly saya yang lain, tapi saya sangat suka yang ini.

Cobalah online!

Bagaimana itu bekerja

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.

2

APL (Dyalog) , 27 19 17 byte

Membutuhkan ⎕IO←0yang default pada banyak sistem.

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

Cobalah online!

Kocok digit hingga valid:

10⊥ decode dari basis-10 digit ke angka reguler,

 kemudian

 elemen pertama dari

{... }⍣{... } mengulangi fungsinya ...
?⍨10 kocok sepuluh bilangan bulat positif pertama
hingga ...
⊃⍺ digit pertama dari upaya terakhir
× adalah positif


1

Python 2 , 100 93 92 90 byte

Terima kasih kepada @ mbomb007 untuk mencukur 2 byte

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

Mencoba angka dalam yang diperlukan sampai ditemukan dengan angka unik. Saya berani bertaruh ada cara yang lebih bersih untuk melakukan ini, tetapi tidak ada yang terlintas dalam pikiran.


return(n==len(set(`k`)))*k or f(n). Cobalah online
mbomb007

1

Pyth , 11 byte

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

Menggunakan algoritma yang sama dengan jawaban Dennis .

Cobalah online!


1

Perl, 48 byte

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

Penjelasan:

Berulang-ulang menghasilkan bilangan bulat acak dari 1 hingga 10 ** $ n-1, menolaknya sampai ada salah satu dari panjang yang benar (jadi setidaknya 10 ** ($ n-1)) tanpa digit berulang.


1

Batch, 156 byte

@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

xmemelihara bitmask dari digit yang digunakan. fmenunjukkan jumlah digit yang tersedia (menghitung mundur dari 9). Digit acak dihasilkan hingga digit yang tidak digunakan ditemukan. n=10dapat didukung untuk 165 byte:

@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

( rmengandung angka nol di depan karena itu golfier.) Pendekatan sebelumnya untuk 165 byte khusus-digit pertama, dan juga bekerja dengan n=10(versi numerik sebenarnya mengambil 166 byte!):

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

Pendekatan asli untuk 170 byte juga bekerja untuk 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%

Menggunakan manipulasi string untuk mendeteksi digit duplikat.


1

Pesta , 66 byte

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

Cobalah online!

Lurus ke depan, gunakan shuf, xargs digunakan untuk bergabung dengan garis dan terus mencoba sementara kombinasi dimulai dengan 0.

Tidak bisa mengalahkan 46 char dari jawaban lain tetapi dengan demikian cepat!


1

Pyth, 15 28 byte

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

Coba di sini


1
Selamat datang di PPCG, dan pekerjaan hebat menggunakan bahasa golf langsung dari kelelawar :-) Saya melihat 2 masalah kecil: 1) sepertinya digit kedua selalu 0, jadi saya pikir Anda akan ingin mengubah ^TttQke ^TtQ(-1 byte, bonus!). 2) semua digit dalam output harus unik, jadi Anda harus memaksakan itu terjadi.
ETHproduksi

@ ETProduk Arg !! Terima kasih telah menunjukkannya. Saya sudah memperbaikinya.
Maria

1

C #, 127 132 128 126 125 byte

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

Cobalah secara Online!

Meminjam ide dari jawaban @ KevinCruijssen untuk menginisialisasi acak r,, dalamif pernyataan untuk menyimpan 2 byte.

Cukup yakin ini bisa bermain golf lebih jauh tetapi saya tidak punya waktu saat ini.


Versi lama menggunakan whileloop:

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

Saya pikir ini tidak benar. Katakanlah integer acak pertama adalah 0, pertama kali akan mencoba if(s.Length<1&r>0)yang palsu, tetapi kemudian akan melakukan if(!s.Contains(r+""))yang benar dan masih append "0"untuk ssebagai digit pertama.
Kevin Cruijssen

@KevinCruijssen Tetap dan bermain golf lebih lanjut
TheLethalCoder

1
@KevinCruijssen Ah saya sudah menyelesaikannya, dalam contoh Anda, Anda tidak mengakhiri .Next(10)... dengan a ;. Jadi tidak ada perbaikan lebih lanjut di sana, tapi ide bagus.
TheLethalCoder

1
Saya baru saja mempostingnya. Dan oops, Anda benar saya melewatkan semi-kolon itu .. Anda masih bisa bermain golf seperti ini: 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

1
@KevinCruijssen Saya baru saja meminjam ide dari jawaban Anda ketika Anda menulis komentar itu! Perbaikan yang bagus terima kasih
TheLethalCoder

1

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

Yang ini menghasilkan angka acak yang sebenarnya

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

Cobalah online!

C (gcc) , 87 85 byte

Ini dia mencetak serangkaian angka.

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

Cobalah online!


1

PHP, 65 63 byte

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

menerima input dari STDIN; jalankan bersama-nR .

buat angka acak antara 1dan 10^Ninklusif;
ulangi sementara hitungan karakter yang berbeda adalah < N.


1
while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x;-2 Bytes
Jörg Hülsermann

0

Mathematica 65 60 Bytes

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

Ini adalah versi yang lebih cepat tetapi menambahkan 9 byte:

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

0

Java 9 JShell, 86 byte

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

Cobalah online!

Catatan: Saya tidak menghitung impor karena paket-paket itu diimpor secara default di JShell, tetapi tidak ada tautan Try-it-online yang saya ketahui untuk JShell, jadi saya telah menyediakan satu untuk Java 9 dengan kode header dan footer untuk membuatnya bekerja dalam konteks itu. Di JShell Anda bisa melakukan:

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

Lalu:

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

Bagaimana itu bekerja:

Kami mendefinisikan fungsi dari Integer ke Long dan membuat aliran tak terbatas dari long acak di kisaran 0-9, membatasi ke item n-1 pertama, kemudian menguranginya dengan int acak dari 1-9 sebagai nilai awal dan fungsi yang mengalikan nilai dengan 10 dan menambahkan nilai berikutnya dari aliran.

Saya menggunakan long jadi ini harus bekerja hingga sekitar 18 digit (n = 18).


0

C, 96 93 byte

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

Inisialisasi Fisher-Yates mengocok inisialisasi hingga digit pertama tidak nol.

Berseragam, dengan asumsi rand()%iseragam. (Karena sebagian besar saya RAND_MAX/imeninggalkan sisa kecil, ada bias yang sangat kecil. Bias ini tumbuh lebih kecil karena RAND_MAX tumbuh lebih besar.)

Lihat itu berfungsi online .

Lihat itu menghasilkan angka yang benar ketika n sama dengan 2, seperti yang ditunjukkan dalam pertanyaan .


0

Aksioma, 191 byte

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 itu, hasil tes

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


0

Ruby, 53 52 byte

Acak hingga digit pertama bukan 0, lalu gabungkan digit dan konversikan ke integer.

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

Cobalah online!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.