Lấy số n chữ số ngẫu nhiên có chữ số riêng biệt và đầu tiên không phải là 0


22

Tôi đọc câu hỏi này và nghĩ rằng nó sẽ tạo ra một thử thách thú vị.

Bài tập

Đưa ra một đầu vào 0<n<10tạo một số ngẫu nhiên với

  • chính xác n chữ số
  • đầu tiên không phải là một 0
    • vì thế f(n)>10**(n-1)-1
  • chữ số riêng biệt

Tiêu chí chiến thắng

Đây là nên mã ngắn nhất sẽ thắng.

Ngẫu nhiên

Tôi có nghĩa là phân phối ngẫu nhiên đều. Vì vậy, từ quan điểm của chương trình, mỗi số có thể có cơ hội như nhau. Nếu ngôn ngữ bạn đang viết có một trình tạo số ngẫu nhiên kỳ lạ, bạn có thể sử dụng ngôn ngữ đó.

Thí dụ

Danh sách các giá trị được chọn ngẫu nhiên từ n=2:

[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
Yêu cầu ngẫu nhiên mà không chỉ định phân phối nên tránh.
flawr

trả về như một số nguyên, không phải là một chuỗi, có?
Giuseppe

@Giuseppe tạo một số ngẫu nhiên
mbomb007

4
Tôi nghĩ về điều này mỗi khi ai đó đưa ra một câu hỏi số ngẫu nhiên xkcd.com/221
Thunda

1
@ ais523 "Cung cấp đầu vào 0 <n <10 tạo một số ngẫu nhiên với"
cleblanc

Câu trả lời:


17

Python 2 , 77 byte

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

Hãy thử trực tuyến!

Xáo trộn danh sách 10 chữ số cho đến khi nó không bắt đầu bằng 0, sau đó tạo một số có các nchữ số đầu tiên được liệt kê.


Chắc chắn chạy nhanh hơn và có ít bộ nhớ hơn cho đầu vào 9hoặc 10.
mbomb007

Giải pháp gọn gàng! Bạn có thể giải thích làm thế nào các [1::3]công việc để chuyển đổi nó từ một danh sách thành một chuỗi? Tôi chưa bao giờ thấy điều đó trước đây.
Julian Wolf

@JulianWolf Nó chỉ hoạt động nếu mỗi thành phần của danh sách có cùng độ dài. Nó thực sự lấy đại diện chuỗi của danh sách, sau đó cắt nó lấy mỗi ký tự thứ 3 sau khi bỏ qua ký tự đầu tiên [.
mbomb007

@JulianWolf [1::3]có được nhân vật ở chỉ số 1, sau đó cứ sau 3 giây . Vì [1, 2, 3], điều đó mang lại 123, bỏ qua dấu ngoặc, dấu phẩy và dấu cách.
Dennis

Bắn, không sao mà có ý nghĩa. Tôi đã quên rằng [1, 2, 3]đã được xâu chuỗi và dấu phẩy và khoảng trắng cần bỏ qua. Cảm ơn!
Julian Wolf

10

Brachylog , 9 10 byte

{~lℕ₁≜≠}ᶠṛ

Hãy thử trực tuyến!

Như thường lệ đối với Brachylog, đây là một chức năng đệ trình. Liên kết TIO ở trên đã được đưa ra một đối số dòng lệnh để làm cho hàm thành một chương trình đầy đủ.

Tôi đã phải thêm một byte bổ sung từ phiên bản đầu tiên này, thay đổi thành ℕ₁, không cho phép đầu ra 0 (một cái gì đó hiện đã được làm rõ).

Giải trình

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

Khá kém hiệu quả, bởi vì trình thông dịch tạo ra một danh sách tất cả các giá trị có thể và sau đó chọn một giá trị ngẫu nhiên (điều đó ᶠṛcó nghĩa là; Brachylog không có tùy chọn "chọn giải pháp ngẫu nhiên" tại thời điểm câu hỏi này được hỏi).

Một số ý kiến ​​về việc ghi nhãn ở đây: nếu bị bỏ qua, phần trong dấu ngoặc chỉ tạo ra một giá trị, một ràng buộc thể hiện các số với thuộc tính chúng ta muốn; do đó, chọn một kết quả ngẫu nhiên mang lại cho chúng ta ràng buộc và trình thông dịch đưa ra giá trị tuyệt đối tối thiểu đáp ứng ràng buộc (1, 10, 102, 1023, 10234, v.v.), đó không phải là điều chúng ta muốn. Do đó, chúng tôi phải buộc nó xây dựng danh sách thông qua một nhãn rõ ràng.

Hầu hết các triển khai Prolog mà tôi thấy đều có nội dung để tìm kết quả ngẫu nhiên khớp với một ràng buộc, nhưng thường không có xác suất thống nhất; Mặc dù vậy, Brachylog không có ai (một người được thêm vào để đối phó với thử thách này, nhưng rõ ràng tôi không thể sử dụng nó do các quy tắc kẽ hở). Nếu có, và nếu nó tình cờ đưa ra xác suất thống nhất cho vấn đề này, chương trình này sẽ được ~lℕ₁≠theo sau bởi nội dung đó, với độ dài có thể là 6 byte.

Brachylog , 8 byte, phối hợp với @Firthize

~lℕ₁≠≜ᶠṛ

Hãy thử trực tuyến!

Đây là loại mánh khóe cấp thấp thiên tài chỉ có ý nghĩa với cách Prolog làm mọi việc, và không có ý nghĩa gì khi được mô tả bằng toán học.

Như trước, ~lℕ₁≠xây dựng một giá trị mô tả một ràng buộc ("chiều dài bằng với đầu vào, số tự nhiên, tất cả các yếu tố khác nhau"). Sau đó ≜ᶠtạo ra tất cả các giá trị có thể đáp ứng các ràng buộc. Vấn đề ở đây là với trình tự đánh giá của Brachylog, không có lựa chọn thực tế nào được thực hiện cho đến khi xuất hiện, do đó, hoạt động "tìm tất cả các giải pháp" không cần áp dụng cho hoạt động "giá trị cụ thể đáp ứng một ràng buộc" . Điều đó có nghĩa là không cần phải {…}chọn phạm vi của nó, tiết kiệm 2 byte.


Tôi sẽ đăng một giải pháp ≜₁trước khi tôi nhận ra rằng nó đã được thêm vào vì thử thách này
Chuỗi không liên quan

8

Thạch , 9 byte

⁵*ṖQL$€MX

Hãy thử trực tuyến! (sẽ không làm việc tại TIO cho n> 6 do việc triển khai không hiệu quả)

hoặc thực hiện thay thế của điều tương tự:

⁵*ṖQL$ÐṀX

Làm sao?

Điều này là khá lén lút, và rất không hiệu quả! Jelly thực hiện một số điều hữu ích khi một nguyên tử mong đợi một danh sách nhưng nhận được một số nguyên (đây là do thiết kế).
Mã này sử dụng một vài hành động ngầm hữu ích sau:

  • Nguyên tử đơn âm , "pop", khi được gọi với một đầu vào số nguyên sẽ tạo ra một phạm vi từ đó bật lên, do đó, đầu vào của n trước tiên tạo ra [1, 2, ..., n] , sau đó bật lên, thu được [1, 2 , ..., n-1] .

  • Nguyên tử đơn âm Q, "khử trùng lặp" hoặc "duy nhất", khi được gọi với một đầu vào số nguyên sẽ tạo ra một danh sách thập phân để nhân đôi, do đó, một đầu vào của n trong đó:
    n = d k - 1 × 10 k - 1 + d k-2 × 10 k-2 + ... + d 1 × 10 + d 0
    trước tiên tạo
    [d k-1 , d k-2 , ..., d 1 , d 0 ]
    và sau đó mang lại các giá trị duy nhất bằng lần xuất hiện đầu tiên.
    Vì vậy, ví dụ, n = 5835518 sẽ mang lại [5, 8, 3, 1] .

Hơn nữa, nguyên tử đơn nguyên M, "chỉ mục phần tử tối đa", trả về các chỉ mục của các mục tối đa từ một danh sách, điều này giúp tiết kiệm hai byte qua phương pháp kiểm tra thay thế rõ ràng hơn cho sự bình đẳng với đầu vào và tìm chỉ mục trung thực ⁵*ṖQL$€=⁸TX, hoặc⁵*Ṗð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

Điều này khá kém hiệu quả, cả về thời gian và bộ nhớ: đầu tiên, một danh sách gồm 10 n số nguyên được tạo ra và một số bị loại bỏ, sau đó cho mỗi danh sách n số nguyên (không phải một số đối tượng 4 bit hay enum) được tạo ra và sau đó được nhân đôi. Sự sao chép này có một triển khai hoàn toàn dựa trên danh sách (không có bộ, bộ sắp xếp hoặc từ điển nào có liên quan, mỗi chữ số được kiểm tra sự tồn tại trong danh sách mà cuối cùng sẽ có đầu ra).
Ngoại tuyến n = 7 sử dụng ~ 0,5 GB và mất ~ 25 giây, trong khi n = 8 sử dụng ~ 4GB và mất ~ 5 phút - Tôi không bận tâm khi chạy n = 9 vì tôi chỉ có 16 GB ram (tôi đoán sẽ mất ~ 45 phút ).

Việc triển khai thay thế chỉ sử dụng ÐṀnhanh chóng tích hợp để giữ bộ lọc tối thiểu (mà ở đây chỉ cần thêm một chút chi phí quản lý cho cùng một số byte).


Tuyệt vời. Tôi đã thử một cái gì đó rất giống như thế này nhưng đã bỏ lỡ thủ thuật lưu trữ các giá trị để trả về trong các chỉ mục danh sách (thông qua việc đệm phù hợp ra khỏi danh sách), thay vì cố gắng lưu trữ chúng một cách riêng biệt. Đây là một mẹo có ích trong Jelly khá thường xuyên và tôi dường như luôn bỏ lỡ nó.

7

Thạch , 11 byte

9Xœ|⁵ḶẊ¤ḣ¹Ḍ

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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.

Đó là một cách rất thông minh để loại bỏ bản sao ...
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

Đây là một hàm đệ quy có số chữ số x . Tham số thứ hai y , ban đầu được đặt thành chuỗi trống, theo dõi số khi chúng ta tạo số đó theo chữ số.

Đầu tiên chúng ta tạo một chữ số z ngẫu nhiên với Math.random()*10|0. Bây giờ, chúng tôi muốn kiểm tra xem y không chứa zyz không phải là 0 .

Chúng ta có thể tính toán điều kiện đầu tiên với !y.match(z). y.match(z)trả về một mảng (luôn luôn trung thực) nếu y chứa z , null (falsy) nếu không; những !chuyển đổi này cho một người boolean và đảo ngược nó.

Điều kiện thứ hai được kiểm tra với y|z. Mặc dù y là một chuỗi, nhưng JS ngầm chuyển đổi nó thành một số nguyên khi sử dụng |. Đây là số nguyên dương nếu y đã chứa các chữ số, 0 nếu không. Kết quả cuối cùng là y|ztrả về 0 iff y trống và z0 hoặc số nguyên dương khác.

Nếu cả hai điều kiện này đều đúng, thì chúng ta sẽ thêm chữ số vào y , giảm x và bắt đầu lại quá trình. Mặt khác, chúng ta chỉ cần quay lại từ đầu và hy vọng rằng chữ số ngẫu nhiên tiếp theo hoạt động. Khi x đạt 0 , chúng ta chỉ cần trả về chuỗi rỗng để kết thúc đệ quy.


Phiên bản trước:

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

Đây là một hàm đệ quy có số chữ số. Tham số thứ hai không xác định ban đầu, y , là bảng tra cứu 10 bit cho chúng ta biết những chữ số nào chúng ta đã có, được lưu trữ thuận tiện dưới dạng một số nguyên.

Đầu tiên chúng ta tạo một chữ số z ngẫu nhiên với Math.random()*10|0. Bây giờ, chúng tôi muốn kiểm tra xem z 'th bit ít quan trọng của y không được thiết lập, và rằng yz là không được cả hai 0 .

Chúng ta có thể tính toán điều kiện đầu tiên với ~y>>z&1; đảo ngược y , dịch chuyển bit z sang phải và chỉ lấy bit có trọng số thấp nhất. Điều này cho 1 nếu chúng ta chưa tạo ra chữ số trong câu hỏi hoặc 0 nếu không.

Điều kiện thứ hai ban đầu khá khó để tìm ra ( y/zlúc đầu tôi đã thử sử dụng để tạo NaNnếu cả hai đều bằng 0), nhưng đến một lúc nào đó tôi nhận ra rằng chỉ đơn giản là y|zsẽ làm được điều đó. Kết quả là 0 iff cả yz0 ; một số nguyên dương khác.

Nếu cả hai điều kiện này đều đúng ( ~y>>z&1&&y|z), thì chúng ta tạo phần còn lại của số và trả trước z . Phần còn lại của số được tạo bằng cách gọi lại hàm với x-1y|1<<z( y , nhưng với bit tại chỉ số z được đặt thành 1 ). Khi x đạt 0 , chúng ta chỉ cần trả về chuỗi rỗng để kết thúc đệ quy.


5

ClojureScript, 81 79 byte

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

Đây là một chức năng ẩn danh, vì vậy bạn phải sử dụng nó như thế này:

(#(...) {arguments})

Nơi bạn thay thế {arguments}bằng các đối số của bạn.

Bạn có thể thử mã ở đây (ClojureScript REPL).

Cảm ơn bạn đã @cliffrootcạo sạch 2 byte!


Mã mở rộng:

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

Giải trình:

Tôi sẽ đi qua từng dòng một, sử dụng một ví dụ đầu vào 8.


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

Khá đơn giản, điều này xác định hàm random-digitsvới một đối số, được gọi n. Trong câu trả lời của tôi, tôi đã sử dụng một hàm ẩn danh ( #(...)), để lưu byte.


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

Hãy xem xét bên trong let, từ trong ra ngoài:

(shuffle (range 10))

Trong ClojureScript (và Clojure), (range n)tương tự như Python range(n): nó cung cấp cho bạn một danh sách với mọi số từ 0đến n - 1( 9trong trường hợp này).

shufflelấy một danh sách và trả về một vectơ (hơi khác so với danh sách) với tất cả các phần tử của nó được xáo trộn. Vì vậy, bằng cách sử dụng ví dụ của chúng tôi, chúng tôi nhận được một cái gì đó như thế này:

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

(subvec {see above} 0 n)

(subvec vector start end)lấy một vectơ (chỉ một vectơ) và trả về một vectơ có tất cả các phần tử từ chỉ mục startđến end. Trong trường hợp này, chúng tôi lấy các phần tử từ 0phần tử thứ cho đối số được đưa ra random-digits. Nếu chúng ta áp dụng điều đó vào ví dụ của mình, chúng ta sẽ nhận được:

[1 0 8 3 6 7 9 2]

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

Câu iflệnh này kiểm tra nếu phần tử đầu tiên của num-vectorlà a 0.

Nếu có 0, sau đó chúng ta gọi lại hàm, với đối số n, sử dụng recur.

Nếu không 0:


(int (apply str num-vector))

(apply function list)lấy một danh sách và đưa chúng vào hàm làm đối số. Ví dụ:

(apply + [2 3 4])

Trở thành:

(+ 2 3 4)

Mà bằng 9.

(str items)biến mỗi mục itemsthành một chuỗi, và sau đó nối chúng lại. intchuyển đổi bất cứ thứ gì thành một số nguyên. Vì vậy, nếu chúng ta áp dụng điều này vào ví dụ của mình, chúng ta sẽ nhận được:

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

Đó là câu trả lời cuối cùng của chúng tôi.


2
Phải yêu ClojureScript vì đã cho phép (int string)thay vì (Integer/parseInt string):)
cliffroot

1
@cliffroot Ý tôi là, bạn có thể làm read-stringở Clojure, nhưng nó không tốt hơn nhiều ...
clismique

2 byte đã lưu #(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))di chuyển apply strmột phần đến cuối, cho phép so sánh 0thay vì \0và sử dụng subvecthay vì takecho phép sử dụng vectơ như một hàm và do đó để loại bỏfirst
cliffroot

@cliffroot Huh, không biết điều đó shuffleđã biến bộ sưu tập thành a vec. Cảm ơn! Sẽ phải viết một lời giải thích mới, mặc dù ...
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:]])

Dùng thử trực tuyến


Tôi không nghĩ rằng bạn cần một giá trị bắt đầu cho phạm vi.
Dennis

Tốt đẹp! Điều đó sẽ làm nó chậm lại. : D Quá tệ Tôi không thể sử dụng trình tạo thay vì danh sách.
mbomb007

Chỉ bằng 11%. Thả trong một cái xô cho mã golf.
Dennis

Vâng, tôi nên sử dụng 99**n, chỉ để chắc chắn rằng tôi có được tất cả. : D
mbomb007

Tôi đã xem xét làm theo cách này quá, nhưng có 80, bằng cách sử dụng if`set(`i`)`[5*n:]].
Jonathan Allan

5

R, 45 byte

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

Tôi nghĩ rằng bạn chỉ có thể đặt k=0vì nó là một vectơ ngầm có độ dài và bạn có thể sử dụng i = scan () để lấy đầu vào từ stdin làm số. Tôi cũng không chắc chắn rằng một danh sách các chữ số là một bài nộp "chính xác", nhưng tôi không phải là thẩm phán.
Giuseppe

@Giuseppe Cảm ơn bạn đã nhập, cập nhật cả hai đề xuất của bạn (trên cả hai bài viết), cảm ơn.
Neil

Sẽ while(!k[1])làm việc để tiết kiệm 2 byte?
BLT

@BLT Cập nhật, cảm ơn.
Neil

3

Đồ dùng Bash + GNU, 46

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

Hãy thử trực tuyến .

Điều này mất nhiều thời gian cho n lớn hơn - khoảng 30 giây cho n = 7 và tăng 10 lần cho mỗi lần tăng, do đó có thể là 8-9 giờ cho n = 10.


mỗi câu hỏi, n = 10 thậm chí không cần phải làm việc, nhanh hơn rất nhiều
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 nhờ @TheLethalCoder

(cũ) Giải thích:

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

Mã kiểm tra:

Hãy thử nó ở đây.

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

Ví dụ đầu ra:

7194
8672953041

Bạn không thể sử dụng một biểu thức lambda ở đây? tức là n->...hay đó là Java 8+?
TheLethalCoder

1
Bạn cũng có thể mượn mẹo tôi vừa sử dụng trong câu trả lời của mình, đặt độ dài trong kiểm tra so sánh tức là for(int l,x;(l=r.length())<n;)và bạn nên lưu một byte.
TheLethalCoder

1
@TheLethalCoder Tất nhiên rồi, cảm ơn. Làm việc theo nhóm! ;) Và vâng, n->...là Java 8. Cá nhân tôi thích codegolf hơn trong Java 7, mặc dù 8 luôn ngắn hơn.
Kevin Cruijssen

2

Perl 6 , 44 byte

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

Thử nó

Mở rộng:

{  # 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 byte

Phiên bản trực tuyến

Tất cả các phiên bản dựa trên xáo trộn các chữ số từ 0-9

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

71 byte

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

73 byte

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

2

MATL , 15 byte

`4Y2GZr1)48=]8M

Hãy thử nó tại MATL Online!

Giải trình

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

Thạch , 12 byte

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

Hiện tại một byte phía sau câu trả lời Jelly khác của tôi, nhưng tôi thực sự thích cái này.

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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

Yêu cầu ⎕IO←0mặc định trên nhiều hệ thống.

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

Hãy thử trực tuyến!

Xáo trộn các chữ số cho đến khi hợp lệ:

10⊥ giải mã từ 10 chữ số cơ bản thành số thông thường,

 sau đó

 yếu tố đầu tiên của

{... }⍣{... } lặp đi lặp lại các chức năng ...
?⍨10 shuffle nguyên dương mười đầu tiên
cho đến khi ...
⊃⍺ chữ số đầu tiên của nỗ lực cuối cùng
× là tích cực


1

Python 2 , 100 93 92 90 byte

Cảm ơn @ mbomb007 đã cạo sạch 2 byte

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

Thử số trong yêu cầu cho đến khi tìm thấy một chữ số duy nhất. Tôi cá là có một cách sạch sẽ hơn nhiều để làm điều này, nhưng không ai nghĩ đến.


return(n==len(set(`k`)))*k or f(n). Dùng thử trực tuyến
mbomb007


1

Perl, 48 byte

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

Giải trình:

Liên tục tạo các số nguyên ngẫu nhiên từ 1 đến 10 ** $ n-1, từ chối chúng cho đến khi có một độ dài chính xác (ít nhất là 10 ** ($ n-1)) không có chữ số lặp lại.


1

Hàng loạt, 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

xduy trì một bitmask của các chữ số được sử dụng. fcho biết số chữ số khả dụng (đếm ngược từ 9). Các chữ số ngẫu nhiên được tạo ra cho đến khi tìm thấy một chữ số không sử dụng. n=10có thể được hỗ trợ cho 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

( rchứa một số 0 đứng đầu bởi vì nó là golfer theo cách đó.) Cách tiếp cận trước đây cho 165 byte đặc biệt bao gồm chữ số đầu tiên và cũng tình cờ hoạt động với n=10(phiên bản số thực sự mất 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%

Cách tiếp cận ban đầu cho 170 byte cũng hoạt động cho 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%

Sử dụng thao tác chuỗi để phát hiện các chữ số trùng lặp.


1

Bash , 66 byte

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

Hãy thử trực tuyến!

Đi thẳng, sử dụng shuf, xargs được sử dụng để nối các dòng và tiếp tục thử trong khi kết hợp bắt đầu bằng 0.

Không thể đánh bại 46 char từ câu trả lời khác nhưng như vậy là nhanh!


1

Bình thường, 15 28 byte

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

Hãy thử nó ở đây


1
Chào mừng bạn đến với PPCG và công việc tuyệt vời khi sử dụng ngôn ngữ chơi gôn ngay lập tức :-) Tôi thấy 2 vấn đề nhỏ: 1) có vẻ như chữ số thứ hai luôn luôn 0, vì vậy tôi nghĩ bạn sẽ muốn thay đổi ^TttQthành ^TtQ(-1 byte, tiền thưởng!). 2) tất cả các chữ số trong đầu ra phải là duy nhất, vì vậy bạn sẽ phải buộc điều đó xảy ra bằng cách nào đó.
Sản xuất ETH

@ETHproductions Arg !! Cảm ơn đã chỉ ra rằng. Tôi đã sửa nó.
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;};

Dùng thử trực tuyến!

Mượn ý tưởng từ câu trả lời của @ KevinCruijssen để khởi tạo ngẫu nhiên r, trong ifcâu lệnh để lưu 2 byte.

Khá chắc chắn rằng điều này có thể được chơi gôn hơn nhưng tôi không có thời gian vào lúc này.


Phiên bản cũ sử dụng whilevòng lặp:

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

Tôi không nghĩ rằng điều này là chính xác. Giả sử số nguyên ngẫu nhiên đầu tiên là 0, đầu tiên nó sẽ thử if(s.Length<1&r>0)là sai, nhưng sau đó nó sẽ làm if(!s.Contains(r+""))đúng và vẫn được thêm "0"vào sdưới dạng chữ số đầu tiên.
Kevin Cruijssen

@KevinCruijssen Đã sửa và đánh gôn xa hơn
TheLethalCoder

1
@KevinCruijssen Ah Tôi đã làm việc đó, trong ví dụ của bạn, bạn không kết thúc .Next(10)... với a ;. Vì vậy, không có cải tiến hơn nữa, nhưng ý tưởng tốt.
TheLethalCoder

1
Tôi vừa đăng nó. Và rất tiếc, bạn đã đúng Tôi đã bỏ lỡ dấu chấm phẩy đó .. Bạn vẫn có thể chơi golf như thế này: 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 Tôi vừa mượn ý tưởng từ câu trả lời của bạn khi bạn đang viết bình luận đó! Cải thiện tốt đẹp
TheLethalCoder

1

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

Cái này tạo ra một số ngẫu nhiên thực tế

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

Hãy thử trực tuyến!

C (gcc) , 87 85 byte

Ở đây nó đang in một chuỗi các chữ số.

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

Hãy thử trực tuyến!


1

PHP, 65 63 byte

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

lấy đầu vào từ STDIN; chạy với -nR.

tạo số ngẫu nhiên giữa 110^Nbao gồm;
lặp lại trong khi số lượng ký tự riêng biệt là < N.


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

0

Toán học 65 60 byte

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

Đây là phiên bản nhanh hơn nhưng thêm 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)

Hãy thử trực tuyến!

Lưu ý: Tôi không tính các lần nhập vì các gói đó được nhập theo mặc định trong JShell, nhưng không có liên kết Dùng thử trực tuyến mà tôi biết cho JShell, vì vậy tôi đã cung cấp một cho Java 9 mã đầu trang và chân trang để làm cho nó hoạt động trong bối cảnh đó. Trong JShell bạn chỉ có thể làm:

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

Và sau đó:

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

Làm thế nào nó hoạt động:

Chúng tôi xác định hàm từ Integer đến Long và tạo một luồng dài vô hạn trong khoảng từ 0-9, giới hạn nó ở các mục n-1 đầu tiên, sau đó giảm nó với giá trị ngẫu nhiên từ 1-9 làm giá trị ban đầu và một hàm nhân giá trị lên 10 và thêm giá trị tiếp theo từ luồng.

Tôi đã sử dụng thời gian dài để nó hoạt động với tối đa khoảng 18 chữ số (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);}

Khởi tạo ngẫu nhiên của Fisher-Yates cho đến khi chữ số đầu tiên không bằng không.

Là đồng phục, giả sử rand()%ilà đồng phục. (Vì hầu hết tôi RAND_MAX/iđể lại một phần còn lại nhỏ, có một sai lệch rất nhỏ. Sự thiên vị này phát triển nhỏ hơn khi RAND_MAX phát triển lớn hơn.)

Xem nó hoạt động trực tuyến .

Xem nó tạo ra các số chính xác khi n bằng 2, như trong câu hỏi .


0

Tiên đề, 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 nó, kết quả kiểm tra

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

Xáo trộn cho đến khi chữ số đầu tiên không phải là 0, sau đó kết hợp các chữ số và chuyển đổi thành một số nguyên.

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

Hãy thử trực tuyến!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.