Ánh xạ một số ngẫu nhiên để pi


27

Một đại diện chính xác kép của một số thập phân chỉ có thể đảm bảo độ chính xác của 15 chữ số thập phân, do đó pi được tính gần đúng như sau:

3.141592653589793

Bạn có thể thấy rằng chữ số 3ở vị trí 1, 10, 16, chữ số 1ở vị trí, 2, 4v.v.

Thử thách

Nhiệm vụ của bạn là tạo một chương trình hoặc hàm tạo một số kép ngẫu nhiên trong khoảng từ 0 đến 1 và ánh xạ các giá trị của số đó lên giá trị của pi. Bạn làm điều này bằng cách đặt các chữ số khác nhau trong các số ngẫu nhiên ở vị trí mà chữ số có trong pi. Nếu không tìm thấy chữ số trong số pi, bạn sẽ bỏ qua nó và mỗi chữ số trong số pi không có trong số ngẫu nhiên sẽ được đại diện bởi một x. Mỗi giá trị chỉ có thể được sử dụng một lần, bắt đầu từ bên trái.

Một vài ví dụ có thể sẽ làm cho điều này rõ ràng hơn. Trong các ví dụ sau, số đầu tiên là pi, số thứ hai là số ngẫu nhiên và số cuối cùng là đầu ra mong muốn.

3.141592653589793
0.111111111111111
x.1x1xxxxxxxxxxxx

3.141592653589793
0.531000000000000
3.1xx5xxxxxxxxxxx

3.141592653589793
0.123456789123456
3.141592653x8x7xx

3.141592653589793
0.967552381459391
3.14159265358979x

Quy tắc:

  • Hàm không được nhận bất kỳ đầu vào nào (một ngoại lệ có thể được giải thích trong dấu đầu dòng 3)
  • Đầu ra chỉ bao gồm chuỗi đầu ra, với một dòng mới tùy chọn (một khoảng trống duy nhất cũng được chấp nhận)
  • Nếu chương trình của bạn không có giá trị Pi tích hợp và / hoặc RNG thì bạn có thể mã hóa Pi và lấy số ngẫu nhiên làm đầu vào. Bạn không thể mã hóa số ngẫu nhiên hoặc lấy Pi làm đầu vào.
  • Cả giá trị được mã hóa cứng cho Pi và 15 chữ số ngẫu nhiên (bạn có thể bỏ qua 0.vì bạn biết nó sẽ nằm trong khoảng từ 0 đến 1), sẽ được bao gồm trong số byte.
  • Nếu ngôn ngữ của bạn không có độ chính xác cần thiết, bạn có thể sử dụng ít độ chính xác hơn theo các hạn chế sau
    • Các chữ số của Pi phải chính xác đến độ chính xác mà bạn có
    • Bạn không thể xuất nhiều giá trị hơn mức bạn đảm bảo có chính xác, tức là bạn không thể xuất 15 chữ số nếu độ chính xác chỉ cho phép 8 số thập phân chính xác.
    • Giá trị được mã hóa cứng của Pi sẽ được tính là 16 byte (bạn không cần dấu thập phân), ngay cả khi chương trình của bạn chỉ hỗ trợ 8 chữ số.
    • Giá trị đầu vào cho số ngẫu nhiên sẽ được tính là 15 byte (bạn không cần 0.. Điều này là do các ngôn ngữ có độ chính xác thấp nên không có lợi thế không công bằng.
    • Chương trình phải hỗ trợ 5 số thập phân chính xác (ít nhất).
    • Chỉnh sửa: Để xác thực câu trả lời: Số ngẫu nhiên phải được in bằng cách nào đó, nhưng thao tác này không phải được bao gồm trong số byte. Vì vậy, ví dụ, nếu có thể chèn print rphần cuối của tập lệnh, phần đó sẽ không tăng điểm.
    • Bạn không thể trừ các byte nếu nó là một phần của hoạt động cần thiết khác. Tức là nếu mã là print pi, r, sau đó bạn chỉ có thể trừ , r.
    • Nếu bạn phải chèn một số vị trí trong mã, vui lòng bao gồm cả hai phiên bản (phiên bản in số ngẫu nhiên và phiên bản không có nhận xét như: _p_oNocần thiết để in số ngẫu nhiên. _pXxx và _oNokhông yyy. _p_oNosẽ không được bao gồm trong số byte.

Mã ngắn nhất trong byte thắng.


Bảng xếp hạng

Đoạn trích Stack ở cuối bài đăng này tạo ra danh mục từ các câu trả lời a) dưới dạng danh sách các giải pháp ngắn nhất cho mỗi ngôn ngữ và b) dưới dạng bảng xếp hạng tổng thể.

Để đảm bảo rằng câu trả lời của bạn hiển thị, vui lòng bắt đầu câu trả lời của bạn bằng một tiêu đề, sử dụng mẫu Markdown sau:

## Language Name, N bytes

nơi Nlà kích thước của trình của bạn. Nếu bạn cải thiện điểm số của mình, bạn có thể giữ điểm số cũ trong tiêu đề, bằng cách đánh bại chúng thông qua. Ví dụ:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Nếu bạn muốn bao gồm nhiều số trong tiêu đề của mình (ví dụ: vì điểm của bạn là tổng của hai tệp hoặc bạn muốn liệt kê riêng các hình phạt cờ của thông dịch viên), hãy đảm bảo rằng điểm thực tế là số cuối cùng trong tiêu đề:

## Perl, 43 + 2 (-p flag) = 45 bytes

Bạn cũng có thể đặt tên ngôn ngữ thành liên kết sau đó sẽ hiển thị trong đoạn trích:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


2
Nếu bạn đang sử dụng một số ngẫu nhiên tích hợp, nó có phải chứa 15 chữ số hay nó có thể có nhiều hơn không? Ngoài ra có bất kỳ yêu cầu để xuất số ngẫu nhiên? Nếu không nó làm cho nó khó hơn một chút để xác nhận câu trả lời.
dùng81655

Aah, đó là một điểm tốt! Số ngẫu nhiên có thể có hơn 15 chữ số. Tôi sẽ thực hiện chỉnh sửa giải thích phải làm gì với số ngẫu nhiên. Cảm ơn đã bình luận!
Stewie Griffin

Liệu ngẫu nhiên " giữa 0 và 1" có nghĩa là 0 < random < 1hay 0 <= random <= 1?
Chris Degnen

@StewieGriffin Tôi bối rối. Điều này có nghĩa là chúng ta có thể sử dụng 15 chữ số pi và số ngẫu nhiên 16/17 chữ số?
Jakube

@Jakube, thành thật mà nói: Tôi đọc câu hỏi hơi sai, do đó trả lời rằng nó có thể có nhiều chữ số hơn, vì vậy câu trả lời cho câu hỏi của bạn là có. Bây giờ đã quá muộn để quay lại câu trả lời đó vì hầu hết các câu trả lời chưa giới hạn số chữ số ngẫu nhiên. Vui lòng hạn chế đến 17 mặc dù.
Stewie Griffin

Câu trả lời:


5

Bình thường, 25 byte

 u&p?}HGH\x.-GH`.n0<`O017

Dùng thử trực tuyến: Trình diễn hoặc Kiểm tra hiển thị số ngẫu nhiên

Giải trình:

 u&p?}HGH\x.-GH`.n0<`O017  
                .n0         the constant pi
               `            convert it into a string
                     O0     random number in the range [0.0, 1.0)
                    `       convert to string
                   <   17   only use the first 17 chars (zero, point and 15 digits)
 u                          for each char H in the pi-string:
    ?}HGH\x                    if H in G (the random number string) then H else "x"
   p                           print this char without newline
  &                            and
           .-GH                remove the digit H once from G
<space>                     suppress the output (u returns the unused digits in G)

14

LabVIEW, 53 LabVIEW Nguyên thủy

Tôi khớp chuỗi và đặt số vào chuỗi x.xxx "trống" và xóa số đó khỏi số pi để nó không hiển thị lại.

số ngẫu nhiên và các ký tự đơn ở đây có thể nhìn thấy được, điều đó có đúng hay tôi phải làm lại bản ghi?


Nó khá rõ ràng đang thực hiện công việc ngay cả khi một vài ký tự hơi khó nhìn, vì vậy bạn không phải làm lại bất cứ điều gì ... Câu trả lời hay! =)
Stewie Griffin

6

Toán học, 105 hoặc 147 ký tự

Nếu số ngẫu nhiên " trong khoảng từ 0 đến 1" 0 <= random <= 1, nghĩa là bao gồm 0 & 1.

StringReplace[ToString@InputForm@N@Pi,
Thread[ToString/@Complement[Range@9,RandomInteger[{0,9},15]]->"x"]]

(105 ký tự)

Mặt khác, lấy số ngẫu nhiên " trong khoảng từ 0 đến 1" 0 < random < 1.

Lặp lại để có 15 số nguyên ngẫu nhiên, không phải tất cả bằng không. Chọn bổ sung từ 0 đến 9 phạm vi, tức là những số từ 0 đến 9 không có trong danh sách ngẫu nhiên. Chuyển đổi các số nguyên đó thành chuỗi và thay thế các ký tự khớp trong chuỗi pi.

(147 ký tự)

While[True,r=RandomInteger[{0,9},15];
If[Union@r!={0},Break[]]];
StringReplace[ToString@InputForm@N@Pi,
Thread[ToString/@Complement[Range@9,r]->"x"]]

3.1x15x265358x7x3

Chữ số ngẫu nhiên: -

FromDigits[r]

820307536180783


Làm xong. Ngắt dòng chỉ bao gồm cho dễ đọc.
Chris Degnen

2
Vẫn xuất hiện dưới dạng 149 byte đối với tôi (với ngắt dòng, 146 không có). Không có gì sai khi thêm cả phiên bản golf và không có người chơi. Một số mẹo chơi gôn: True1>0, RandomIntegercó thể sử dụng ký hiệu infix {0,9}~RandomInteger~15. Bạn có thể có thể lưu một số byte bằng cách đưa ra rmột số giá trị và thực sự sử dụng điều kiện của Whilethay vì sử dụng Break.Then Forcó thể lưu một byte khác While. Mặc dù tôi không thấy lý do tại sao bạn cần vòng lặp nếu bạn giả sử số ngẫu nhiên trong phạm vi [0,1).
Martin Ender

@ MartinBüttner Tôi thích 1>0:-)
Chris Degnen

Tôi thường đọc số ngẫu nhiên "trong khoảng từ 0 đến 1" có nghĩa là 0 <ngẫu nhiên <1.
Chris Degnen

5

JavaScript (ES6), 89 87 byte

_=>(r=[...Math.random()+""],Math.PI+"").replace(/./g,d=>(r[i=r.indexOf(d)]=_,~i?d:"x"))

Giải trình

Chỉnh sửa: Chuỗi ngẫu nhiên hiện không bị cắt ngắn như được làm rõ bởi người đăng.

Vòng lặp qua từng chữ số pi và loại bỏ chữ số khỏi số ngẫu nhiên nếu nó được tìm thấy, khác thay thế chữ số trong pi bằng x.

_=>(
    r=[...Math.random()+""],      // r = array of 15 digit random number chars
    Math.PI+"").replace(/./g,d=>( // for each digit d of pi, includes "." which is always
                                  //     in the random number
      r[i=r.indexOf(d)]=_,        // i = position of d within r, remove digit from r
                                  // "_" is the unused function argument (equals undefined)
      ~i?d:"x"                    // if found, leave the digit, else replace with x
    ))

Kiểm tra

Kiểm tra đầu ra số ngẫu nhiên cũng có.


Không thể ngẫu nhiên () tạo ra 15 số không tương ứng với 0,000 ... hoặc 1.000 ...? tức là không nằm trong khoảng từ 0 đến 1.
Chris Degnen

@ChrisDegnen Math.random()tạo ra một số phạm vi [0,1)để nó có thể 0nhưng không bao giờ 1. OP không nói rõ là phạm vi bao gồm hay độc quyền nên tôi cho rằng bất cứ điều gì hợp lý đều ổn. Đây cũng là phạm vi mà các câu trả lời khác sử dụng. Tuy nhiên, bạn đã làm cho tôi biết rằng nếu chính xác 0thì nó sẽ thất bại bởi vì số .pi sẽ không được khớp và trở thành x. Điều này có cơ hội 1 trong 2 ^ 53 xảy ra nhưng tôi vẫn quyết định sửa nó.
dùng81655

:-) xin lỗi vì việc đó.
Chris Degnen

Khả năng đánh chính xác 0 hoặc 1 cho một cú đúp ngẫu nhiên là không đáng kể, vì vậy với mục đích của thử thách này, một phạm vi [0,1]là ổn (cũng vậy (0,1)).
Stewie Griffin

Tốt đẹp. Tôi đề xuất một biến thể ngắn hơn.
MST

3

CJam, 48 46 42 38 36 byte

P`'xf+1dmr`{1$f#:!1a/0=:)W+H<.%}/1f=

Kiểm tra nó ở đây.

Và đây là phiên bản in cả số π và số ngẫu nhiên:

P_p`'xf+1dmr`_oNo{1$f#:!1a/0=:)W+H<.%}/1f=

Kiểm tra nó ở đây.

Tôi không cắt số ngẫu nhiên thành 15 chữ số thập phân, như được OP làm rõ trong một bình luận.

Giải trình

Ý tưởng là biến mỗi ký tự trong biểu diễn chuỗi của π thành một cặp ký tự đó và x. Đối với mỗi ký tự trong số ngẫu nhiên, chúng tôi trao đổi cặp đầu tiên bắt đầu bằng ký tự đó. Cuối cùng, chúng ta xuất ký tự thứ hai của mỗi cặp.

P`      e# Get string representation of π.
'xf+    e# Append "x" to each character.
1dmr`   e# Get string representation of random number in [0,1).
{       e# For each character in that string...
  1$    e#   Copy the list of pairs.
  f#    e#   For each pair, find the index of the current character. If the character is
        e#   not in the pair, we get -1 (truthy). If it is the first character of the pair,
        e#   we get 0 (falsy). If it is the second character, we get 1 (truthy).
  :!    e#   Logical NOT for each of the results. We get a 1 for every pair we could
        e#   potentially swap.
  1a/   e#   Split around those 1s.
  0=    e#   Keep only the first chunk.
  :)    e#   Turn all the 0s into that chunk into 1s.
  W+    e#   Append a -1.
  H<    e#   Truncate to 17 elements (the number of pairs).
  .%    e#   Apply % pairwise. This reverses the element at the position of the -1.
}/
1f=     e# Select the second character from each pair.

2

Lua, 231 230 byte

m,s=math,""p,r=m.pi..s,s..m.random()p=p:sub(1,#p-1)p:gsub(".",function(c)s=s..(47>c:byte()and c or"x")end)r:gsub("[^%.]",function(c)l=p:find(c)if l then p,s=p:sub(1,l-1).."x"..p:sub(l+1),s:sub(1,l-1)..c..s:sub(l+1)end end)print(s)

Giải thích

function f()
  m,s=math,""
  p,r=m.pi..s,s..m.random()
  p=p:sub(1,#p-1)                       -- remove the last digit of math.pi

  p:gsub(".",function(c)
    s=s..(47>c:byte()and c or"x")      -- Construct a string full of "x" with a single dot
  end)

  r:gsub("[^%.]",function(c)            -- Iterate over each character but the dot in the random number
    l=p:find(c)                         -- if c isn't in pi, l=nil 
    if l                                -- which is one of the two falsy value in lua
    then
      p,s=p:sub(1,l-1).."x"..p:sub(l+1),-- If c is in pi, we replace it in p by an x
          s:sub(1,l-1)..c..s:sub(l+1)   -- and in s by its value
    end
  end)
  return s
end

Đáng buồn thay, lua không giúp tôi tất cả ở đây. math.pi làm tròn chữ số cuối cùng của số pi nó trả về:

print(math.pi)
>> 3.1415926535898

Tôi phải cắt bớt số này:

stringPI=""..math.pi
print(stringPI:sub(1,#stringPI-1))
>> 3.141592653589

Mặc định lớn thứ hai để thực hiện thử thách này là lua thiếu chuỗi.replace (). Khi tôi thực hiện hành động này hai lần bằng cách sử dụng s:sub(1,l-1)..c..s:sub(l+1), tôi muốn thực hiện một chức năng ẩn danh, nghĩ rằng nó sẽ ngắn hơn. Không phải vậy, vì vậy tôi đã viết nó hai lần.

Lý do tôi phải cẩn thận về dấu chấm, là cách lua trả lại vị trí của nó. Trong regexes, một dấu chấm có nghĩa là "bất kỳ ký tự nào", vì vậy khi tôi đánh giá ký tự .trong vòng lặp của mình, nó khớp với ký tự đầu tiên:

c="."  -- The value of the dot in the loop
found = stringPI:find(c)
print(stringPI)
print("location of \".\": "..found)
print("char at "..found..": "..stringPI:sub(found,found))

>> 3.141592653589
>> location of ".": 1   --Keep in mind that lua arrays are 1-based :)
>> char at 1: 3 

Bạn có thể kiểm tra lua trực tuyến . Vì tôi không chọn PRNG, đây là mã cho phép bạn chạy thử nghiệm trong khi vẫn xem các giá trị.

function f()m,s=math,""p,r=m.pi..s,s..m.random()print("Random number: "..r)p=p:sub(1,#p-1)p:gsub(".",function(c)s=s..(c:byte()<47 and c or"x")end)r:gsub("[^%.]",function(c)l=p:find(c)if l then p,s=p:sub(1,l-1).."x"..p:sub(l+1),s:sub(1,l-1)..c..s:sub(l+1)end end)return s end

for i=1,10
do
    print(f())
end

2

Python 2.7, 117 110 byte

import math,random
n=list(`random.random()`)
print''.join(n.pop(n.index(d))if d in n else'x'for d in`math.pi`)

Đã thử nghiệm trên ứng dụng QPython Android mới nhất, nhưng sẽ hoạt động ở bất cứ đâu.

Chỉnh sửa 1: thay đổi str(pi)thành backticks.

Để thử nghiệm:

import math,random
n=list(`random.random()`)
print `math.pi`
print ''.join(n)
print''.join(n.pop(n.index(d))if d in n else'x'for d in`math.pi`)

Câu trả lời tốt đẹp! Bằng cách này, "dấu nháy đơn SO sử dụng để đánh dấu mã" là các ký hiệu backticks hoặc grove, bằng cách :-)
cat

1

Python, 147 byte

import math as m,random as r
L=lambda t:[_ for _ in str(t)]
p=L(m.pi)
R=L(r.random())
A=""
print R #subtracted from byte count
for n in p:
    try:R.remove(n);A+=n
    except:A+='x'
print A

Khá tự giải thích: chức năng lambda chuyển đổi float thành danh sách; sau đó chúng tôi lặp qua danh sách pi cố gắng loại bỏ từng chữ số khỏi danh sách ngẫu nhiên. Nếu chúng ta có thể, tốt, hãy thêm nó vào câu trả lời; nếu không, hãy thêm một 'x' thay vào đó.


str(t)chỉ cung cấp cho bạn 11 chữ số chính xác từ t, repr(t)cung cấp cho bạn tất cả t15 chữ số.
Noodle9

1

Perl, 70 byte

$_=4*atan2(1,1);s/\d/x$&/g;for$i(rand=~/\d/g){s/x$i/$i/}s/x./x/g;print

Với nhận xét:

$_=4*atan2(1,1);        # Perl doesn't have a Pi constant
s/\d/x$&/g;             # prepend a x to all digits in Pi
for $i (rand=~/\d/g)    # iterate the digits in the random number
{ s/x$i/$i/ }           # replace first occurrence of x-nr pair 
s/x./x/g;               # strip all remaining numbers
print                   # print!

Phiên bản này sẽ in pi, số ngẫu nhiên và kết quả:

$_=$p=4*atan2(1,1);
s/\d/x$&/g;
$r=rand;
for $i ($r=~/\d/g)
{ s/x$i/$i/ }
s/x./x/g;
print "$p\n$r\n$_\n"

Ví dụ đầu ra:

3.14159265358979
0.877757977767946
x.x4x59x6xxx897x

Tôi hy vọng điều này là ổn:

  • pi chứa tổng cộng 15 chữ số, bao gồm cả 3, vì vậy nó không vượt quá độ chính xác.
  • chữ số cuối cùng ( 9) là chính xác.
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.