더하기 곱하기 더하기 시퀀스


27

( 관련 )

정수 감안할 때 n > 1,
1) 숫자의 범위를 구축 n, n-1, n-2, ... 3, 2, 1하고 합계 계산
2) 그 숫자의 각 숫자를 가지고 및 제품 계산
3)의 각 숫자 가지고 수와 합계 계산
4)를 반복하면 때까지 2, 3 단계 한 자릿수에 도달합니다. 그 숫자가 결과입니다.

시퀀스의 처음 20 개 용어는 다음과 같습니다.

3, 6, 0, 5, 2, 7, 9, 2, 7, 9, 1, 9, 0, 0, 9, 6, 7, 0, 0, 6

참고 :이 순서는 OEIS에 없습니다.

I / O 및 규칙

  • 숫자는 매우 빠르게 커지므로 솔루션은 실패없이 최대 100,000 개의 입력 숫자를 처리 할 수 ​​있어야합니다 (코드가 그 이상을 처리 할 수 ​​있다면 괜찮습니다).
  • 입력 및 출력은 편리한 방법 으로 제공 할 수 있습니다 .
  • 전체 프로그램 또는 기능이 허용됩니다. 함수 인 경우 출력하지 않고 출력을 반환 할 수 있습니다.
  • 표준 허점 은 금지되어 있습니다.
  • 이것은 이므로 모든 일반적인 골프 규칙이 적용되며 가장 짧은 코드 (바이트)가 이깁니다.

n     output
1234   9
3005   3
5007   5
9854   8
75849  8
100000 0

3
OEIS에없는 시퀀스 챌린지에 +1
JAD

2
n ≤ 100000 일 때마다 단계 2와 3의 두 번의 반복만으로도 결과를 얻을 수 있습니다. 우리는 그것을 이용할 수 있습니까 ? 아니면 우리가 선택한 알고리즘이 더 큰 n 값에 대해 작동해야 합니까?
Dennis

2
@Dennis 알고리즘은의 모든 값에 대해 작동해야합니다 n. 게시 된 솔루션은 최대 작동해야합니다 n = 100000.
AdmBorkBork

3
Numbers will get very large quickly아니 그것은하지 않습니다
l4m2

3
@ l4m2 출력이 아닙니다. 그러나 100000 + 99999 + ... + 1 = 5000050000 은 33 비트 숫자이며, 선택한 언어에 따라 표현에 문제가 있거나 없을 수 있습니다.
Dennis

답변:


10

파이썬 2 , 77 72 71 62 60 바이트

lambda n:reduce(lambda x,c:eval(c.join(`x`)),'*+'*n,-n*~n/2)

2 바이트를 골라 낸 @xnor에게 감사드립니다!

온라인으로 사용해보십시오!


나는 단지 for 루프로 전환,하지만 미래에 대한 그 트릭을 기억해야합니다.
Dennis

어디있어 repeat until you reach a single digit?
Titus

2
@Titus 2 단계와 3 단계를 n 번 반복 하면 충분합니다. 실제로 n ≤ 100000 이기 때문에 세 번의 반복으로 충분합니다.
Dennis

이제 당신이 그것을 언급했습니다 : 실제로, 세 번의 반복이 필요한 가장 작은 입력은 236172; 그리고 그것은 백만 미만의 유일한 것입니다.
Titus



4

젤리 , 8 바이트

RSDPDƲÐL

온라인으로 사용해보십시오!

전체 프로그램 (결과가 포함 된 싱글 톤 배열을 반환하지만 대괄호는 STDOUT에 표시되지 않음)


이것은 내가 본 것 중 가장 "자연스럽게 보이는"젤리 답변입니다. 비 ASCII 문자는 2 개뿐입니다
RedClover


어, 여기서 논의 할 수 없어요, 고마워요 : P TNB는 소음이없는 경우 이에 대해 논의 할 수있는 대체 장소가 될 수 있습니다. ;)
Outgolfer Erik

4

MATL , 15 13 바이트

이 달언어에 대한 찬사 :

:`sV!UpV!Utnq

온라인으로 사용해보십시오!

숫자를 문자열로 변환 V한 다음 !변환 하고이 수직 벡터를 다시 숫자 로 변환하는 것보다 숫자의 숫자를 얻는 간단한 방법이 없다고 생각 U합니다.

Creator 1 덕분에 2 바이트를 절약 했습니다! 나는 암시 적 끝을 잊어 버렸고, 제거 할 수 있음을 의미 ]하고 요소 수를와 비교하는 대신 1단순히 그 값을 줄이고 부울로 직접 사용할 수 있습니다.

따라서 설명은 다음과 같습니다.

                 % Grab input n implicitly
:                % Range from 1 ... n inclusive
 `               % Do ... while
  s               % sum the vector
   V!U            % Convert the number to digits
      p           % Take the product of these digits
       V!U        % Convert the product into digits
          t       % Duplicate the result
           n      % Count the number of elements
            q     % Decrement the number of elements
                  % Loop until the number of elements is 1
                 % Implicit end

1 ... MATL, Luis Mendo.


3

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

f=(n,k=n*++n/2)=>k>9?f(!n,eval([...k+''].join('*+'[+!n]))):k

온라인으로 사용해보십시오!

댓글

f = (                     // f = recursive function taking:
  n,                      //   n = original input
  k = n * ++n / 2         //   k = current value, initialized to sum(i=1..n)(i)
) =>                      //
  k > 9 ?                 // if k has more than 1 digit:
    f(                    //   recursive call to f() with:
      !n,                 //     a logical NOT applied to n
      eval(               //     the result of the expression built by:
        [...k + '']       //       turning k into a list of digits
        .join('*+'[+!n])  //       joining with '*' on even iterations or '+' on odd ones
      )                   //     end of eval()
    )                     //   end of recursive call
  :                       // else:
    k                     //   stop recursion and return the last value

대체 버전, 59 바이트 (비경쟁)

n <236172 에서만 작동하는 비 재귀 버전입니다 . (요청한 범위를 다루지 만 유효한 일반 알고리즘으로 적합하지 않습니다.)

n=>[...'*+*+'].map(o=>n=eval([...n+''].join(o)),n*=++n/2)|n

온라인으로 사용해보십시오!


N> = 77534568790 일 때 주 버전이 깨집니다. N = 7753456879 일 때 작동합니다. 중단 점이 정확히 어디에 있는지 확실하지 않습니다. 물론, requirment는 최대 N = 100,000까지만 처리하기 때문에 문제가되지 않습니다. 따라서 왜 이것을 작성했는지 모르겠습니다. ...
Ross Presser

1
@RossPresser 대략적인 추정으로, 나는 그것이 최대 작동한다고 말하고 싶습니다 Number.MAX_SAFE_INTEGER ** 0.5 ~= 94906265.
Arnauld


2

Stax , 14 13 10 바이트

ñu┌↕a√äJ²┐

실행 및 디버깅

꽤 재미있었습니다. 마지막에 비교를 할 수있는 더 간결한 방법이 있는지 궁금합니다.

설명

|+wE:*E|+c9>                 # Full Program Unpacked
|+                           # Create range and sum it
   wE:*                      # Start loop, digitize number, product of digits
       E|+                   # Digitize number, sum digits
          c9>                # Duplicate, check length is = 1
                             # Otherwise loop back to the 'w' character

ovs 덕분에 -1 바이트

Scrooble 덕분에 -3 바이트


2

R , 152130109 바이트

function(w,x=w*(w+1)/2,y=prod(d(x)),z=sum(d(y)))"if"(z>9,f(,z),z)
d=function(x)x%/%10^(0:max(0,log10(x)))%%10

온라인으로 사용해보십시오!

@Giuseppe는 문자열과 뒤로를 강제하지 않고 더 적은 바이트로 숫자의 자릿수를 얻는 방법과 함께 아직 익숙하지 않은 다양한 R을 가진 21 42 바이트를 찾았습니다 !

# Old
d=function(x)strtoi(el(strsplit(paste(x),"")))
# New
d=function(x)x%/%10^(0:max(0,log10(x)))%%10

options(scipen=9) 되고 제 생성물 스테이지 8E + 05 80000, R 인쇄로 끝나는 때문에, 기존의 기능에 대한 9,854의 경우에 필요 하였다.


아, 알겠습니다 과학적 표기법 출력. 잘 잡아!
AdmBorkBork

1
마지막으로 주위에 도착 scipen: 온라인 사용해보십시오 ! (가)주의 max(0,log10(x))때문에 경우이며 x=0다음 log10(0)=-Inf오류가 발생한다.
주세페

1

Pyth , 11 바이트

usj*FjGTTsS

여기 사용해보십시오!

usj * FjGTTsS – 전체 프로그램. N = 입력
          S – 범위. 수율 [1, N] ⋂ ℤ.
         s – 합계
u – 두 번의 연속 반복으로 동일한 결과가 나오지 않지만 (var : G) :
   * FjGT – 디지털 제품.
 sj T – 디지털 합계.

1

, 18 바이트

≔Σ…·¹NθW›θ⁹≔ΣΠθθIθ

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 설명:

≔Σ…·¹Nθ

입력까지 정수를 합산하십시오.

 W›θ⁹≔ΣΠθθ

결과가 9보다 크지 만 숫자 곱의 자릿수를 취하십시오.

Iθ

결과를 문자열로 캐스트하고 내재적으로 인쇄하십시오.


1

Gaia , 8 바이트

┅⟨Σ₸∨Π⟩°

온라인으로 사용해보십시오!

이전 설명 (Gaia의 결함 IMO : P 인 버그를 수정하기 전) :

┅⟨ΣΠ⟩ ° – 전체 프로그램. N = 입력
┅ – 범위. 스택으로 [1, N] ⋂ ℤ을 누릅니다.
 ⟨⟩ ° – 두 번의 반복이 동일한 결과를 생성하지는 않지만
  Σ – 합 (또는 정수에 적용될 때 디지털 합).
   Π – 디지털 제품.

Dennis 덕분에 1 바이트를 절약했습니다 .


┅⟨ΣΠ⟩°바이트를 저장합니다.
Dennis

디지털 합계가 0 인 값으로는 작동하지 않습니다.4
Jo King

@JoKing 고정 해주셔서 감사합니다. 불행하게도 Gaia 0에서 []어떤 이유로 결과 의 숫자를 가져옵니다. (
Mr. Xcoder

1

F #, 175 바이트

let d n=seq{for i in(string n).ToCharArray() do yield string i|>uint64}
let c n=
 let mutable r=Seq.sum{1UL..n}
 while r>9UL do r<-d r|>Seq.reduce(fun a x->x*a)|>d|>Seq.sum
 r

온라인으로 사용해보십시오!

함수의 유일한 경고는 입력 값이 유형이어야한다는 것입니다 uint64.

Ungolfed는 다음과 같습니다.

let d n=seq{for i in(string n).ToCharArray() do yield string i|>uint64}

let c n =
 let mutable r = Seq.sum {1UL..n}
 while r > 9UL do
  r<-d r
  |> Seq.reduce(fun a x->x*a)
  |> d
  |> Seq.sum
 r

이 함수 d n는 숫자 n를 구성 요소 숫자로 변환합니다 . 먼저 문자열로 변환 한 다음 문자열의 각 문자를 가져옵니다. 그런 다음 각 문자를 다시 문자열로 변환해야합니다. 그렇지 않으면 문자가 "실제"값 대신 ASCII 값으로 변환됩니다.

c n기능은 기본 기능이며 n초기 값입니다. 이 기능 r에서 우리의 실행 가치가 있습니다. while루프는 다음 작업을 수행합니다

  • r구성 요소 숫자 ( d r) 로 변환하십시오 .
  • 모든 자릿수의 곱을 구하십시오. 이는 Seq.reduce누적 값 ( a)과 순서 ( x) 의 다음 값 으로 함수를 사용하며이 경우 제품을 반환합니다. 초기 값은 시퀀스의 첫 번째 요소입니다.
  • 이 제품 값을 구성 요소 숫자 ( d) 로 변환하십시오 .
  • 이전의 숫자를 합산하여에 할당합니다 r.

1

펀칭, 136 바이트

101p&::*+2/>:82+%01g*01p82+/:#v_$01gv
X      v_v# #:/+82p10+g10%+82: <p100<
v:g10$ >#<#^                 #<^
>82+/#v_.@
      >101p^

당신은 할 수 여기를보십시오 .

모든 인터프리터의 셀 크기가 충분하지는 않지만 거의 모든 사람이 작은 숫자로 작동합니다. 더 많은 수의 경우 BefunExecn 과 같은 통역사가 필요할 수 있습니다 .


1

Gol> <> , 35 33 바이트

1AY:P*2,TYMR*YR+:a(?Bt
:a(qlBaSD$

온라인으로 사용해보십시오!

Jo King의 -2 바이트

광범위한 함수 및 암시 적 무한 루프 사용

전체 프로그램 예 및 작동 방식

1AGIE;GN
2AY:P*2,YlMR*YlR+:a(?B8R!
:a(?BaSD$

<main program>
1AG       Register row 1 as function G
   IE;    Take number input; halt on EOF
      GN  Call G and print the result as number
          Repeat indefinitely

<function G>
2AY            Register row 2 as function Y
   :P*2,       Sum of 1 to n
        Y      Call Y (break into digits)
         lMR*  Product
Y              Call Y
 lR+           Sum (an implicit zero is used)
    :a(?B      Return if the result is less than 10
         8R!   Skip initial 8 commands
               Repeat indefinitely

<function Y>
:a(?B      Return if the top is less than 10
     aSD   Divmod by 10; [... n] => [... n/10 n%10]
        $  Swap top two, so the "div" goes to the top


1

apt, 16 14 13 바이트

_ì ×ìx}gN®õ x

시도 해봐


설명

                  :Implicit input of integer U
         ®        :Map
        N         :The array of inputs (which just contains U)
          õ       :  Range [1,U]
            x     :  Reduce by addition
_     }g          :Take the last element of N, run it through the following function and push the result to N
                  : Repeat U times and then return the last element of N
 ì                :  Split to an array of digits
   ×              :  Reduce by multiplication
    ìx            :  Split to an array of digits and reduce by addition

깔끔하게, 나는 이것을 직접 해결하려고 시도했지만 좋은 해결책을 찾지 못했기 때문에 당신의 것을 보는 것이 흥미 롭습니다.
Nit

감사합니다, @Nit. 그래도 더 짧은 방법이 있습니다.
얽히고 설킨

@ 니트! 그래도 더 짧은 방법이 있어야한다고 확신했습니다.
얽히고 설킨


0

PHP 7, 89 바이트

for($a=$argn*-~+$argn/2;$a>9;)$a=array_sum(($s=str_split)(array_product($s($a))));echo$a;

파이프로 실행 -r하거나 온라인으로 사용해보십시오 .

  • PHP는 항상 입력을 문자열로 사용 하므로 원하는대로 작동 +하기 위해 int로 캐스팅해야 ~합니다.
  • 사전 증분은 작동하지 않습니다. 어디에 넣든 상관없이 두 피연산자 모두에 영향을 미칩니다.
  • 그러나 한 자리가 반복 전후에 발생하는지는 중요하지 않습니다 (추가 반복은 변경되지 않습니다). 그래서 for()대신 사용할 수 있습니다 do ... while().
  • 함수 이름의 인라인 할당에는 PHP 7 이상이 필요합니다.
    이전 PHP에는 바이트가 하나 더 필요합니다. for($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    ( str_split변수에 할당하지 않으면 다른 바이트가 낭비됩니다.)



0

PowerShell 코어 , 91101 93 바이트

Function F($a){$o=$a*($a+1)/2;1,2|%{$o=[char[]]"$([char[]]"$o"-join'*'|iex)"-join'+'|iex};$o}

온라인으로 사용해보십시오!

조금 풀려서 ...

Function F ($a)
{
    $o=$a*($a+1)/2;
    1..2 | % {
        $o = [char[]]"$o"-join '*' | iex;
        $o = [char[]]"$o"-join '+' | iex;
    }
    $o | Write-Output
}

첫 단계는 정수를 숫자로 나누는 것이 었습니다. 정수를 문자열 배열로 나누면 됩니다. 그런 다음 피연산자를 삽입 한 다음 문자열을 명령으로 평가하십시오. 그런 다음 입력이 한 자리가 될 때까지 다중 추가 사이클을 수행해야합니다.

iexInvoke-Command첫 번째 매개 변수 위치로 전달 된 문자열을 평가 하는 별명입니다 .

편집 : @AdmBorkBork 요청에 따라 바이트 수에 함수 헤더를 추가했습니다. 또한 약간의 수학을 수행하고 반복 횟수의 상한이 < log log 10^6 < log 6 < 2이므로 6 바이트를 더 절약했습니다.

x2 편집 : @AdmBorkBork 는 정수를 수학 표현식으로 변환하는 좀 더 간결한 방법을 찾은 다음으로 파이프하는 것이 좋습니다 iex. 이것은 8 바이트를 절약했습니다. 고맙습니다!


다른 PowerSheller를 만나서 반갑습니다! 그러나 Function F($a){ }바이트 수에 함수 정의를 포함해야한다고 생각합니다 . 그러나을 [char[]]대신 사용하여 일부를 저장할 수 있어야 -split''-ne''한다고 생각합니다.
AdmBorkBork

[char[]]1234=Ӓ유효하지 않습니다. 작동시킬 수는 있지만 지금은 분명하지 않을 수 있습니다. 제안 해 주셔서 감사합니다!
Jeff Freeman

미안 분명하지 않다 - [char[]]"$o"그리고 |iex보다는 iex( ).
AdmBorkBork

이 팁은 내 코드의 8 %를 줄였습니다. 대단해 감사!
Jeff Freeman



0

자바 8, 129 바이트

n->{long r=1,i=n;for(;i>1;r+=i--);for(;r>9;r=(i+"").chars().map(p->p-48).sum(),i=1)for(int s:(r+"").getBytes())i*=s-48;return r;}

온라인으로 사용해보십시오.

설명:

n->{            // Method with integer parameter and long return-type
  long r=1,     //  Result-long, starting at 1
       i=n;     //  Temp integer, starting at the input `n`
  for(;i>1;     //  Loop as long as `i` is not 1 yet
      r+=i--);  //   And increase `r` by `i`
  for(;r>9      //  Loop as long as `r` is not a single digit yet
      ;         //    After every iteration:
       r=(i+"").chars().map(p->p-48).sum(),
                //     Set `r` to the sum of digits of `i`
       i=1)     //     And reset `i` to 1
    for(int s:(r+"").getBytes())i*=s-48;
                //    Set `i` to the product of the digits of `r`
  return r;}    //  Return `r` as result

0

줄리아 0.6 , 56 바이트

f(n,k=(n+1)n÷2)=k>9?f(0,sum(digits(prod(digits(k))))):k

온라인으로 사용해보십시오!

매우 간단합니다 : (n+1)n÷21..n에서 합계를 계산 하고, 한 자릿수 ( >9)인지 확인하십시오. 그렇지 않은 경우 k를 k의 곱의 곱의 합으로 설정하여 k를 다시 시도하십시오. 그렇지 않으면 k를 반환하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.