(KevinC's) Urutan DeciDigits Segitiga


19

Memasukkan:

Bilangan bulat positif n yaitu 1 <= n <= 25000.

Keluaran:

  1. Dalam urutan ini kita mulai dengan angka desimal 1 / n .
  2. Kemudian kita mengambil jumlah digit hingga digit ke- n setelah koma (1-diindeks); diikuti oleh jumlah digit hingga ( n -1) 'th, lalu ( n -2)' th, dll. Lanjutkan hingga n adalah 1.
  3. Hasil adalah jumlah dari semua ini digabungkan.

Sebagai contoh:

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

Aturan tantangan:

  • Jika desimal 1 / n tidak memiliki n digit setelah koma, yang hilang akan dihitung sebagai 0 (yaitu 1/2 = 0.50 => (5+0) + (5) = 10).
  • Anda mengambil digit tanpa pembulatan (yaitu digit 1/6are 166666dan not166667 )

Aturan umum:

  • Aturan standar berlaku untuk jawaban Anda, jadi Anda diperbolehkan menggunakan STDIN / STDOUT, fungsi / metode dengan parameter yang tepat, program lengkap. Panggilanmu.
  • Celah Default tidak diperbolehkan.
  • Jika memungkinkan, silakan tambahkan tautan dengan tes untuk kode Anda.
  • Juga, silakan tambahkan penjelasan jika perlu.

1 - 50 pertama secara berurutan:

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

Terakhir 24990 - 25000 dalam urutan:

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

8
Apakah ada yang menyebut nama saya?
Kevin

Jawaban:


6

Jelly , 9 byte

R⁵*:%⁵+\S

Agak lambat, tapi pendek. Cobalah online! atau verifikasi 50 kasus uji pertama .

Bagaimana itu bekerja

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 byte

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

atau

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

atau

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

Penjelasan

Ambil contoh dari spec tantangan. Kami ingin menghitung:

  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

Mengatur ulang, ini adalah:

  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)

dimana . produk skalar dari dua vektor.

Cukup banyak solusinya.

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

Ini memberi kita Nangka desimal pertama 1/N(#&@@ ekstrak elemen pertama dariRealDigits hasil karena itu juga mengembalikan offset dari digit pertama yang tidak kita pedulikan).

Kemudian kita mendapatkan daftar dari Nbawah ke 1menggunakan (#-Range@#+1)atau Range[#,1,-1], keduanya lebih pendek dariReverse@Range@# , dan mengambil produk skalar.

Solusi alternatif yang digunakan Accumulateuntuk menghitung daftar semua jumlah awalan dan kemudian menambahkan jumlah awalan dengan Tr.

Karena ini sangat cepat bahkan untuk input besar, berikut adalah sebaran plot urutan hingga N = 100,000(melakukan semuanya dan memplotnya memakan waktu cukup lama):

masukkan deskripsi gambar di sini
Klik untuk versi yang lebih besar.

Garis biru adalah batas atas naif dari 9 N (N+1) / 2(jika semua angka desimal adalah9 ) dan garis oranye persis setengah dari itu. Tidak mengherankan ini tepat di dalam cabang utama plot karena, secara statistik, kami berharap angka rata-rata menjadi 4,5.

Garis tipis titik plot yang dapat Anda lihat di bawah cabang utama adalah pecahan yang berakhir ...3333..., karena semuanya terletak sangat dekat 3 N (N+1) / 2.


Jawaban yang sangat bagus, dan saya suka grafik-plot! Sangat disayangkan ini bukan yang terpendek dan saya tidak bisa menerimanya sebagai jawabannya. :) Jika saya tidak lupa, saya mungkin akan menghasilkan hadiah kecil dalam dua hari untuk menjawab jauh lebih banyak daripada tugas sederhana yang saya berikan.
Kevin Cruijssen

1
@KevinCruijssen Terima kasih! :)
Martin Ender

6

05AB1E , 12 11 byte

Di<ë°¹÷.pSO

Cobalah online! atau Test suite untuk 50 angka pertama.

Penjelasan

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

Versi yang lebih efisien untuk mencoba angka besar di TIO

Perbedaannya dengan versi yang lebih pendek adalah bahwa di sini kita menjumlahkan produk digit dan pembalikan indeks berbasis 1 mereka alih-alih menjumlahkan digit dalam awalan.

Di<ë°¹÷SDgLR*O

Cobalah online!


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

Penjelasan:

Coba di sini.

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;

Diadaptasi dari jawaban ini (juga oleh saya): Pembagian jumlah yang tidak sedikit dan saran Jörg Hülsermann yang disarankan untuk diedit. Gunakan seperti:

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

sunting: mengoreksi bug untuk +1 byte dan melipat tugas $ a menjadi $ argv [1] untuk -2 byte untuk bersih 1 byte lebih sedikit.


3

Scala, 84 byte

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

Tidak Disatukan:

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

Penjelasan:

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

Saya bisa menyimpan beberapa byte dengan mengeksploitasi cara compiler tokenizes: Dengan memanggil argumen &, Anda dapat menulis 1 to&mapalih-alih 1 to n map. Aturan yang sama berlaku untuk def?.


3

Jelly , 11 byte

’aµR⁵*:µDFS

TryItOnline
Pertama 50

Terlalu lambat untuk kasus uji besar.

Bagaimana?

’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
Saya tidak berpikir saya pernah melihat jawaban Jelly di mana penjelasannya adalah garis lurus ;-)
ETHproduk

Saya hampir menempatkan R⁵*sebagai setara kiri ke kanan tetapi kemudian melihat garis lurus yang bagus :)
Jonathan Allan

3

PHP, 76 byte

(Edit -1 byte - Terima kasih user59178 - solusi Anda bahkan lebih baik)

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

Anda bisa menyimpan byte (titik koma) dengan memindahkannya $c=blahke bagian pertamafor(;;)
user59178

2

MATL, 19 byte

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

Cobalah secara Online!

Penjelasan

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 Bytes

Ini kurang menyakitkan daripada yang saya perkirakan, dan didasarkan pada jawaban saya di sini :

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

Penjelasan

1.0g - Gunakan notasi BigDecimal untuk yang satu.

.divide(n, n, 1)+"" - Membagi dengan n dengan n presisi (fungsi BigDecimal saja) dan mengkonversi ke str.

(...)[2..x+1].getChars() - Dapatkan substring dari iterasi saat ini sebagai array char.

.sum()-48*(x)- Jumlahkan nilai ASCII dari karakter dan kurangi sebesar 48 untuk setiap elemen. Ini mengubah nilai dari angka ASCII ke Integer yang pada dasarnya menghemat byte *.toInteger().

(1..n).collect{...}.sum() - Ulangi setiap digit di divisi, lakukan fungsi ini, dapatkan semuanya dalam satu array dan jumlah.

Disimpan 2 Bytes dan Efisiensi Pengorbanan ...

Ini adalah versi yang lebih efisien yang tidak menghitung ulang BigDecimal setiap iterasi.

{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^]

Pemakaian

Inputnya adalah integer yang diperluas.

   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

Performanya bagus dan hanya membutuhkan sekitar 3 detik untuk menghitung untuk kasus uji besar.

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

Penjelasan

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

Jelly , 10 byte

⁵*:⁸D+\_ỊS

Bukan pendekatan terpendek , tetapi cukup efisien. Cobalah online! atau verifikasi semua kasus uji .

Bagaimana itu bekerja

⁵*:⁸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))])

Tidak cantik, tetapi dilakukan dengan membagi float kemudian mengkonversi ke string dan kemudian seleksi indeks string iteratif untuk mendapatkan segitiga angka, kemudian melakukan pemahaman daftar dan mengkonversi masing-masing char ke int dan akhirnya menjumlahkan mereka semua.


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)

Bagaimana itu bekerja

Jawaban ini menunjukkan teknik untuk menghitung c angka desimal dari a / b :

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

Ini akan menjadi titik awal yang sangat baik untuk tantangan ini. Pertama kita dapat mengubahnya sedikit sehingga menghitung b angka desimal 1 / b , dengan menyusun ulang parameter dan menetapkan default:

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

Selanjutnya kita dapat mengubah ini sehingga menghitung jumlah dari angka desimal b pertama, alih-alih menggabungkannya (ini menghilangkan dparameternya):

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

Kami hampir mencapai solusi; sekarang kita hanya perlu membuatnya mengalikan setiap digit dengan c + 1 :

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

Hmm, ini sepertinya agak lama. Bagaimana jika kita menambahkan c dengan 1 sebagai permulaan?

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

Itu menghemat satu byte. Dan inilah cara untuk menyimpan satu lagi:

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

Dan sekarang kita punya jawaban. f(7)adalah 103, f(11)apakah 270, f(1)apakah ... 2? Oh, kami lupa memperhitungkan kasus di mana a / b adalah 1 pada iterasi pertama (yaitu b adalah 1). Mari kita lakukan sesuatu tentang ini:

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

1 mod b selalu 1 , kecuali b adalah 1 , dalam hal ini akan menjadi 0 . Program kami sekarang benar untuk semua input, pada 47 byte .


1

Python 2, 49 byte

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

Uji di Ideone .


0

C, 53 byte

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

Di bawah utama untuk melakukan beberapa tes ...

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

Mengapa seseorang tidak memilih ini? apakah itu karena beberapa bug? apakah karena saya tidak menemukan min yang tepat untuknya? Bagi saya jumlah char sudah cukup dan ok jangan ragu untuk cacel jawaban ini juga sebagai yang lain di mana saya tidak dapat berbicara
RosLuP

3
Seperti orang lain mengomentari jawaban Anda yang lain, inti dari kode golf adalah membuat kode sesingkat mungkin , namun Anda terus menyertakan sekelompok makro tanpa alasan yang jelas. f(n,i,x,s){while(i)x=10*(x%n),s+=i--*(x/n);return s;}hanya sepanjang 53 byte.
Dennis
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.