Chuỗi Add-Multiply-Add


27

( Liên quan )

Cho một số nguyên n > 1,
1) Xây dựng phạm vi số n, n-1, n-2, ... 3, 2, 1và tính tổng
2) Lấy các chữ số riêng của số đó và tính tích
3) Lấy các chữ số riêng của số đó và tính tổng
4) Lặp lại các bước 2 và 3 cho đến khi bạn đạt đến một chữ số Chữ số đó là kết quả.

Hai mươi điều khoản đầu tiên của chuỗi dưới đây:

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

Lưu ý: Trình tự này KHÔNG có trong OEIS.

I / O và Nội quy

  • Các số sẽ nhận được rất lớn một cách nhanh chóng, do đó, giải pháp phải có khả năng xử lý các số đầu vào lên tới 100.000 mà không bị lỗi (thật tốt nếu mã của bạn có thể xử lý được điều đó).
  • Đầu vào và đầu ra có thể được cung cấp bởi bất kỳ phương pháp thuận tiện .
  • Một chương trình đầy đủ hoặc một chức năng được chấp nhận. Nếu một chức năng, bạn có thể trả lại đầu ra thay vì in nó.
  • Sơ hở tiêu chuẩn bị cấm.
  • Đây là vì vậy tất cả các quy tắc chơi gôn thông thường đều được áp dụng và mã ngắn nhất (tính bằng byte) sẽ thắng.

Ví dụ

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

3
+1 cho thử thách theo chuỗi không có trong OEIS
JAD

2
Bất cứ khi nào n ≤ 100000 , chỉ cần hai lần lặp của bước 2 và 3 là đủ để có kết quả. Chúng ta có thể tận dụng lợi thế đó hay thuật toán chúng ta chọn sẽ làm việc cho các giá trị lớn hơn của n ?
Dennis

2
@Dennis Thuật toán sẽ hoạt động với mọi giá trị của n. Các giải pháp được đăng chỉ phải làm việc lên đến n = 100000.
admBorkBork

3
Numbers will get very large quicklykhông, nó không
l4m2

3
@ l4m2 Không phải đầu ra. Nhưng 100000 + 99999 + ... + 1 = 5000050000 là số 33 bit, ngôn ngữ bạn chọn có thể có hoặc không gặp khó khăn khi trình bày.
Dennis

Câu trả lời:


10

Python 2 , 77 72 71 62 60 byte

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

Cảm ơn @xnor vì đã chơi golf 2 byte!

Hãy thử trực tuyến!


Tôi mới chuyển sang một vòng lặp for, nhưng tôi sẽ phải nhớ thủ thuật đó cho tương lai.
Dennis

Trường hợp ở repeat until you reach a single digitđâu?
Tít

2
@Titus Tôi chỉ cần thực hiện n lần lặp của bước 2 và 3, luôn luôn là đủ. Trong thực tế, kể từ n ≤ 100000 , ba lần lặp là đủ.
Dennis

Bây giờ bạn đề cập đến nó: Trên thực tế, đầu vào nhỏ nhất sẽ yêu cầu ba lần lặp là 236172; và đó là những người duy nhất dưới 1 triệu.
Tít



4

Thạch , 8 byte

RSDPDƲÐL

Hãy thử trực tuyến!

Chương trình đầy đủ (nó trả về một mảng đơn có chứa kết quả, nhưng dấu ngoặc không hiển thị trong STDOUT).


Đây là câu trả lời Jelly "trông tự nhiên" nhất mà tôi từng thấy. Chỉ có 2 ký tự không phải ASCII
RedClover

@Soaku codegolf.stackexchange.com/questions/69424/ triệt
Trái cây Esolanging

Uh, chúng ta có thể vui lòng không thảo luận ở đây không, cảm ơn. : P TNB có thể là nơi thay thế để thảo luận về vấn đề này, nếu không có tiếng ồn. ;)
Erik the Outgolfer

4

MATL , 15 13 byte

Để tưởng nhớ ngôn ngữ của tháng :

:`sV!UpV!Utnq

Hãy thử trực tuyến!

Tôi không nghĩ có một cách đơn giản hơn để lấy các chữ số của một số hơn là chuyển đổi số thành một chuỗi V, sau đó hoán vị nó !và chuyển vectơ dọc này trở lại thành một số U.

Đã lưu 2 byte nhờ chính Người tạo 1 ! Tôi đã quên kết thúc ngầm, có nghĩa là tôi có thể loại bỏ ]và thay vì so sánh số lượng phần tử với 1, tôi chỉ có thể giảm giá trị đó và sử dụng trực tiếp như một boolean.

Vì vậy, lời giải thích như sau:

                 % 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 ... của MATL, Luis Mendo.


3

JavaScript (ES6), 60 byte

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

Hãy thử trực tuyến!

Đã bình luận

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

Phiên bản thay thế, 59 byte (không cạnh tranh)

Một phiên bản không đệ quy chỉ hoạt động cho n <236172 . (Nó bao gồm phạm vi được yêu cầu nhưng không đủ điều kiện là thuật toán chung hợp lệ.)

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

Hãy thử trực tuyến!


phiên bản chính của bạn bị hỏng khi N> = 77534568790. Nó hoạt động khi N = 7753456879; không chắc chắn chính xác điểm dừng ở đâu. Tất nhiên, điều này không thành vấn đề vì yêu cầu chỉ xử lý tối đa N = 100.000, vì vậy tôi không chắc tại sao tôi lại viết bài này ....
Ross Presser

1
@RossPresser Theo ước tính sơ bộ, tôi muốn nói rằng nó hoạt động tốt hơn Number.MAX_SAFE_INTEGER ** 0.5 ~= 94906265.
Arnauld


2

Stax , 14 13 10 byte

ñu┌↕a√äJ²┐

Chạy và gỡ lỗi nó

Là khá thú vị để thực hiện. Tôi tự hỏi nếu có một cách ngắn gọn hơn để làm so sánh ở cuối.

Giải trình

|+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

-1 byte nhờ vào lò nướng

-3 byte nhờ Scrooble


2

R , 152 130 109 byte

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

Hãy thử trực tuyến!

@Giuseppe đã tìm thấy 21 42 byte với nhiều thứ R khác nhau mà tôi chưa từng sử dụng, cùng với cách lấy các chữ số của một số mà không ép buộc chuỗi và ngược lại, và với ít byte hơn!

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

options(scipen=9) đang được yêu cầu đối với trường hợp của 9854 cho các chức năng cũ, bởi vì giai đoạn sản phẩm đầu tiên kết thúc như là 80000, trong đó in R như 8e + 05.


Ah tôi thấy. Đầu ra ký hiệu khoa học. Nắm bắt tốt!
admBorkBork

1
Cuối cùng cũng nhận được scipen: Hãy thử trực tuyến ! lưu ý max(0,log10(x))là bởi vì nếu x=0, sau log10(0)=-Infđó gây ra lỗi.
Giuseppe

1

Bình thường , 11 byte

usj*FjGTTsS

Hãy thử nó ở đây!

usj * FjGTTsS - Chương trình đầy đủ. N = Đầu vào.
          S - Phạm vi. Năng suất [1, N] ⋂.
         s - Tổng.
u - Mặc dù không có hai lần lặp liên tiếp nào mang lại kết quả như nhau, do (var: G):
   * FjGT - Sản phẩm kỹ thuật số.
 sj T - Tổng số.

1

Than , 18 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

≔Σ…·¹Nθ

Tính tổng các số nguyên cho đến đầu vào.

 W›θ⁹≔ΣΠθθ

Trong khi kết quả lớn hơn 9, hãy lấy tổng các chữ số của tích các chữ số.

Iθ

Truyền kết quả thành chuỗi và in ngầm.


1

Gaia , 8 byte

┅⟨Σ₸∨Π⟩°

Hãy thử trực tuyến!

Giải thích cũ (trước khi sửa lỗi là lỗi của Gaia IMO: P):

┅⟨ΣΠ⟩ ° - Chương trình đầy đủ. N = Đầu vào.
- Phạm vi. Đẩy [1, N] vào ngăn xếp.
 ⟩ ° - Trong khi không có hai lần lặp liên tiếp nào cho kết quả như nhau, hãy làm:
  - Tổng (hoặc tổng kỹ thuật số, khi áp dụng cho một số nguyên).
   Π - Sản phẩm kỹ thuật số.

Đã lưu 1 byte nhờ Dennis .


┅⟨ΣΠ⟩°tiết kiệm một byte.
Dennis

Điều này không hoạt động đối với các giá trị là tổng kỹ thuật số là 0, như4
Jo King

@JoKing Đã sửa, cảm ơn vì đã phát hiện ra điều đó. Thật không may, tại Gaia, lấy một số chữ số của 0kết quả []vì một số lý do :(
Ông Xcoder

1

F #, 175 byte

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

Hãy thử trực tuyến!

Nhắc nhở duy nhất cho chức năng là giá trị đầu vào phải là loại uint64.

Ungolfed nó giống như thế này:

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

Hàm d nchuyển đổi số nthành chữ số thành phần của nó. Đầu tiên, nó chuyển đổi thành một chuỗi, sau đó nhận từng ký tự trong chuỗi. Mỗi ký tự sau đó phải được chuyển đổi thành một chuỗi, nếu không các ký tự sẽ được chuyển đổi thành giá trị ASCII thay vì giá trị "thực" của chúng.

Các c nchức năng là chức năng chính, với nnhư giá trị ban đầu. Trong chức năng rnày là giá trị chạy của chúng tôi. Các whilevòng lặp nào sau đây:

  • Chuyển đổi rthành các chữ số thành phần của nó ( d r).
  • Lấy sản phẩm của tất cả các chữ số. Điều này sử dụng Seq.reducehàm lấy giá trị tích lũy ( a) và giá trị tiếp theo trong chuỗi ( x) và trong trường hợp này trả về sản phẩm. Giá trị ban đầu là phần tử đầu tiên trong chuỗi.
  • Chuyển đổi giá trị sản phẩm này thành các chữ số thành phần của nó ( d).
  • Tính tổng các chữ số từ trước và gán giá trị này cho r.

1

Befunge, 136 byte

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

Bạn có thể thử nó ở đây .

Mặc dù không phải tất cả các trình thông dịch đều có kích thước ô đủ lớn, nhưng nó hoạt động với số lượng nhỏ cho khá nhiều người ngoài kia. Đối với số lượng lớn hơn, nbạn có thể cần một thông dịch viên như BefunExec .


1

Gol> <> , 35 33 byte

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

Hãy thử trực tuyến!

-2 byte bởi Jo King.

Sử dụng rộng rãi các chức năng và các vòng lặp vô hạn ngầm.

Ví dụ chương trình đầy đủ & Cách thức hoạt động

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

Japt, 16 14 13 byte

_ì ×ìx}gN®õ x

Thử nó


Giải trình

                  :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

Không, tôi đã cố gắng tự giải quyết vấn đề này nhưng không tìm được giải pháp tốt để thấy điều đó thật thú vị.
Nit

Cảm ơn, @Nit. Mặc dù vậy, phải có một cách ngắn hơn.
Xù xì

@Nit, hiểu rồi! Vẫn tin rằng phải có một cách ngắn hơn, mặc dù.
Shaggy


0

PHP 7, 89 byte

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

Chạy như ống với -rhoặc thử trực tuyến .

  • PHP luôn lấy đầu vào là chuỗi, vì vậy tôi phải sử dụng +để chuyển sang int ~để làm việc như mong muốn.
  • Gia tăng trước sẽ không hoạt động: bất kể tôi đặt nó ở đâu, nó sẽ ảnh hưởng đến cả hai toán hạng.
  • Nhưng: Không thành vấn đề nếu chữ số đơn diễn ra trước hoặc sau khi lặp (lặp lại bổ sung sẽ không thay đổi một thứ); vì vậy tôi có thể sử dụng for()thay vì do ... while().
  • PHP 7 trở lên là bắt buộc để gán nội tuyến của tên hàm.
    PHP cũ hơn yêu cầu thêm một byte: for($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    (Không gán str_splitcho một biến nào cả sẽ lãng phí một byte khác.)



0

Lõi PowerShell , 91 101 93 byte

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

Hãy thử trực tuyến!

Khó hiểu một chút ...

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

Các bước đầu tiên là chia số nguyên thành các chữ số - đã thực hiện điều này bằng cách chia số nguyên thành một mảng các ký tự chuỗi . Sau đó, chèn toán hạng và sau đó đánh giá chuỗi dưới dạng một lệnh. Sau đó, đó là vấn đề thực hiện chu trình đa cộng cho đến khi đầu vào là một chữ số.

iexlà một bí danh để Invoke-Commandđánh giá một chuỗi được truyền vào vị trí param đầu tiên.

Chỉnh sửa: Theo yêu cầu của @AdmBorkBork , tôi đã thêm tiêu đề hàm vào số byte. Ngoài ra, tôi đã làm một bài toán nhỏ và nhận ra rằng giới hạn trên của số lần lặp là< log log 10^6 < log 6 < 2 , do đó đã lưu thêm sáu byte.

Chỉnh sửa x2: @AdmBorkBork tìm thấy một cách ngắn gọn hơn để chuyển đổi số nguyên thành biểu thức toán học, và sau đó đề xuất chuyển nó thành iex. Điều này đã lưu 8 byte. Cảm ơn bạn!


Rất vui khi thấy một PowerSheller khác ở xung quanh! Tuy nhiên, tôi nghĩ bạn cần bao gồm định nghĩa hàm Function F($a){ }trong số byte của bạn. Tuy nhiên, tôi nên có thể tiết kiệm một số sử dụng [char[]]thay vì -split''-ne'', tôi nghĩ vậy.
admBorkBork

[char[]]1234=Ӓ, không hợp lệ; Tôi có thể làm cho nó hoạt động, nhưng nó có thể không rõ ràng ngay bây giờ. Cám ơn vì sự gợi ý!
Jeff Freeman

Xin lỗi tôi đã không rõ ràng - [char[]]"$o"|iexhơn là iex( ).
admBorkBork

Mẹo này đã cạo 8% mã của tôi. Tuyệt vời. Cảm ơn!
Jeff Freeman



0

Java 8, 129 byte

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

Hãy thử trực tuyến.

Giải trình:

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

Julia 0,6 , 56 byte

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

Hãy thử trực tuyến!

Khá đơn giản: tính (n+1)n÷2tổng từ 1..n, kiểm tra xem đó có phải là một số có một chữ số không ( >9), nếu không, hãy thử lại với k được đặt thành tổng các chữ số của tích của các chữ số của k, nếu không trả về k.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.