(KevinC 's) 삼각 DeciDigits 시퀀스


19

입력:

양의 정수 n1 <= n <= 25000입니다.

산출:

  1. 이 순서에서 우리는 10 진수 1 / n으로 시작 합니다.
  2. 그런 다음 쉼표 뒤의 n 번째 자리 까지 (1 인덱싱) 자리 수를 올립니다 . ( n -1), 그 다음 ( n -2) 등이 될 때까지 자릿수를 올립니다 . 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
누군가 내 이름을 언급 했습니까?
케빈

답변:



15

수학, 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@#, 그리고 스칼라 제품을.

대체 솔루션은 대신 Accumulate모든 접두사 합계 목록을 계산하는 데 사용 하고 해당 접두사 합계를로 추가합니다 Tr.

이것은 큰 입력에서도 실제로 빠르기 때문에 여기까지의 시퀀스의 산점도가 있습니다 N = 100,000( 모두 수행 하고 플롯하는 데 다소 시간이 걸렸습니다).

여기에 이미지 설명을 입력하십시오
더 큰 버전을 보려면 클릭하십시오.

파란색 선은 순진한 상한 9 N (N+1) / 2(모든 10 진수가 모두 인 경우 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

자바 (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örg Hülsermann의 제안에 따라 수정. 다음과 같이 사용하십시오.

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

편집 : +1 바이트의 버그를 수정하고 $ 1을 $ 2의 $ argv [1]로 할당하여 1 바이트 이하의 순으로 줄였습니다.


3

스칼라, 84 바이트

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

언 골프 드 :

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

컴파일러가 토큰 화하는 방식을 활용하여 바이트를 절약 &할 수 있습니다 . argument를 호출하면 1 to&map대신 대신 쓸 수 있습니다 1 to n map. 동일한 규칙이에 적용됩니다 def?.


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
설명은 ;-) 직선이고 나는 내가 전에 젤리 대답을 본 적이 생각하지 않는다
ETHproductions

나는 거의 R⁵*왼쪽에서 오른쪽으로 동등하게 넣었 지만 멋진 직선을 보았습니다 :)
Jonathan Allan

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

그루비, 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() -현재 반복의 부분 문자열을 char 배열로 가져옵니다.

.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

파이썬 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))])

예쁘지 않지만 float 나누기를 통해 문자열로 변환 한 다음 반복적 인 문자열 인덱스 선택을 통해 숫자의 삼각형을 얻은 다음 목록 이해를 수행하고 각 문자를 int로 변환하고 마지막으로 모두 합산합니다.


1

자바 스크립트 (ES6), 47 바이트

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

작동 원리

이 답변a / bc 소수 자릿수 를 계산하는 기술을 보여줍니다 .

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

이것은이 도전에 대한 훌륭한 출발점이 될 것입니다. 처음에 우리는 그것을 계산하는 약간 너무 변경할 수 있습니다 B 의 진수를 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

그것은 1 바이트를 절약합니다. 그리고 하나 더 저장하는 방법이 있습니다 :

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 모드 B는 항상 1 않으면, B는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 
*/

왜 누군가가 이것을 투표하지? 버그 때문인가요? 내가 그에게 적합한 분을 찾지 못했기 때문입니까? 나를 위해 그 문자의 수는 충분하고 괜찮습니다. 소포를 위해 자유롭게 느끼십시오. 나는 말할 수없는 다른 대답으로도
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.