(KevinC's) Chuỗi tam giác DeciDigits


19

Đầu vào:

Một số nguyên dương n1 <= n <= 25000.

Đầu ra:

  1. Trong chuỗi này, chúng tôi bắt đầu với số thập phân 1 / n .
  2. Sau đó chúng ta lấy tổng các chữ số lên cho đến khi n 'th chữ số sau dấu phẩy (1-lập chỉ mục); theo sau là tổng các chữ số cho đến ( n -1) 'th, sau đó ( n -2)', v.v ... Tiếp tục cho đến n là 1.
  3. Đầu ra là tổng của tất cả những kết hợp này.

Ví dụ:

n = 7
1/7 = 0.1428571428...
7th digit-sum = 1+4+2+8+5+7+1 = 28
6th digit-sum = 1+4+2+8+5+7 = 27
5th digit-sum = 1+4+2+8+5 = 20
4th digit-sum = 1+4+2+8 = 15
3rd digit-sum = 1+4+2 = 7
2nd digit-sum = 1+4 = 5
1st digit     = 1
Output = 28+27+20+15+7+5+1 = 103

Quy tắc thử thách:

  • Nếu số thập phân 1 / n không có n chữ số sau dấu phẩy thì những chữ số còn thiếu sẽ được tính là 0 (nghĩa là 1/2 = 0.50 => (5+0) + (5) = 10).
  • Bạn lấy các chữ số mà không làm tròn (tức là các chữ số 1/6166666và không 166667)

Quy tắc chung:

  • Các quy tắc chuẩn áp dụng cho câu trả lời của bạn, vì vậy bạn được phép sử dụng STDIN / STDOUT, các hàm / phương thức với các tham số thích hợp, các chương trình đầy đủ. Cuộc gọi của bạn.
  • Lỗ hổng mặc định bị cấm.
  • Nếu có thể, vui lòng thêm một liên kết với một bài kiểm tra cho mã của bạn.
  • Ngoài ra, xin vui lòng thêm một lời giải thích nếu cần thiết.

1 - 50 đầu tiên trong chuỗi:

0, 10, 18, 23, 10, 96, 103, 52, 45, 10, 270, 253, 402, 403, 630, 183, 660, 765, 819, 95, 975, 1034, 1221, 1500, 96, 1479, 1197, 1658, 1953, 1305, 1674, 321, 816, 2490, 2704, 4235, 2022, 3242, 2295, 268, 2944, 3787, 3874, 4097, 1980, 4380, 4968, 3424, 4854, 98

24990 - 25000 cuối cùng trong chuỗi:

1405098782, 1417995426, 1364392256, 1404501980, 1408005544, 1377273489, 1395684561, 1405849947, 1406216741, 1142066735, 99984

8
Có ai nhắc đến tên tôi không?
Kevin

Câu trả lời:



15

Toán học, 42 byte

#&@@RealDigits[1/#,10,#,-1].(#-Range@#+1)&

hoặc là

#&@@RealDigits[1/#,10,#,-1].Range[#,1,-1]&

hoặc là

Tr@Accumulate@#&@@RealDigits[1/#,10,#,-1]&

Giải trình

Lấy ví dụ từ thông số kỹ thuật thách thức. Chúng tôi muốn tính toán:

  1+4+2+8+5+7+1
+ 1+4+2+8+5+7
+ 1+4+2+8+5
+ 1+4+2+8
+ 1+4+2
+ 1+4
+ 1

Sắp xếp lại, đây là:

  1*7 + 4*6 + 2*5 + 8*4 + 5*3 + 7*2 + 1*1
= (1, 4, 2, 8, 5, 7, 1) . (7, 6, 5, 4, 3, 2, 1)

trong đó .sản phẩm vô hướng của hai vectơ.

Đó là khá nhiều tất cả các giải pháp làm.

#&@@RealDigits[1/#,10,#,-1]

Điều này mang lại cho chúng tôi các Nchữ số thập phân đầu tiên của 1/N( #&@@trích phần tử đầu tiên của RealDigitskết quả vì điều đó cũng trả về phần bù của chữ số đầu tiên mà chúng tôi không quan tâm).

Sau đó chúng tôi nhận được danh sách từ Nxuống 1hoặc sử dụng (#-Range@#+1)hoặc Range[#,1,-1], cả hai đều là ngắn hơn Reverse@Range@#, và lấy sản phẩm vô hướng.

Thay vào đó, giải pháp thay thế sử dụng Accumulateđể tính toán danh sách tất cả các tổng tiền tố và sau đó cộng các tổng tiền tố đó với Tr.

Vì điều này thực sự nhanh ngay cả đối với các đầu vào lớn, nên đây là một biểu đồ phân tán của chuỗi lên đến N = 100,000(thực hiện tất cả chúng và vẽ sơ đồ chúng mất một lúc):

nhập mô tả hình ảnh ở đây
Nhấn vào đây để xem phiên bản lớn hơn.

Đường màu xanh là giới hạn trên ngây thơ của 9 N (N+1) / 2(nếu tất cả các chữ số thập phân là 9) và đường màu cam chính xác bằng một nửa. Không có gì đáng ngạc nhiên khi điều này nằm ngay trong nhánh chính của cốt truyện vì theo thống kê, chúng tôi hy vọng chữ số trung bình là 4,5.

Dòng điểm cốt truyện mỏng mà bạn có thể thấy bên dưới nhánh chính là các phân số kết thúc ...3333..., vì tất cả chúng đều nằm rất gần nhau 3 N (N+1) / 2.


Câu trả lời rất hay, và tôi thích cốt truyện đồ thị! Thật không may, đây không phải là ngắn nhất và tôi không thể chấp nhận nó là câu trả lời. :) Nếu tôi không quên tôi có thể kiếm một khoản tiền thưởng nhỏ trong hai ngày để trả lời nhiều hơn so với nhiệm vụ đơn giản mà tôi đã đưa ra.
Kevin Cruijssen

1
@KevinCruijssen Cảm ơn! :)
Martin Ender

6

05AB1E , 12 11 byte

Di<ë°¹÷.pSO

Hãy thử trực tuyến! hoặc một bộ Kiểm tra cho 50 số đầu tiên.

Giải trình

              # implicit input n
Di<           # if n == 1 then 0
   ë          # else
    °¹÷       # 10^n // n
       .p     # get prefixes
         SO   # sum digits

Phiên bản hiệu quả hơn để thử số lượng lớn trên TIO

Sự khác biệt so với phiên bản ngắn hơn là ở đây chúng tôi tổng hợp sản phẩm của các chữ số và đảo ngược chỉ số dựa trên 1 của chúng thay vì tổng các chữ số trong tiền tố.

Di<ë°¹÷SDgLR*O

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


5

Java 8, 181 169 166 153 142 byte

import java.math.*;n->{int m=n+2,r=0,i;for(;m>2;)for(i=m--;i-->2;r+=(BigDecimal.ONE.divide(new BigDecimal(n),n,3)+"").charAt(i)-48);return r;}

Giải trình:

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

import java.math.*;   // Required import for BigDecimal

n->{                  // Method with integer as both parameter and return-type
  int m=n+2,          //  Copy of the input-integer plus 2
      r=0,            //  Result-integer, starting at 0
      i;              //  Index-integer
  for(;m>2;)          //  Loop (1) as long as `m` is larger than 2
    for(i=m--;        //   Set index `i` to `m`, and decrease `m` by one afterwards
        i-->2;        //   Inner loop (2) from `m` down to 2 (inclusive)
      r+=             //    Add to the result-sum:
         (BigDecimal.ONE.divide(
                      //     1 divided by,
           new BigDecimal(n),
                      //     the input
           n,3)       //     With the minimal required precision
          +"")        //     Convert this to a String
          .charAt(i)  //     Take the character of this String at index `i`
          -48         //     And convert it to a number
     );               //   End of inner loop (2)
                      //  End of loop (1) (implicit / single-line body)
  return r;           //  Return result
}                     // End of method

4

PHP, 66 65 byte

for($b=$c=$argv[$a=1];$c;)$o+=$c--*(($a=10*($a%$b))/$b^0);echo$o;

Chuyển thể từ câu trả lời này (cũng bởi tôi): Phân chia số lượng không quá ít và đề xuất chỉnh sửa của Jörg Hülsermann cho nó. Sử dụng như:

php -r "for($b=$c=$argv[$a=1];$c;)$o+=$c--*(($a=10*($a%$b))/$b^0);echo$o;" 7

chỉnh sửa: đã sửa một lỗi cho +1 byte và gấp phần gán $ a thành $ argv [1] cho -2 byte cho mạng nhỏ hơn 1 byte.


3

Scala, 84 byte

val b=BigDecimal
def?(& :Int)=1 to&map(x=>(""+b(1)/b(&))slice(2,x+2)map(_-48)sum)sum

Ung dung:

def f(n: Int)={
  val digits = ""+BigDecimal(1)/BigDecimal(n)
  (1 to n).map( x=>
    digits.slice(2, x+2).map(d => d - 48).sum
  ).sum

Giải trình:

val b=BigDecimal   //define an alias for BigDecimal
def?(& :Int)=      //define a method called ? with an integer & as a parameter
  1 to &           //create a range from 1 to &
  map(x=>          //for each number x...
    (""+b(1)/b(&))   //calculate the fraction
    slice(2,x+2)     //and take the slice starting from the third element,
                     //(dropping the "1.") and containing x elements
    map(_-48)        //for each char, subtract 48 to get the integer value
    sum              //and sum them
  )sum             //and take the sum

Tôi có thể lưu một số byte bằng cách khai thác cách trình biên dịch mã hóa: Bằng cách gọi đối số &, bạn có thể viết 1 to&mapthay vì 1 to n map. Quy tắc tương tự áp dụng cho def?.


3

Thạch , 11 byte

’aµR⁵*:µDFS

TryItOnline
50 đầu tiên

Quá chậm cho các trường hợp thử nghiệm lớn.

Làm sao?

’aµR⁵*:µDFS - Main link: n
’           - decrement
 a          - and (to handle special case where n=1, to return 0 rather than 10)
  µ         - monadic chain separation
   R        - range: [1,2,...n]
    ⁵       - literal 10
     *      - exponentiation: [10,100,...,10^n]
      :     - integer division: [10//n,100//n,...,10^n//n]
       µ    - monadic chain separation
        D   - cast to a decimal list [[digits of 10//n],[digits of 100//n],...]
         F  - flatten into one list
          S - sum

2
Tôi không nghĩ rằng tôi đã từng thấy một câu trả lời Jelly trong đó lời giải thích là một đường thẳng ;-)
ETHproductions

Tôi đã gần như đặt từ R⁵*trái sang phải tương đương nhưng sau đó thấy đường thẳng đẹp :)
Jonathan Allan

3

PHP, 76 byte

(Chỉnh sửa -1 byte - Cảm ơn người dùng59178 - giải pháp của bạn thậm chí còn tốt hơn)

for($c=substr(bcdiv(1,$a=$argv[1],$a),2);$i<$a;)$s+=($a-$i)*$c[$i++];echo$s;

bạn có thể lưu một byte (dấu chấm phẩy) bằng cách di chuyển $c=blahvào phần đầu tiên củafor(;;)
user59178

2

MATL, 19 byte

li/GEY$4LQ)!UYsG:)s

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

Giải trình

l       % Push a 1 literal to the stack
i/      % Grab the input (n) and compute 1/n
GE      % Grab the input again and multiply by 2 (2n)
Y$      % Compute the first 2n digits of 1/n after the decimal
4LQ)    % Get only the digits past the decimal point
!U      % Convert to numbers
Ys      % Compute the cumulative sum
G:)     % Get the first n terms
s       % Sum the result and implicitly display

2

Groovy, 87 byte

Điều này ít đau đớn hơn tôi dự đoán, và dựa trên câu trả lời của tôi ở đây :

{n->(1..n).collect{x->(1.0g.divide(n, n, 1)+"")[2..x+1].getChars().sum()-48*(x)}.sum()}

Giải trình

1.0g - Sử dụng ký hiệu BigDecimal cho một.

.divide(n, n, 1)+"" - Chia cho n với độ chính xác n (chỉ chức năng BigDecimal) và chuyển đổi thành str.

(...)[2..x+1].getChars() - Lấy chuỗi con của lần lặp hiện tại dưới dạng một mảng char.

.sum()-48*(x)- Tính tổng các giá trị ASCII của các ký tự và giảm 48 cho mỗi phần tử. Điều này biến giá trị từ chữ số ASCII thành Số nguyên về cơ bản tiết kiệm byte *.toInteger().

(1..n).collect{...}.sum() - Lặp lại từng chữ số trong phép chia, thực hiện chức năng này, lấy tất cả chúng trong một mảng và tổng.

Đã lưu 2 byte và hiệu quả hy sinh ...

Đây là phiên bản hiệu quả hơn, không tính toán lại BigDecimal mỗi lần lặp.

{n->i=1.0g.divide(n, n, 1)+"";(1..n).collect{x->i[2..x+1].getChars().sum()-48*(x)}.sum()}

2

J, 27 byte

1#.[:+/\-{.10#.inv%<.@*10^]

Sử dụng

Đầu vào là một số nguyên mở rộng.

   f =: 1#.[:+/\-{.10#.inv%<.@*10^]
   (,.f"0) (>: i. 50x) , 24990x + i. 11
    1          0
    2         10
    3         18
    4         23
    5         10
    6         96
    7        103
    8         52
    9         45
   10         10
   11        270
   12        253
   13        402
   14        403
   15        630
   16        183
   17        660
   18        765
   19        819
   20         95
   21        975
   22       1034
   23       1221
   24       1500
   25         96
   26       1479
   27       1197
   28       1658
   29       1953
   30       1305
   31       1674
   32        321
   33        816
   34       2490
   35       2704
   36       4235
   37       2022
   38       3242
   39       2295
   40        268
   41       2944
   42       3787
   43       3874
   44       4097
   45       1980
   46       4380
   47       4968
   48       3424
   49       4854
   50         98
24990 1405098782
24991 1417995426
24992 1364392256
24993 1404501980
24994 1408005544
24995 1377273489
24996 1395684561
24997 1405849947
24998 1406216741
24999 1142066735
25000      99984

Hiệu suất là tốt và chỉ cần khoảng 3 giây để tính toán cho các trường hợp thử nghiệm lớn.

   timex 'f 7x'
0.000119
   timex 'f 24999x'
3.8823
   timex 'f 25000x'
3.14903

Giải trình

1#.[:+/\-{.10#.inv%<.@*10^]  Input: n
                          ]  Get n
                       10^   Raise 10 to the nth power
                  %          Get the reciprocal of n
                      *      Multiply (1/n) with (10^n)
                   <.@       Floor it
           10#.inv           Convert it to a list of base 10 digits
        -                    Negate n
         {.                  Take the last n values from the list of digits
                             (This is to handle the case for n = 1)
   [:  \                     For each prefix of the list of digits
     +/                        Reduce it using addition to get the sum
1#.                          Convert those sums as base 1 digits and return
                             (This is equivalent to taking the sum)

2

Thạch , 10 byte

⁵*:⁸D+\_ỊS

Không phải là cách tiếp cận ngắn nhất , nhưng khá hiệu quả.Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

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

⁵*:⁸D+\_ỊS  Main link. Argument: n (integer)

⁵*          Yield 10**n.
  :⁸        Divide 10**n by n (integer division).
    D       Convert the quotient to base 10.
     +\     Take the cumulative sum of the digits.
        Ị   Insignificant; yield (abs(n) <= 1).
       _    Subtract the resulting Boolean from each decimal digit.
            This takes care of edge case n = 1, which would return 2 otherwise.
         S  Take the sum.

1

Python 2, 90 byte

lambda o:sum([sum([int(i)for i in s])for s in map(lambda x:str(1.0/o)[2:x],range(3,3+o))])

Không đẹp, nhưng được thực hiện thông qua phép chia float, sau đó chuyển đổi thành chuỗi và sau đó chọn chỉ số chuỗi lặp để lấy tam giác số, sau đó thực hiện việc hiểu danh sách và chuyển đổi từng char thành int và cuối cùng là tổng hợp tất cả.


1

JavaScript (ES6), 47 byte

f=(b,a=1%b,c=b+1)=>c&&(a/b|0)*c+f(b,a%b*10,c-1)

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

Câu trả lời này cho thấy một kỹ thuật tính c chữ số thập phân của a / b :

f=(a,b,c,d=".")=>~c?(a/b|0)+d+f(a%b*10,b,c-1,""):d

Điều này sẽ làm cho một điểm khởi đầu tuyệt vời cho thử thách này. Đầu tiên chúng ta có thể thay đổi nó một chút để nó tính b chữ số thập phân 1 / b , bằng cách sắp xếp lại các tham số và đặt mặc định:

f=(b,a=1,c=b,d=".")=>~c?(a/b|0)+d+f(b,a%b*10,c-1,""):d

Tiếp theo, chúng ta có thể thay đổi điều này để nó tính tổng của các chữ số thập phân b đầu tiên , thay vì nối chúng (điều này không đi với dtham số):

f=(b,a=1,c=b)=>~c?(a/b|0)+f(b,a%b*10,c-1):0

Chúng tôi gần như là một giải pháp; bây giờ chúng ta chỉ cần làm cho nó nhân mỗi chữ số với c + 1 :

f=(b,a=1,c=b)=>~c?(a/b|0)*-~c+f(b,a%b*10,c-1):0

Hmm, điều này có vẻ hơi dài. Điều gì xảy ra nếu chúng ta tăng c lên 1 để bắt đầu?

f=(b,a=1,c=b+1)=>c?(a/b|0)*c+f(b,a%b*10,c-1):0

Điều đó tiết kiệm một byte. Và đây là một cách để tiết kiệm thêm một:

f=(b,a=1,c=b+1)=>c&&(a/b|0)*c+f(b,a%b*10,c-1)

Và bây giờ chúng tôi có câu trả lời của chúng tôi. f(7)là 103, f(11)là 270, f(1)là ... 2? Ồ, chúng tôi đã quên tính đến trường hợp a / b là 1 trong lần lặp đầu tiên (tức là b là 1). Hãy làm gì đó về điều này:

f=(b,a=1%b,c=b+1)=>c&&(a/b|0)*c+f(b,a%b*10,c-1)

1 mod b luôn là 1 , trừ khi b1 , trong trường hợp đó sẽ là 0 . Chương trình của chúng tôi hiện chính xác cho tất cả các đầu vào, ở mức 47 byte .


1

Python 2, 49 byte

lambda n:sum(10**-~k/n%10*(n-k)for k in range(n))

Kiểm tra nó trên Ideone .


0

C, 53 byte

f(n,i,x,s){while(i)x=10*(x%n),s+=i--*(x/n);return s;}

Bên dưới chính để làm một số thử nghiệm ...

//44,79
#define R return
#define F for
#define U unsigned
#define N int
#define B break
#define I if
#define L(i) for(;i-->0;)
#define J(a,b)  if(a)goto b
#define G goto
#define P printf
#define D double
#define C unsigned char
#define A getchar()
#define O putchar
#define M main
#define Y malloc
#define Z free
#define S sizeof
#define T struct
#define E else
#define Q static
#define X continue  
main()
{N  k, a=0, b=0, i;

 F(i=1;i<50;++i) 
       P("f(%u)=%u |", i, f(i,i,1,0));
 P("\n");
 F(i=24990;i<=25000;++i) 
       P("f(%u)=%u |", i, f(i,i,1,0));
 P("\n");
 R 0;
}

/*
f(1)=0 |f(2)=10 |f(3)=18 |f(4)=23 |f(5)=10 |f(6)=96 |f(7)=103 |f(8)=52 |f(9)=45
f(10)=10 |f(11)=270 |f(12)=253 |f(13)=402 |f(14)=403 |f(15)=630 |f(16)=183 |f(17)=660 
f(18)=765 |f(19)=819 |f(20)=95 |f(21)=975 |f(22)=1034 |f(23)=1221 |f(24)=1500
f(25)=96 |f(26)=1479 |f(27)=1197 |f(28)=1658 |f(29)=1953 |f(30)=1305 |f(31)=1674
f(32)=321 |f(33)=816 |f(34)=2490 |f(35)=2704 |f(36)=4235 |f(37)=2022 |f(38)=3242
f(39)=2295 |f(40)=268 |f(41)=2944 |f(42)=3787 |f(43)=3874 |f(44)=4097 |f(45)=1980
f(46)=4380 |f(47)=4968 |f(48)=3424 |f(49)=4854 |
f(24990)=1405098782 |f(24991)=1417995426 |f(24992)=1364392256 |f(24993)=1404501980
f(24994)=1408005544 |f(24995)=1377273489 |f(24996)=1395684561 |f(24997)=1405849947 
f(24998)=1406216741 |f(24999)=1142066735 |f(25000)=99984 
*/

Tại sao ai đó xuống bỏ phiếu này? Có phải vì một số lỗi? Có phải vì tôi không tìm được min phù hợp với anh ấy hay cô ấy? Đối với tôi số char đó là đủ và ok cảm thấy thoải mái vì câu trả lời này cũng như câu trả lời khác mà tôi không thể nói
RosLuP

3
Như những người khác đã nhận xét về các câu trả lời khác của bạn, quan điểm của môn đánh gôn là làm cho mã càng ngắn càng tốt , tuy nhiên bạn tiếp tục đưa vào một loạt các macro mà không có lý do chính đáng. f(n,i,x,s){while(i)x=10*(x%n),s+=i--*(x/n);return s;}chỉ dài 53 byte.
Dennis
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.