Tính A (N) / B (N) với các chữ số C (N)


15

Hãy xem xét ba chuỗi số, A, BC:

  • A: Một chuỗi dựa trên quan hệ tái phát f(n) = f(n-1)+f(n-2), bắt đầu bằng f(1) = 3, f(2) = 4. Vì vậy, trình tự bắt đầu như thế này:3 4 7 11 18 29 47 76 ...
  • B: Các số tổng hợp , đó là tất cả các số nguyên không phải là số nguyên tố (hoặc 1):4 6 8 9 10 12 14 15 16 ...
  • C: Các chữ số của Pi: 3 1 4 1 5 9 2 6 5 ...

Cho một số nguyên dương N < 50, dưới dạng đối số hàm hoặc STDIN, trả về giá trị thập phân của phân số A(N)/B(N)C(N)chữ số sau dấu thập phân. Các quy tắc thông thường để làm tròn được áp dụng (làm tròn lên nếu chữ số N + 1 'là 5 hoặc cao hơn). Nếu chữ số thứ n củapi bằng 0, số nguyên phải được in. ký hiệu khoa học / Dạng chuẩn được chấp nhận cho các số cao hơn 1000.

Đây là mã golf, vì vậy câu trả lời ngắn nhất trong byte thắng.

Vài ví dụ:

N = 1: 0.750
N = 2: 0.7
N = 3: 0.8750
N = 4: 1.2
N = 6: 2.416666667
N = 10: 11.056
N = 20: 764.8750

Tất nhiên, áp dụng quy tắc golf tiêu chuẩn.

Chức năng phải chấm dứt trong vòng chưa đầy hai phút trên bất kỳ máy tính xách tay hiện đại nào.


Khi bạn nói C(n)chữ số, chúng ta có phải bao gồm dấu 0 không?
Maltysen

Giới hạn thời gian áp dụng?
Dennis

@Dennis, ý bạn là Ngì? Nếu vậy, lên đến N = 49. Hay cái gì khác?
Stewie Griffin

JavaScript có độ chính xác điểm nổi giới hạn là 16. Quá khứ bạn sẽ bắt đầu nhận được kết quả không chính xác. Cái này có ổn không
Hạ cấp

1
@vihan Giải pháp của tôi (ATM chưa được công bố) lưu trữ 49 chữ số pi đầu tiên trong một chuỗi. Và bạn không cần quá 9 chữ số chính xác trong kết quả, nếu bạn lo lắng về điều đó.
Sản xuất ETH

Câu trả lời:


9

Pyth, 60 57 58 byte

.[K`.Rchu,eGsGQjT7e.ftPZQ)Je/u+/*GHhyHy^TQr^T3ZZT\0+xK\.hJ

Khai thác thử nghiệm

Điều này khá đơn giản - tính toán số pi, chuỗi Wikipedia và các vật liệu tổng hợp, làm tròn đến chữ số C (n), chữ số đến chữ số C (n) cộng với vị trí của các chữ số dấu thập phân, được thực hiện.

A (n): hu,eGsGQjT7

B (n): e.ftPZQ)

C (n): e/u+/*GHhyHy^TQr99ZZT

60 -> 57: Làm sạch trường hợp đặc biệt n = 1 trong phép tính pi.

57 -> 58: Không sử dụng số tiền đủ cao cho pi cho toàn bộ phạm vi đầu vào - tăng 99 lần lặp lên 1000 lần lặp.

Lưu ý về làm tròn: Điều này sử dụng hệ thống làm tròn "gần nhất" của Python, thay vì hệ thống "hướng tới vô cực" do OP chỉ định. Tuy nhiên, sự khác biệt chỉ quan trọng nếu các chữ số ngay sau điểm làm tròn là 5000..., ví dụ 1,25 được làm tròn thành 1 chữ số. Tôi đã kiểm tra phạm vi đầu vào, và điều này không bao giờ xảy ra, vì vậy kết quả chính xác là luôn được trả về.


2

PowerShell, 420 byte (ayyyyyyyy) 378 byte

param($n);[int[]]$p="03141592653589793238462643383279502884197169399375"-Split'';$a=@(0,3,4);for($i=3;$i-lt50;$i++){$a+=$a[$i-1]+$a[$i-2]};$c=[char[]]"00001010111010111010111011111010111110111010111011111011111010111110111";$b=@(0);for($i=4;$i-le70;$i++){if($c[$i]-eq'1'){$b+=$i}};[double]$r=$a[$n]/$b[$n];$q=$p[$n+1];$s="";(0..($q-1))|%{$s+="0"};([math]::Round($r,$q,[MidpointRounding]::AwayFromZero)).ToString("0.$s")

Cảm ơn isaacg vì đã lưu 41 byte, để tính toán cách làm tròn câu hỏi. Có nghĩa là tôi đã không bao gồm sự khủng khiếp [MidpointRounding]::AwayFromZerovà không cần phải phân vai rõ ràng như một [double].

Đây là một niềm vui lớn!

Mở rộng:

# Take input N
param($n)

# First digits of pi, stored as integer array
[int[]]$p="03141592653589793238462643383279502884197169399375"-Split''

# Fibonacci sequence A(N)
$a=@(0,3,4)
for($i=3;$i-lt50;$i++){
  $a+=$a[$i-1]+$a[$i-2]
}

# Zero-indexed bitmask for if the n-th integer is composite (1) or not (0)
$c=[char[]]"00001010111010111010111011111010111110111010111011111011111010111110111"

# Populate B(N) as an array using the $c mask
$b=@(0)
for($i=4;$i-le70;$i++){
  if($c[$i]-eq'1'){
    $b+=$i
  }
}

# Calculation Time!
$r=(a($n))/$b[$n]

# A small golf, as $p[$n+1] gets used a couple times
$q=$p[$n+1]

# Need to generate a string of zeroes for padding
$s=""
(0..($q-1))|%{$s+="0"}

# Round the number, then send it to a string so we get the necessary number of zeroes
([math]::Round($r,$q)).ToString("0.$s")

Đệ quy trong PowerShell là ... chậm, chúng ta sẽ nói, vì vậy chúng ta phải xây dựng A(N)hướng khác và lưu trữ nó thành một mảng, sau đó lập chỉ mục cho nó.


Ngoài ra, bò thần, đã làm các yêu cầu đầu ra giết chết điều này. PowerShell mặc định làm tròn số a / k / a gần nhất của ngân hàng, điều này đòi hỏi phải sử dụng các verbose đặc biệt [MidpointRounding]::AwayFromZerođể chuyển đổi kiểu làm tròn . Trên hết, sau đó chúng ta cần phải đệm các số 0 ở cuối, nếu có. Hai yêu cầu này kết hợp để biến một vài dòng cuối cùng từ 20 Byte [math]::Round($r,$q) thành 102 Byte (từ $s=""đến +$s)) ... wow.


Mô tả / bình luận tuyệt vời! 32 ký tự cho [MidpointRounding]::AwayFromZeromột mình gần như là quá tốt / xấu là đúng ... =)
Stewie Griffin

1
Xem ghi chú của tôi về làm tròn trong câu trả lời của tôi. Làm tròn mặc định PowerShell sẽ ổn.
isaacg

1

Javascript (ES6), 302 byte

Một từ: dang dở.

x=>{a=[0,3,4],b=[0],c='03141592653589793238462643383279502884197169399375';for(i=1;i<x;a[i+2]=a[i]+a[++i]);for(i=1,p=[];++i<70;v=p.every(x=>i%x),(v?p:b).push(i));r=''+Math.round(a[x]/b[x]*(l=Math.pow(10,c[x])))/l;if(x==33)return r;r.indexOf`.`<0&&(r+='.');while(!r[r.indexOf`.`+ +c[x]])r+='0';return r}

49 chữ số đầu tiên của pi được lưu trữ trong một chuỗi và hai chuỗi còn lại được tạo tự động. Điều này đã được đánh golf khoảng nửa chừng; Tôi (gần như) chắc chắn rằng tôi có thể vắt thêm 50 byte trong số đó.

Hoạt động cho tất cả các trường hợp thử nghiệm, và nên hoạt động cho phần còn lại. Tai nạn trên bất cứ thứ gì lớn hơn 49 hoặc nhỏ hơn 0 (dù sao nó cũng không bao giờ gặp phải những tình huống này). Tôi đặc biệt thích kết quả của nó cho 0:

NaN.

Tại sao điều này còn dang dở?
Beta Decay

@BetaDecay Ý tôi là tôi chưa chơi golf xong. Tôi sẽ ngay khi tôi có thời gian.
Sản xuất ETH

1

Octave, 276 236 byte

Trước hết tôi nghĩ sẽ rất tuyệt khi sử dụng một số độ chính xác không giới hạn trong các công cụ toán học này (và để làm mới một số kiến ​​thức về nó) vì vậy tôi bắt đầu viết một số thuật toán và cuối cùng kết thúc rằng pigiá trị không chính xác đến mức tôi sẽ phải sử dụng mảng một lần nữa. Vì vậy, một lần nữa, không có thành công lớn:

function c(A)p="3141592653589793238462643383279502884197169399375";f=ones (1,50);f(1)=3;f(2)=4;for i=3:53f(i)=f(i-1)+f(i-2);end
i=0;x=1;while i<A
x++;for j=2:x/2
if mod(x,j)==0 i++;break;end end end
printf(["%." p(A) "f\n"],f(A)/x);end

Vẫn còn khá dễ đọc phải không?

Sử dụng

chức năng sao chép-dán vào quãng tám, hàm gọi cvới đối số có giá trị bắt buộc:

>>> c(1)
0.750
>>> c(49)
407880480.04348

Tối ưu hóa:

  • Thay thế endif, endforvà tương tự với endhoạt động theo cùng một cách
  • giảm biến ibằng một lưu một byte
  • xóa num2str(str2num(p(A)))vô nghĩa :)

Tôi thích rằng bạn đã đăng một giải pháp Octave (bản thân tôi là một chàng trai MATLAB!). Lưu ý rằng mã này chỉ là Octave, không phải MATLAB. MATLAB sử dụng end, không endif, rất nhiều byte được lưu. Nếu bạn cũng có hộp công cụ tượng trưng cho MATLAB, bạn có thể sử dụng vpađể có đủ số thập phân cho pi : vpa(sym(pi),49). Tôi không có nó ở máy tính xách tay này, vì vậy tôi không chắc symcó cần thiết ở đó không, nhưng nên tiết kiệm khá nhiều byte dù sao =) Và có thể đọc được không nhất thiết phải là một điều tốt trong môn đánh gôn =)
Stewie Griffin

x ++ cũng không phải là lệnh MATLAB. Tôi không biết có sự khác biệt lớn như vậy giữa hai ... IMO, không nên như vậy. Tôi nghĩ rằng tất cả các mã được viết bằng Octave nên có thể được chuyển sang MATLAB (nhưng không nhất thiết phải theo cách khác vì MATLAB có nhiều tùy chọn hơn).
Stewie Griffin

Phê duyệt chỉnh sửa của bạn. Tôi không có MATLAB quanh đây vì vậy tôi không thể kiểm tra nó. Tôi đã tìm kiếm giải pháp để có được nhiều số thập phân pi hơn trong quãng tám, nhưng không có gì ngắn hơn chỉ là mảng, thật không may. Nhưng tham gia whiletừ endwhilevà tương tự hoạt động tốt, vì vậy tôi đang cập nhật câu trả lời với ít ký tự hơn :)
Jakuje
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.