(KevinC's) Üçgen DeciDigits Dizisi


19

Giriş:

Pozitif bir tam sayı , n olup 1 <= n <= 25000.

Çıktı:

  1. Bu sırayla ondalık sayı 1 / n ile başlıyoruz .
  2. Sonra kadar basamak kadar toplamını almak n virgül (1 endeksli) th sonra basamak'; kadar basamak kadar toplamı, ardından ( N -1) 'inci, daha sonra ( n kadar -2)' inci vb devam n 1 'dir.
  3. Çıktı , tüm bunların toplamıdır.

Örneğin:

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

Zorluk kuralları:

  • 1 ondalık / ederse n yok n rakam virgülden sonra, eksik olanları 0 (yani sayılacaktır 1/2 = 0.50 => (5+0) + (5) = 10).
  • Rakamları yuvarlamadan alırsınız (yani rakamları 1/6vardır 166666ve değildir 166667)

Genel kurallar:

  • Cevabınız için standart kurallar geçerlidir , bu nedenle STDIN / STDOUT, fonksiyon / yöntemi uygun parametrelerle, tam programları kullanmanıza izin verilir. Çağrınız.
  • Varsayılan Loopholes yasaktır.
  • Mümkünse, lütfen kodunuz için test içeren bir bağlantı ekleyin.
  • Ayrıca, gerekirse bir açıklama ekleyin.

Sıradaki ilk 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

Sıradaki son 24990-25000:

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

8
Birisi benim adımdan bahsetti mi?
Kevin

Yanıtlar:


6

Jöle , 9 bayt

R⁵*:%⁵+\S

Oldukça yavaş, ama kısa. Çevrimiçi deneyin! veya ilk 50 test vakasını doğrulayın .

Nasıl çalışır

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 bayt

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

veya

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

veya

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

açıklama

Meydan okuma özelliğinden örnek alın. Hesaplamak istiyoruz:

  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

Yeniden düzenleme, bu:

  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)

burada .iki vektörün skaler ürünüdür.

Çözümün hemen hemen hepsi bu kadar.

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

Bu bize ilk alır Nondalık basamak 1/N( #&@@özler ilk öğesiRealDigits olması da biz umurumda değil ilk basamak ofset döndürdüğü için sonuç).

Sonra gelen listesini almak Niçin aşağı 1kullanarak ya (#-Range@#+1)ya Range[#,1,-1], daha kısa, her ikisi de Reverse@Range@#ve skaler ürün almak.

Bunun yerine alternatif çözüm Accumulate, tüm önek toplamlarının bir listesini hesaplamak için kullanır ve ardından bu önek toplamlarını toplar Tr.

Bu, büyük girdiler için bile gerçekten hızlı olduğu için, dizinin bir dağılım grafiği N = 100,000( hepsini yapmak ve bunları çizmek biraz zaman aldı):

resim açıklamasını buraya girin
Büyütmek için tıklayınız.

Mavi çizgi, naif üst sınırıdır 9 N (N+1) / 2(tüm ondalık basamaklar olsaydı9 ) ve turuncu çizgi bunun tam yarısıdır. Şaşırtıcı olmayan bir şekilde, bu arsanın ana şubesinin içinde, çünkü istatistiksel olarak ortalama rakamın 4.5 olmasını bekliyorduk.

Ana dalın altında görebileceğiniz arsa noktalarının ince çizgisi, ...3333...hepsi çok yakın olduğu için biten fraksiyonlardır 3 N (N+1) / 2.


Çok güzel bir cevap, ve grafik çizim seviyorum! Bu en kısa değil neredeyse talihsiz bir durum ve cevap olarak kabul edemem. :) Unutmazsam, verdiğim basit ödevden çok daha fazlasını yanıtlamak için iki gün içinde küçük bir ödül yapabilirim.
Kevin Cruijssen

1
@KevinCruijssen Teşekkürler! :)
Martin Ender

6

05AB1E , 12 11 bayt

Di<ë°¹÷.pSO

Çevrimiçi deneyin! veya ilk 50 numara için bir Test takımı .

açıklama

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

TIO'da büyük sayıları denemek için daha verimli bir sürüm

Daha kısa versiyonun farkı, burada öneklerde rakamları toplamak yerine rakamların çarpımını ve 1 tabanlı indekslerinin tersini toplamamızdır.

Di<ë°¹÷SDgLR*O

Çevrimiçi deneyin!


5

Java 8, 181 169 166 153 142 bayt

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

Açıklama:

Burada deneyin.

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 bayt

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

Bu cevaptan uyarlandı (benim tarafımdan da): Çok az sayıdan değil , Jörg Hülsermann'ın önerdiği düzenleme. Gibi kullanın:

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

edit: +1 bayt için bir hata düzeltildi ve $ a atamasını $ argv [1] 'ye -2 bayt için net 1 bayt daha az katladı.


3

Scala, 84 bayt

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

Açıklama:

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

Derleyicinin tokenize etme şeklini kullanarak bazı baytlar kaydedebilirim: Argümanı çağırarak bunun yerine &yazabilirsiniz . Aynı kural için de geçerlidir .1 to&map1 to n mapdef?


3

Jöle , 11 bayt

’aµR⁵*:µDFS

TryItOnline
İlk 50

Büyük test durumları için çok yavaş.

Nasıl?

’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
Daha önce açıklamanın düz bir çizgi olduğu bir Jelly cevabı gördüğümü sanmıyorum ;-)
ETHproductions 14:30 '

Neredeyse R⁵*soldan sağa eşdeğer olarak koydum ama sonra güzel düz çizgi gördüm :)
Jonathan Allan

3

PHP, 76 bayt

(-1 baytını düzenle - Teşekkürler user59178 - çözümünüz daha iyi)

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

bir bayt (noktalı virgül) ' $c=blahi ilk kısmına taşıyarak kaydedebilirsinizfor(;;)
user59178

2

MATL, 19 bayt

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

Çevrimiçi deneyin!

açıklama

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 Bayt

Bu, tahmin ettiğimden daha az acı vericiydi ve buradaki cevabım üzerine kurulu :

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

açıklama

1.0g - Biri için BigDecimal gösterimini kullanın.

.divide(n, n, 1)+"" - n hassasiyetle n'ye bölün (yalnızca BigDecimal işlevi) ve str'ye dönüştürün.

(...)[2..x+1].getChars() - Geçerli yinelemenin alt dizesini karakter dizisi olarak alın.

.sum()-48*(x)- Karakterlerin ASCII değerlerini toplayın ve her öğe için 48 oranında azaltın. Bu, değeri ASCII basamağından bir tamsayıya dönüştürerek baytları temel olarak kaydeder *.toInteger().

(1..n).collect{...}.sum() - Bölmedeki her bir basamağı yineleyin, bu işlevi yaparak hepsini tek bir dizide toplayın.

2 Bayt Tasarruf ve Verimlilik Kurbanı ...

Bu, her yinelemede BigDecimal'ı yeniden hesaplamayan daha verimli bir sürümdür.

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

2

J, 27 bayt

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

kullanım

Giriş genişletilmiş bir tamsayıdır.

   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

Performans iyidir ve büyük test durumlarını hesaplamak için yalnızca 3 saniye gerekir.

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

açıklama

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

Jöle , 10 bayt

⁵*:⁸D+\_ỊS

En kısa yaklaşım değil , oldukça verimli. Çevrimiçi deneyin! veya tüm test senaryolarını doğrulayın .

Nasıl çalışır

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

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

Güzel değil, ancak şamandıra bölünmesi ve ardından bir üçgen ve daha sonra sayı üçgeni almak için yinelemeli dize dizin seçimi dönüştürülerek yapılır, daha sonra liste kavrama gerçekleştirin ve her karakter bir int dönüştürmek ve sonunda hepsini toplamak.


1

JavaScript (ES6), 47 bayt

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

Nasıl çalışır

Bu cevap hesaplamak için bir yöntem gösterilmektedir c ondalık basamak a / b :

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

Bu, bu meydan okuma için mükemmel bir başlangıç ​​noktası olacaktır. Öncelikle bunun hesaplar hafifçe böylece değiştirebilirsiniz b ondalık basamak 1 / b parametrelerini yeniden sıralama ve varsayılan ayarlayarak,:

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

Daha sonra bunu , birleştirmek yerine ilk b ondalık basamağının toplamını hesaplayacak şekilde değiştirebiliriz (bu, dparametre ile ortadan kalkar):

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

Neredeyse bir çözüme gidiyoruz; şimdi sadece her rakamı c + 1 ile çarpmamız gerekiyor :

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

Hmm, bu biraz uzun görünüyor. Başlamak için c'yi 1 arttırırsak ne olur ?

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

Bu bir bayt kazandırır. İşte bir tane daha kurtarmanın yolu:

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

Ve şimdi cevabımız var. f(7)103, f(11)270, f(1)... 2? Oh, ilk yinelemede a / b'nin 1 olduğu durumu hesaba katmayı unuttuk (yani b 1'dir). Bunun hakkında bir şeyler yapalım:

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

1 mod b her zaman 1 sürece, B ise 1 bu durumda olacaktır, 0 . Programımız artık 47 baytta tüm girişler için doğrudur .


1

Python 2, 49 bayt

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

Ideone üzerinde test edin .


0

C, 53 bayt

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

Bazı testler yapmak için ana bölümün altında ...

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

Neden birileri buna oy veriyor? çünkü bazı böcek? onun için doğru dakikayı bulamadığım için mi? Benim için karakter sayısı yeterli ve tamam bu cevap cacel için ben de konuşamıyorum diğer gibi
çekinmeyin

3
Diğerleri sizin diğer cevaplarınız hakkında yorum yaptıklarından, golf kodunun kodunu mümkün olduğunca kısa hale getirmektir, ancak iyi bir sebep olmadan bir grup makro eklemeye devam edersiniz. f(n,i,x,s){while(i)x=10*(x%n),s+=i--*(x/n);return s;}yalnızca 53 bayt uzunluğundadır.
Dennis
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.