(ของ KevinC) ลำดับ DeciDigits รูปสามเหลี่ยม


19

การป้อนข้อมูล:

เป็นจำนวนเต็มบวกn1 <= n <= 25000ซึ่งเป็น

เอาท์พุท:

  1. ในขั้นตอนนี้เราเริ่มต้นด้วยเลขทศนิยม 1 / n
  2. จากนั้นเราก็นำผลรวมของตัวเลขจนถึงหลักที่nหลังเครื่องหมายจุลภาค (ดัชนี 1 รายการ); ตามด้วยผลรวมของตัวเลขจนถึง ( n -1) 'th จากนั้น ( n -2)' th เป็นต้นดำเนินการต่อจนถึงnคือ 1
  3. ผลลัพธ์คือผลรวมของสิ่งเหล่านี้รวมกัน

ตัวอย่างเช่น:

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

กฏท้าทาย:

  • หากทศนิยมของ 1 / nไม่มีตัวเลขnหลังเครื่องหมายจุลภาคตัวเลขที่หายไปจะถูกนับเป็น 0 (เช่น1/2 = 0.50 => (5+0) + (5) = 10)
  • คุณใช้ตัวเลขโดยไม่ต้องปัดเศษ (เช่นตัวเลข1/6เป็น166666และไม่ใช่166667)

กฎทั่วไป:

  • กฎมาตรฐานจะใช้สำหรับคำตอบของคุณดังนั้นคุณจึงได้รับอนุญาตให้ใช้ STDIN / STDOUT ฟังก์ชัน / เมธอดพร้อมพารามิเตอร์ที่เหมาะสมโปรแกรมเต็มรูปแบบ การโทรของคุณ
  • ช่องโหว่เริ่มต้นเป็นสิ่งต้องห้าม
  • หากเป็นไปได้โปรดเพิ่มลิงค์พร้อมทดสอบรหัสของคุณ
  • นอกจากนี้โปรดเพิ่มคำอธิบายหากจำเป็น

1 - 50 รายการแรกตามลำดับ:

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 ตามลำดับ:

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

8
มีใครพูดถึงชื่อของฉันบ้างไหม?
เควิน

คำตอบ:


6

เยลลี่ขนาด 9 ไบต์

R⁵*:%⁵+\S

ค่อนข้างช้า แต่สั้น ลองออนไลน์! หรือตรวจสอบ 50 กรณีทดสอบแรก

มันทำงานอย่างไร

R⁵*:%⁵+\S  Main link. Argument: n

R          Range; yield [1, ..., n].
 ⁵*        10 power; yield [10**1, ..., 10**n].
   :       Divide each power by n.
    %⁵     Take each quotient modulo 10.
           This yields all desired decimal digits.
      +\   Take the cumulative sum of the digits.
        S  Take the sum.

15

Mathematica ขนาด 42 ไบต์

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

หรือ

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

หรือ

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

คำอธิบาย

นำตัวอย่างจากสเป็คการท้าทาย เราต้องการคำนวณ:

  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

การจัดเรียงใหม่นี่คือ:

  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)

.ผลคูณสเกลาร์อยู่ที่ไหนของเวกเตอร์สองตัว

นั่นเป็นวิธีแก้ปัญหาทั้งหมด

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

นี่ทำให้เราได้Nทศนิยมแรกของ1/N( #&@@แยกองค์ประกอบแรกของRealDigitsผลลัพธ์เพราะมันจะคืนค่าออฟเซ็ตของตัวเลขแรกที่เราไม่สนใจด้วย)

จากนั้นเราจะได้รายการจากNลงสู่การ1ใช้(#-Range@#+1)หรือRange[#,1,-1]ทั้งสองอย่างนั้นสั้นกว่าReverse@Range@#และใช้ผลิตภัณฑ์สเกลาร์

การแก้ปัญหาทางเลือกแทนที่จะใช้ในการคำนวณรายชื่อของทุกเงินก้อนคำนำหน้าแล้วเพิ่มขึ้นจำนวนเงินที่มีคำนำหน้าAccumulateTr

ตั้งแต่นี้เป็นไปอย่างรวดเร็วแม้สำหรับปัจจัยการผลิตขนาดใหญ่ที่นี่เป็นพล็อตกระจายของลำดับขึ้นไปN = 100,000(ทำทั้งหมดของพวกเขาและพวกเขาวางแผนเอาขณะที่แม้ว่า):

ป้อนคำอธิบายรูปภาพที่นี่
คลิกเพื่อดูรุ่นที่ใหญ่กว่า

เส้นสีน้ำเงินเป็นขอบเขตที่ไร้เดียงสาของ9 N (N+1) / 2(หากตัวเลขทศนิยมทั้งหมดเป็น9) และเส้นสีส้มคือครึ่งหนึ่งของที่แน่นอน น่าประหลาดใจที่นี่อยู่ในสาขาหลักของพล็อตตั้งแต่สถิติเราคาดว่าตัวเลขเฉลี่ยจะเป็น 4.5

เส้นบาง ๆ ของจุดพล็อตที่คุณสามารถดูด้านล่างสาขาหลักเศษซึ่งสิ้นสุดในขณะที่พวกเขาทั้งหมดอยู่อย่างใกล้ชิดกับ...3333...3 N (N+1) / 2


คำตอบที่ดีมากและฉันรักพล็อตกราฟ! มันเกือบจะเป็นเรื่องโชคร้ายที่มันไม่สั้นและฉันก็ไม่สามารถยอมรับมันเป็นคำตอบได้ :) ถ้าฉันไม่ลืมฉันอาจทำเงินเล็กน้อยในสองวันสำหรับการตอบรับมากกว่าการมอบหมายง่ายๆที่ฉันให้
Kevin Cruijssen

1
@KevinCruijssen ขอบคุณ! :)
Martin Ender

6

05AB1E , 12 11 ไบต์

Di<ë°¹÷.pSO

ลองออนไลน์! หรือชุดการทดสอบสำหรับ 50 หมายเลขแรก

คำอธิบาย

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

รุ่นที่มีประสิทธิภาพยิ่งขึ้นสำหรับการลองตัวเลขขนาดใหญ่บน TIO

ความแตกต่างของเวอร์ชั่นที่สั้นกว่าคือที่นี่เรารวมผลรวมของตัวเลขและการกลับรายการของดัชนี 1 รายการของพวกเขาแทนการรวมตัวเลขในคำนำหน้า

Di<ë°¹÷SDgLR*O

ลองออนไลน์!


5

Java 8, 181 169 166 153 142 ไบต์

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

คำอธิบาย:

ลองที่นี่

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 ไบต์

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

ดัดแปลงมาจากคำตอบนี้ (โดยฉันด้วย): การแบ่งของตัวเลขที่ไม่น้อยมากและการแก้ไขที่แนะนำของJörgHülsermann ใช้เช่น:

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

แก้ไข: แก้ไขข้อผิดพลาดสำหรับ +1 ไบต์และพับการมอบหมายของ $ a เป็น $ argv [1] สำหรับ -2 ไบต์สำหรับสุทธิน้อยกว่า 1 ไบต์


3

สกาลา, 84 ไบต์

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

Ungolfed:

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

คำอธิบาย:

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

ฉันจะสามารถประหยัดไบต์บางส่วนโดยการใช้ประโยชน์จากวิธีการเรียบเรียง tokenizes: โดยการเรียกอาร์กิวเมนต์&คุณสามารถเขียนแทน1 to&map กฎเดียวกันนำไปใช้กับ1 to n mapdef?


3

เยลลี่ 11 ไบต์

’aµR⁵*:µDFS

TryItOnline
50 คนแรก

ช้าเกินไปสำหรับกรณีทดสอบขนาดใหญ่

อย่างไร?

’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
ฉันไม่คิดว่าฉันเคยเห็นคำตอบของ Jelly มาก่อนซึ่งคำอธิบายนั้นเป็นเส้นตรง ;-)
ETHproductions

ฉันไม่เกือบใส่R⁵*เป็นซ้ายไปขวาเทียบเท่า แต่แล้วเห็นเส้นตรงดี :)
โจนาธานอัลลัน

3

PHP, 76 ไบต์

(แก้ไข -1 ไบต์ - ขอบคุณผู้ใช้ 59178 - ทางออกของคุณดีกว่า)

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

คุณสามารถบันทึกไบต์ (เซมิโคลอน) โดยการย้าย$c=blahเข้าไปในส่วนแรกของfor(;;)
user59178

2

MATL, 19 ไบต์

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

ลองออนไลน์!

คำอธิบาย

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 ไบต์

มันเจ็บปวดน้อยกว่าที่ฉันคาดไว้และขึ้นอยู่กับคำตอบของฉันที่นี่ :

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

คำอธิบาย

1.0g - ใช้เครื่องหมาย BigDecimal สำหรับหนึ่ง

.divide(n, n, 1)+"" - หารด้วย n ด้วยความแม่นยำ n (ฟังก์ชัน BigDecimal เท่านั้น) และแปลงเป็น str

(...)[2..x+1].getChars() - รับซับสตริงของการวนซ้ำปัจจุบันเป็นอาร์เรย์ของถ่าน

.sum()-48*(x)- รวมค่า ASCII ของอักขระและลด 48 สำหรับแต่ละองค์ประกอบ นี้จะคุ้มค่าจากหลัก ASCII *.toInteger()เพื่อจำนวนเต็มหลักประหยัดไบต์มากกว่า

(1..n).collect{...}.sum() - วนซ้ำของตัวเลขแต่ละตัวในการหารทำฟังก์ชันนี้รับทั้งหมดในอาร์เรย์และผลรวมเดี่ยว

บันทึก 2 ไบต์และประสิทธิภาพที่ลดลง ...

นี่เป็นรุ่นที่มีประสิทธิภาพมากกว่าที่ไม่คำนวณ BigDecimal ซ้ำแต่ละครั้ง

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

2

J, 27 ไบต์

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

การใช้

อินพุตเป็นจำนวนเต็มแบบขยาย

   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

ประสิทธิภาพดีและใช้เวลาเพียงประมาณ 3 วินาทีในการคำนวณสำหรับกรณีทดสอบขนาดใหญ่

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

คำอธิบาย

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

เยลลี่ 10 ไบต์

⁵*:⁸D+\_ỊS

ไม่ใช่วิธีที่สั้นที่สุดแต่มีประสิทธิภาพพอสมควร ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

มันทำงานอย่างไร

⁵*:⁸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 ไบต์

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

ไม่ใช่สวย แต่ทำโดยการแบ่งทศนิยมแล้วแปลงเป็นสตริงแล้วเลือกดัชนีสตริงซ้ำเพื่อรับสามเหลี่ยมของตัวเลขจากนั้นทำรายการความเข้าใจและแปลงถ่านแต่ละตัวให้เป็น int และสุดท้ายพวกเขาทั้งหมด


1

JavaScript (ES6), 47 ไบต์

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

มันทำงานอย่างไร

คำตอบนี้แสดงให้เห็นถึงเทคนิคในการคำนวณตัวเลขทศนิยมc / a :

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

นี่จะเป็นจุดเริ่มต้นที่ยอดเยี่ยมสำหรับความท้าทายนี้ ครั้งแรกที่เราสามารถเปลี่ยนเล็กน้อยเพื่อที่จะคำนวณตัวเลขทศนิยมของ1 / bโดยการจัดเรียงใหม่พารามิเตอร์และการตั้งค่าเริ่มต้น:

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

ต่อไปเราสามารถเปลี่ยนสิ่งนี้ได้เพื่อที่จะคำนวณผลรวมของตัวเลขทศนิยมbแรกแทนการต่อกัน (ทำกับdพารามิเตอร์):

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

เราใกล้จะแก้ปัญหาแล้ว ตอนนี้เราแค่ต้องทำให้มันคูณแต่ละหลักด้วยc + 1 :

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

อืมดูเหมือนจะยาวไปหน่อย ถ้าเราเพิ่มค่าcด้วย 1 ให้เริ่มด้วยล่ะ

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

ที่ช่วยประหยัดหนึ่งไบต์ และนี่คือวิธีการประหยัดอีกหนึ่ง:

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

และตอนนี้เรามีคำตอบ f(7)คือ 103, f(11)คือ 270, f(1)คือ ... 2? โอ้เราลืมกรณีที่a / bเป็น 1 ในการคำนวณซ้ำครั้งแรก (เช่นbคือ 1) ลองทำอะไรสักอย่างกับสิ่งนี้:

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

1 mod ขเสมอ1เว้นแต่เป็น1ซึ่งในกรณีนี้ก็จะเป็น0 โปรแกรมของเราอยู่ในขณะนี้ที่ถูกต้องสำหรับปัจจัยการผลิตทั้งหมดใน47 ไบต์



0

C, 53 ไบต์

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

ด้านล่างหลักสำหรับการทำแบบทดสอบ ...

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

ทำไมบางคนลงคะแนนนี้ เป็นเพราะข้อบกพร่องบางอย่าง? เป็นเพราะฉันไม่พบนาทีที่ถูกต้องสำหรับเขาหรือเธอ? สำหรับฉันแล้วจำนวนของถ่านก็เพียงพอแล้วและก็โอเคสำหรับ cacel คำตอบนี้ด้วยเช่นกันเพราะฉันไม่สามารถพูดได้
RosLuP

3
ดังที่คนอื่น ๆ ให้ความเห็นเกี่ยวกับคำตอบอื่น ๆ ของคุณจุดของโค้ดกอล์ฟคือการทำให้รหัสสั้นที่สุดเท่าที่จะเป็นไปได้แต่คุณยังคงรวมแมโครจำนวนมากโดยไม่มีเหตุผลที่ดี f(n,i,x,s){while(i)x=10*(x%n),s+=i--*(x/n);return s;}มีความยาว53ไบต์เท่านั้น
Dennis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.