Toán học hoạt động như thế nào trong thế giới của Anastasiya?


44

Lý lịch:

Toán học hoạt động tiêu chuẩn như phép cộng và phép nhân cơ bản trong thế giới thực hoạt động như sau:

12 + 123 = 135

12 * 123 = 1476

Điều đó không thú vị và nhàm chán! Nhiều trường đã diễn giải điều này như thực hành, thực hành, thực hành các thuật toán chính thức. Điều đó ngụ ý một chế độ ăn uống toán học khá cứng nhắc và nhàm chán và không phải là những gì được dự định trong thử thách này. Hãy sẵn sàng để chơi một số niềm vui trên trang web yêu thích của chúng tôi.

Xem xét quá trình thêm hai số nguyên dương, sau đó thêm lại tất cả các chữ số của kết quả. Lặp lại với phép cộng cho đến khi chỉ thu được một chữ số duy nhất. Ví dụ:

  1. Kết quả 12 + 123là 135.
  2. Thêm tất cả các chữ số của 135 chúng tôi có được 1 + 3 + 5 = 9.

Số bước cần thiết để có được một giá trị một chữ số 9 trong phần bổ sung lặp lại này là 2.

Như với quá trình bổ sung trước đó, phép nhân của hai số nguyên dương theo cùng một quy trình. Nhân tất cả các chữ số của kết quả của nó và sau đó lặp lại quá trình này cho đến khi chỉ còn lại một chữ số. Lấy ví dụ trên:

  1. Kết quả 12 * 123là 1476.
  2. Nhân tất cả các chữ số của 1476 chúng tôi thu được 1 * 4 * 7 * 6 = 168.
  3. Nhân lại tất cả các chữ số của 168 chúng ta thu được 1 * 6 * 8 = 48.
  4. Nhân lại tất cả các chữ số của 48 chúng tôi thu được 4 * 8 = 32.
  5. Nhân một lần nữa tất cả các chữ số của 32 chúng tôi thu được 3 * 2 = 6.

Số bước cần thiết để có được một giá trị một chữ số 6 phép nhân lặp lại này là 5.

Vì lợi ích của thử thách này và tránh mọi hành vi lạm dụng các ký hiệu toán học, tôi giới thiệu hai ký hiệu giả này: (+)(*), nhưng bạn có thể sử dụng bất kỳ ký hiệu nào bạn thích , hoạt động như sau:

  1. Hoạt động của quá trình bổ sung lặp đi lặp lại để có được một giá trị duy nhất là 12 (+) 123 = 9.
  2. Hoạt động của quá trình nhân lặp lại để có được một giá trị duy nhất là 12 (*) 123 = 6.

Thử thách:

Thách thức là viết một chương trình hoặc một chức năng có thể thực hiện cả hai thao tác như được giải thích trong phần nền: (+)(*).

Đầu vào:

Các đầu vào của chương trình, chức năng là hai số nguyên dương và một hoạt động hoặc (+)(*). Định dạng của đầu vào là một lựa chọn tùy ý của lập trình viên . Bạn có thể định dạng đầu vào, ví dụ, a (+) bhoặc F(a, (+), b)hoặc bất kỳ định dạng mà bạn muốn.

Đầu ra:

Đầu ra của chương trình hoặc hàm phải chứa kết quả hoạt động và số bước cần thiết với định dạng tự do như bạn muốn.

Các trường hợp thử nghiệm (bỏ qua định dạng đầu vào và đầu ra):

    81 (+) 31       -->   (4 ; 2)
    351 (+) 14568   -->   (6 ; 3)
    21 (*) 111      -->   (8 ; 3)
    136 (*) 2356    -->   (0 ; 2)

Quy tắc chung:

  • Đây là , vì vậy câu trả lời ngắn nhất tính bằng byte sẽ chiến thắng thử thách.
    Đừng để esolang ngăn cản bạn đăng câu trả lời bằng các ngôn ngữ thông thường. Tận hưởng thử thách này bằng cách cung cấp câu trả lời càng ngắn càng tốt với ngôn ngữ lập trình của bạn. Nếu bạn đăng một câu trả lời thông minh và một lời giải thích rõ ràng, câu trả lời của bạn sẽ được đánh giá cao (do đó các upvote) bất kể ngôn ngữ lập trình bạn sử dụng.
  • Các quy tắc chuẩn áp dụng cho câu trả lời của bạn, vì vậy bạn được phép sử dụng STDIN / STDOUT, các hàm / phương thức với các tham số phù hợp, các chương trình đầy đủ, v.v. Sự lựa chọn là của bạn.
  • Nếu có thể, chương trình của bạn có thể xử lý số lượng lớn. Nếu không, điều đó sẽ ổn thôi.

Hãy bắt đầu trò chơi!!


Phần bổ sung lặp lại ( gốc kỹ thuật số ) về cơ bản là bản sao của codegolf.stackexchange.com/q/1128/194
Peter Taylor

4
Câu hỏi đầu tiên tuyệt vời! Và tôi nhận ra định dạng quy tắc chung và câu từ Câu hỏi của riêng tôi. ;)
Kevin Cruijssen

4
@KevinCruijssen Yup. đúng rồi. Vì nó không có bản quyền nên tôi sao chép nó mà không có sự cho phép của bạn. Hehehe: D
Anastasiya-Romanova

4
@ Anastasiya-Romanova "không có bản quyền"? Thế kỷ XXI? Không; tất cả mọi thứ ở đây là CC-BY-SA 3.0. Quyền được cấp khi nội dung được gửi. Kiểm tra chân trang.
Mindwin

1
@ BradGilbertb2gills Vâng, tất nhiên. Nó được nêu trong bài viết bằng cách này. Trích dẫn: "Định dạng của đầu vào là sự lựa chọn tùy ý của lập trình viên".
Anastasiya-Romanova

Câu trả lời:


11

APL Dyalog , 33 32 30 29 byte

Điều này mở rộng APL để bao gồm ký hiệu tiền tố +/A n₁ n₂×/A n₁ n₂. (Trong thực tế, bạn có thể sử dụng bất kỳ thao tác nào ở bên trái của /A.) Trả về danh sách {kết quả, số lần lặp lại}.

A←{(⊃,≢)⍺⍺{∪⍵,⍨⍺⍺⍎¨⍕⊃⍵}⍣≡⍺⍺⍵}

A←{định nghĩa hàm bậc cao hơn theo hàm trái ⍺⍺và đối số tay phải

(⊃,≢) yếu tố đầu tiên của, tiếp theo là số lượng

⍺⍺{hàm được cung cấp ( +/cho tổng hoặc ×/cho sản phẩm) được cung cấp cho hàm bậc cao hơn

các yếu tố độc đáo của

⍵,⍨ đối số được nối vào

⍺⍺ chức năng cho ăn được áp dụng cho

⍎¨ đánh giá từng nhân vật của

đại diện cho nhân vật của

⊃⍵ yếu tố đầu tiên của đối số

}⍣≡ áp dụng nhiều lần cho đến khi kết quả giống hệt với đối số, bắt đầu bằng

⍺⍺⍵hàm được cung cấp ban đầu ( +/hoặc ×/) được áp dụng cho đối số ban đầu

} [kết thúc định nghĩa hàm bậc cao]

Dùng thử trực tuyến! ( đã được mô phỏng với elý do bảo mật.)

Cảm ơn @ngn vì đã lưu một byte.


0 byte (trong trò đùa)

Dyalog APL thực sự đã hỗ trợ đầy đủ cho toán học Anastasiyan; thay vì (+)(×), nó sử dụng +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}.

Hãy thử 81 +{(⊃,≢)⍺⍺{∪⍵,⍨⍺⍺e¨⍕⊃⍵}⍣≡⍺⍺/⍺⍵} 3121 ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/e¨⍕⍵}⍣=⍵⍺⍺⍨⍺} 111.


Cảm ơn câu trả lời, (+1). Nó có thể xử lý số lượng lớn đầu vào?
Anastasiya-Romanova

1
Nếu bạn thiết lập ⎕FR←1287(tức là sử dụng IEEE 754-2008 128-bit thập phân F loating điểm R epresentation) và ⎕PP←34(tức là sử dụng 34 ký tự P rint P recision), bạn có thể sử dụng số nguyên dưới đây 10³⁴.
Adám

Hmm, mặc dù nó có hỗ trợ đầy đủ, đúng không +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}vẫn khá một vài byte? Tôi bối rối về việc đây là 0 byte ..: S
Kevin Cruijssen 24/8/2016

3
@KevinCruijssen OP cho phép mọi ký hiệu đầu vào. Vì vậy, nếu một ngôn ngữ tình cờ hỗ trợ ký hiệu toán học mặc định Anastasiyan, glyph đa char (+)sẽ là Anastasiyan +. Dyalog APL không hỗ trợ toán học Anastasiyan, nhưng nó sử dụng một glyph đa char khác nhau, giống như *sức mạnh và bạn cần ×nhân lên, trong khi đó /có nghĩa là nhân rộng và bạn cần ÷phân chia.
Adám

1
@ Adám Ah ok, điều đó có ý nghĩa. Đó là uốn cong quy tắc của OP, nhưng không phá vỡ chúng. Vẫn còn khá kỳ lạ là thay vì (+)bạn có +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}đầu vào, nhưng vì OP thực sự đã nêu bất kỳ định dạng đầu vào nào sẽ làm, bạn có thể sử dụng hàm làm tham số. Hmm, tôi tự hỏi nếu điều này cũng có thể trong các ngôn ngữ lập trình khác hỗ trợ các chức năng như đầu vào.
Kevin Cruijssen

8

Haskell, 108 byte

f=map(read.pure).show
g h=(\x->(h.f$last x,length x+1)).takeWhile(>10).iterate(h.f)
(a#b)o=g(foldr1 o)$o a b

Xác định chức năng #lần đầu tiên mất abvà sau đó các nhà điều hành o. Thực tế thú vị: điều này hoạt động với bất kỳ nhà điều hành (thực sự, bất kỳ chức năng) bạn muốn!


Cảm ơn câu trả lời, (+1). Nó có thể xử lý số lượng lớn đầu vào?
Anastasiya-Romanova

4
@ Anastasiya-Romanova 秀 Có, nó có thể xử lý các con số lớn bằng RAM của bạn vì Integerloại của Haskell không bị ràng buộc.
ThreeFx

8

Pyke, 16 byte

RE`DltImbRoKr)oh

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

RE               - evaluate the input as Pyke code
                 -  (`B` is product and `s` is sum, the second line is a tuple)
  `              - i = str(^)
    ltI      )   - if len(i) != 1:
       mb        -   map(i, int)
         R       -   get the `B` or `s` from input
          oK     -   o++
            r    -   goto_start()
              oh - o++ + 1

Nhân lên Bvà thêm như s. Hai đầu vào số được phân tách bằng dấu phẩy.


1
Đẹp! Chúng ta có thể có được một lời giải thích?
Emigna

Cảm ơn câu trả lời, (+1). Nó có thể xử lý số lượng lớn đầu vào?
Anastasiya-Romanova

@ Anastasiya-Romanova cần có thể xử lý các số tùy ý
Màu xanh

Tôi không thể kiểm tra mã của bạn vì web bị chặn do vi phạm chính sách sử dụng internet của bố mẹ tôi. T_T
Anastasiya-Romanova

Một cái gì đó như thế này: Trang web bị chặn! Bạn đã cố gắng truy cập một trang web vi phạm chính sách sử dụng internet của bạn. URL: pyke.catbus.co.uk/?code=RE%60DltImbRoKr%29oh&input=B%0A21%2C+111&warnings=0 Thể loại: Chưa được xếp hạng
Anastasiya-Romanova

8

JavaScript (ES6), 59

Hàm đệ quy, định dạng đầu vào được tùy chỉnh để đơn giản hóa cuộc gọi đệ quy:

  • toán tử: '+' hoặc '*'
  • toán hạng: mảng của hai giá trị
f=(o,v,s=1,t=eval(v.join(o)))=>t>9?f(o,[...t+''],s+1):[t,s]

Kiểm tra

f=(o,v,s=1,t=eval(v.join(o)))=>t>9?f(o,[...t+''],s+1):[t,s]

;[
  [81,'+',31,     /* -> */ 4, 2]
, [351,'+',14568, /* -> */ 6, 3]
, [21,'*',111,    /* -> */ 8, 3]
, [136,'*',2356,  /* -> */ 0, 2]
].forEach(t=>{
  var [a,o,b,k1,k2] = t,
      [r,s]=f(o,[a,b]);
  console.log(k1==r && k2==s ? 'OK':'KO',a,o,b,'->',r,s)
})  
  


Cảm ơn câu trả lời, (+1). Nó có thể xử lý số lượng lớn đầu vào?
Anastasiya-Romanova

1
@ Anastasiya-Romanova đến giới hạn định dạng số javascript, độ chính xác 53 bit (17 chữ số thập phân)
edc65

8

Python 2, 60 byte

f=lambda s,c=0:s[1:]and f(min(s).join(`eval(s)`),c+1)or(s,c)

Đầu vào là một chuỗi như 81+31, đầu ra là một chuỗi của một chuỗi đơn và một bộ đếm (ví dụ : ('4', 2).

Kiểm tra nó trên Ideone .


Nếu lấy đầu vào dưới dạng một chuỗi các chuỗi và một chuỗi đơn lẻ được cho phép, ví dụ: f(['81', '31'],'+')có thể lưu thêm một byte nữa, nhưng cảm giác như kéo dài quy tắc hơi xa ...
Dennis


... trong trường hợp tôi thậm chí còn đi xa và cân nhắc vượt qua operator.addhoặc operator.multương ứng;)
Tobias Kienzler

7

Bình thường, 16

eJ.uvjhQ`N.vQ)lJ

Lấy đầu vào như "+ 123 12"để thêm và "* 123 12"nhân. Đầu ra như thế nào result<linefeed>steps.

Hãy thử ở đây hoặc chạy Test Suite , nhưng lưu ý rằng điều này phụ thuộc vào eval, vì vậy chỉ có biến thể bổ sung mới hoạt động trong trình thông dịch trực tuyến. Phép nhân hoạt động chính xác với trình thông dịch ngoại tuyến.

Điều này sử dụng hàm giảm tích lũy để tạo danh sách kết quả trung gian, vì vậy "+ 351 14568"chúng tôi nhận được [14919, 24, 6]. Điều này hoạt động vì các số có một chữ số là một điểm cố định của phép cộng và phép nhân Anastasiya. Sau đó, chúng ta chỉ cần lấy phần tử cuối cùng của mảng cũng như độ dài của mảng.

Điều này sẽ làm việc cho số lượng lớn tùy ý, ít nhất là cho đến khi bạn hết bộ nhớ.


7

R, 175 167 164 140 134 127 126 119 byte

function(G,S,D){i=1;O=switch(S,"+"=sum,prod);x=O(G,D);while(x>9){i=i+1;x=O(strtoi(strsplit(paste(x),"")[[1]]))};c(x,i)}

Ung dung:

f=function(G,S,D) #The function takes : the left operand, the operation symbol (between quote marks)
                  #and then the right operand
i=1               #That's the counter

O=switch(S,"+"=sum,prod)     #`O` takes the value `sum` if `S` matches `+`, `prod` 
                             #(which is the next agument) if not. 

x=O(G,D)                     #Does the first operation

while(nchar(x)>1)                 #While the number of character of the result 
                                  #of the operation is not of length 1, i.e., an integer :

    i=i+1                                    #Increase the counter
    x=O(strtoi(strsplit(paste(x),"")[[1]]))  #Apply the operation `O` to the first operation and 
                                             #the eventual subsequent ones

c(x,i)                                 #Outputs the result and the counter

ifelseđã trở lại ! Vâng!
Không

Sử dụng :

Special addition
> f(31,"+",81)
[1] 4 2

Special multiplication
> f(136,"*",2356)
[1] 0 2

Cảm ơn rất nhiều đến @plannapus vì đã chơi hết 24 byte!
-7 byte nhờ một ý tưởng hay từ @Vlo !


Vâng, xin vui lòng thêm giải thích kể từ khi tôi yêu R! Đây là ngôn ngữ thứ hai của tôi sau VBA. (+1)
Anastasiya-Romanova

1
@ Anastasiya-Romanova: Xong rồi!
Frédéric

@plannapus: Thực sự tốt đẹp! Cảm ơn rất nhiều !
Frédéric

1
@ Frédéric sử dụng tốt đẹp strtoi! Thêm 4 byte là bạn đã đánh bại tôi.
plannapus

1
Có vẻ như bạn có thể đánh gôn thêm một byte bằng cách bao gồm định nghĩa của O trong phép gán x trong thao tác đầu tiên: x = (O = switch (S, sum, `*`)) (G, D);.
rturnbull

6

05AB1E , 20 15 byte

[¼¹iOëP}Dg#S]¾‚

Giải trình

[       Dg# ]    # loop until number is single digit
 ¼               # increase counter
  ¹iO            # if operation is addition, sum list
     ëP}         # else take product of list
           S     # split into a list of digits
             ¾‚  # pair final number with counter and output

Toán tử là 1 cho phép cộng, 0 cho phép nhân.

Dùng thử trực tuyến


Cảm ơn câu trả lời, (+1). Nó có thể xử lý số lượng lớn đầu vào?
Anastasiya-Romanova

@ Anastasiya-Romanova Tôi không thấy lý do tại sao không. Bạn có một ví dụ?
Emigna

Chương trình của bạn đã được thử nghiệm cho loại đầu vào đó, vì vậy nó hoàn hảo :)
Anastasiya-Romanova

6

Thạch , 11 10 byte

Dj⁹VµÐĿḊĖṪ

Đầu vào là một cặp số và +hoặc ×.

Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

Làm thế nào nó hoạt động

Dj⁹VµÐĿḊĖṪ  Main link. Left argument: [x, y] (integers). Right argument: + or ×

    µÐĿ     Repeatedly execute the chain to the left, initially with argument
            [x, y], then with the previous return value. Stop when the results are
            no longer unique, and return the array of all intermediate results.
D           Decimal; convert the integers [x, y] or the return value z to base 10.
 j⁹         Join, separating by the link's right argument, i.e., '+' or '×'.
   V        Evaluate the result. This casts the previous return value to string,
            so, e.g., [8, 1, '+', 3, 1] becomes "81+31" before evaluation.
       Ḋ    Dequeue; discard the first intermediate result, i.e., [x, y].
        Ė   Enumerate; prefix each integer in the array with its 1-based index.
         Ṫ  Tail; extract the last index-value pair.

6

Mã máy ARM, 48 byte

Đổ lục giác:

b570 2a00 bf0c 1840 4348 2101 230a e00c 3101 0015 fbb0 f6f3 fb06 0413 2a00 bf0c 192d 4365 0030 d1f5 0028 280a d2f0 bd70

Chức năng này không phụ thuộc vào bất kỳ cuộc gọi hệ thống hoặc chức năng thư viện. Đây là mã Thumb-2, là mã hóa lệnh có độ dài thay đổi (2 hoặc 4 byte) cho ARM 32 bit. Do đó, giá trị tối đa nó có thể xử lý là 2 ^ 32-1. Có thể bỏ 2 byte nếu nó không tuân thủ AAPCS ( 46 byte ), vì chúng ta sẽ không phải xếp chồng các thanh ghi lúc đầu.

Lắp ráp Ungolfed (cú pháp GNU):

.syntax unified
.text
.global anastasiya
.thumb_func
anastasiya:
    @Input:
    @r0 - First number
    @r1 - Second number
    @r2 - 0 for add, 1 for multiply
    @Output:
    @r0 - Resultant value
    @r1 - Number of steps
    push {r4,r5,r6,lr}
    cmp r2,#0
    ite eq @if r2==0
    addeq r0,r0,r1 @r0+=r1
    mulne r0,r0,r1 @else r0*=r1
    movs r1,#1 @r1 is the number of steps
    movs r3,#10
    b endloop
    loop:
        adds r1,r1,#1 @Increment number of steps
        movs r5,r2 @r5=1 if multiply, 0 if add
        parseDigits:
            udiv r6,r0,r3 @r6=r0/r3
            mls r4,r6,r3,r0 @r4=r0 - r6*r3
            @Last two operations were r4=r0%r3 (r3==10)
            cmp r2,#0
            ite eq @if r2==0
            addeq r5,r5,r4 @r5+=r4
            mulne r5,r5,r4 @else r5*=r4
            movs r0,r6 @r0=r6 (Set r0 to r0/10)
            bne parseDigits @while (r0!=0)
        @Now our new total is in r5
        movs r0,r5 @Put it in r0
    endloop:
        cmp r0,#10
        bhs loop @while (r0 >=10)
    pop {r4,r5,r6,pc} @Return

Kiểm tra tập lệnh trong C:

#include <stdio.h>
unsigned long long anastasiya(unsigned,unsigned,unsigned);

int main(void) {
    unsigned x,y,op;
    printf("Enter first operand, second operand, and 0 for addition or 1 for multiplication.\n");
    scanf("%u%u%u",&x,&y,&op);
    unsigned long long res = anastasiya(x,y,op);
    printf("Result = %u, steps = %u\n",(unsigned)res ,(unsigned)(res >> 32));
}

4

R, 130 124 ký tự

Một cách tiếp cận hơi khác so với @ Frédéric 's:

f=function(a,f,b){b=c(a,b);n=1;while((m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)))>1){b=d%%10^(1:m)%/%10^(1:m-1);n=n+1};c(d,n)}

Thụt lề, với dòng mới:

f=function(a,f,b){
    b=c(a,b) # Take both numbers
    n=1 #Counter
    while((m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)))>1){
#My own special digit splitter! (d is the result and m is the nb of char of d)
        b=d%%10^(1:m)%/%10^(1:m-1)
        n=n+1
    }
    c(d,n) #Print results
    }

Dòng 4 có lẽ cần giải thích thêm:

switch(f,'(+)'=sum,prod) #pick which operator to use
switch(f,'(+)'=sum,prod)(b) # apply it to b
d<-switch(f,'(+)'=sum,prod)(b) #Saves the result in d
nchar(d<-switch(f,'(+)'=sum,prod)(b))#Measures the number of character of d
m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)) #Saves it in m
(m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)))>1 #Checks if it is more than 1

Các trường hợp thử nghiệm:

> f(12,"(+)",123)
[1] 9 2
> f(12,"(*)",123)
[1] 6 5
> f(351,"(+)",14568)
[1] 6 3

Khá đáng tiếc bạn đã đến muộn với câu trả lời này, nhưng bạn có upvote của tôi. Cảm ơn vì đã tạo ra điều này trong R.
Anastasiya-Romanova

Tại sao không may?
plannapus

Bởi vì nếu bạn đã đến trước, thì bạn sẽ có nhiều sự ủng hộ hơn
Anastasiya-Romanova

@ Anastasiya-Romanova enough Đủ công bằng :)
plannapus

Điểm thưởng cho việc có fcả tên hàm và một trong các đối số của nó :)
JDL

4

Octave, 85 byte MATLAB, 123, 114, 105, 94 byte

Quyết định dịch cái này sang Octace, để tận dụng việc lập chỉ mục trực tiếp và tăng cap capitites. Lấy đầu vào trên biểu mẫu : f(a,operator), trong đó a = [number1, number2], và operator==1đưa ra sản phẩm và operator==2đưa ra tổng.

function[x,i]=f(a,o)
g={@prod,@sum}{o};x=g(a);i=1;while(x=g(num2str(x)-48))>9;i++;end

Giải thích:

g={@prod,@sum}{o} : Chọn chức năng, sản phẩm hoặc tổng hợp thích hợp và gán nó cho g

x=g(a) lấy tổng hoặc sản phẩm của đầu vào

i=1; ... i++ : Tăng số đếm số bước

while(x=g(num2str(x)-48))>9;
          num2str(x)-48)     % turns a number 123 into an array [1 2 3].
        g(num2str(x)-48))    % Takes the sum or product of the array
      x=g(num2str(x)-48))    % Assign that value to the variable x
      x=g(num2str(x)-48))>9  % Checks if x > 9, continue looping if yes

Đã xóa hai dòng mới, một khoảng trắng và đặt cả hai số đầu vào trong một vectơ thay vì các đối số riêng biệt. Điều này đã tiết kiệm được 9 byte, nhờ vào pyjama! Đã xóa k=@(x)...để lưu thêm 11 byte nhờ vào beaker =) Cuối cùng, đã dịch toàn bộ sang Octave để lưu thêm 9 byte ...


4

Java, 164 159 146 byte

int[]p(int t,int m,String[]d){int r=m;for(String i:d){int x=Integer.decode(i);r=m<1?r+x:r*x;}return r>9?p(++t,m,(r+"").split("")):new int[]{r,t};}

Đối số đầu tiên chỉ là bộ đếm, luôn là 0

Đối số thứ hai là phương thức, 0 cho THÊM và 1 cho NHIỀU.

Đối số thứ ba là một chuỗi các Chuỗi, chứa các giá trị cần thêm / nhân.

Ung dung

public static int[] p(int t, int m, String[] d) {
    int r = m;
    for (String i : d) {
        int x = Integer.decode(i);
        r = m < 1 ? r + x : r * x;
    }
    return (r + "").length() > 1 ? p(++t, m, (r + "").split("")) : new int[]{r, t};
}

cảm ơn @Kevin Cruijssen vì đã cắt giảm một vài byte.

cảm ơn @milk đã cạo 5 byte.

Chương trình kiểm tra

public static final int ADD = 0;
public static final int MULTIPLY = 1;

public static void main(String[] args) {
    System.out.println(Arrays.toString(p(0, ADD, new String[]{"12", "123"}))); //9
    System.out.println(Arrays.toString(p(0, MULTIPLY, new String[]{"12", "123"}))); //6
}

public static int[] p(int t, int m, String[] d) {
    int r = m;
    for (String i : d) {
        int x = Integer.decode(i);
        r = m < 1 ? r + x : r * x;
    }
    return (r + "").length() > 1 ? p(++t, m, (r + "").split("")) : new int[]{r, t};
}

Đẹp, ngắn hơn câu trả lời Java của tôi . Tuy nhiên, bạn cũng nên in các bước cũng như câu trả lời hiện đang thiếu trong câu trả lời của bạn ..
Kevin Cruijssen 24/8/2016

@KevinCruijssen Ahh. Điều đó thật nhàm chán .. Tôi sẽ thử khắc phục điều đó ngay bây giờ.
Shaun Wild

Btw, bạn có thể đánh golf câu trả lời hiện tại của bạn một chút. m==0có thể m<1, và Integer.parseIntcó thể được Integer.decode.
Kevin Cruijssen

Tôi không sử dụng Java nhiều, nhưng jcuối cùng bạn có cần var đó không? Nội tuyến (r+"")hai lần trông giống như nó sẽ cạo một vài byte.
sữa

1
Chúng ta không thể thay đổi bài viết của tôi trong tương lai? Nếu bạn muốn đề xuất một chỉnh sửa làm như vậy trong các ý kiến.
Shaun Wild

3

Thạch , 17 byte

+×⁵?µDSP⁵?$ÐĿµL;Ṫ

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

Đưa ra các lập luận như thế x y 1này, tính toán tổng Anastasiya x (+) y.

Đưa ra lập luận như thế x y 0, điều này tính toán sản phẩm Anastasiya x (*) y.

Đầu ra được đưa ra là [number of steps, result].


Cảm ơn câu trả lời, nhưng đầu ra chương trình của bạn không chứa số bước cần thiết? Am i thiếu cái gì ở đây?
Anastasiya-Romanova

3

Python, 160 146 129 byte

def r(s):
 n=str(eval(s));c=0
 while n[1:]:exec("n=str(reduce(lambda a,b:a%sb,map(int,list(n))))"%"*+"["+"in s]);c+=1
 return n,c

Sẽ đăng một lời giải thích sớm.

Đầu vào ở dạng 12+12hoặc 5*35(với bình thường +*dấu hiệu), và giả sử rằng đó là hai toán tử duy nhất.

Nó có thể xử lý số lượng đầu vào lớn như bộ nhớ máy tính của bạn cho phép.

Tôi gần như chắc chắn tự tin rằng điều này có thể hơn nữa.

EDIT: 16 31 byte được lưu nhờ @Copper.


Cảm ơn câu trả lời, (+1). Nó có thể xử lý số lượng lớn đầu vào?
Anastasiya-Romanova

@ Anastasiya-Romanova Uhmmm ... Tôi khá chắc chắn rằng họ có thể. Bạn có thể cho tôi ví dụ về đầu vào lớn? Tôi sẽ thử và tính toán từ những thứ đó.
clismique

Có thể: 3218753647208435810122106 * 29349566754?
Anastasiya-Romanova

1
@ Anastasiya-Romanova 秀 Vâng, nó hoạt động trong ~ 0,5 giây, không đúng thời gian.
clismique

Bạn có thể thay đổi "+" if "+" in s else "*"thành "*+"["+"in s], và sau đó thay vì gán nó t, chỉ cần thêm nó vào dòng trong execcuộc gọi.
Đồng

3

R, 110 byte

Sử dụng bộ chia @plannapus.

function(A,F,B){r=Reduce;x=r(F,A,B);y=1;while(x>9){m=nchar(x);x=r(F,x%%10^(1:m)%/%10^(1:m-1));y=y+1};cat(x,y)}

f=function(A,F,B){
  r=Reduce                                  # Shortcut for Reduce
  x=r(F,A,B)                                # A operator B
  y=1                                       # Initiate counter
  while(x>9)                                # If number of digits > 2, or number > 9
  {m=nchar(x)                               # Count number of digits
    x=r(F,x%%10^(1:m)%/%10^(1:m-1))         # @plannapus's splitter, then feed into the A operator B operator C, etc while condition true
    y=y+1}                                  # Increment counter
  cat(x,y)}                                 # Print

Đầu ra

> f(136,"*",2356)
0 2
> f(31,"+",81)
4 2
> f(2,"+",3)
5 1
> (function(A,F,B){r=Reduce;x=r(F,A,B);y=1;while(x>9){m=nchar(x);x=r(F,x%%10^(1:m)%/%10^(1:m-1));y=y+1};cat(x,y)})(21,"*",111)
8 3

chỉnh sửa: Tôi không thể đếm.


R là tuyệt vời vì cho phép chúng tôi rút ngắn chức năng của nó, một cái gì đó có giá trị trong việc chơi golf. (+1)
Anastasiya-Romanova

3

Clojure 126 byte

(defn f [o a b] (loop [n (o a b) c 1] (if (< n 10) [n c] (recur (reduce #(o %1 %2) (map #(- (int %) 48) (str n))) (inc c)))))

Hàm được gọi như vậy:

(f + 81 31)

Đây là mã không được mã hóa:

(defn f [o a b]
  (loop [n (o a b) c 1]
    (if (< n 10)
      [n c]
      (recur (reduce #(o %1 %2)
                     (map #(- (int %) 48) (str n)))
             (inc c)))))

(def test-cases [[+ 81 31]
                 [+ 351 14568]
                 [* 21 111]
                 [* 136 2356]])

(map #(apply f %) test-cases)
;;=> ([4 2] [6 3] [8 3] [0 2])

Hãy nhớ rằng Clojure vẫn còn mới đối với tôi, vì vậy đây có thể không phải là giải pháp tốt nhất. Thử thách thật thú vị. Ngoài ra, mã chạy với số lượng rất lớn mà không gặp bất kỳ khó khăn nào.


Điều này là rất muộn, nhưng bạn có thể giảm hầu hết các không gian trong đó.
clismique

2

Perl 6 53 byte

{$/=(&^b($^a,$^c),{[[&b]] .comb}...10>*);$/[*-1],+$/}

( 12, &[+], 123 )được chấp nhận cho đầu vào, tôi có thể giảm xuống còn 53 byte.
( &[+]là viết tắt của &infix:<+>"sự tôn kính" đối với toán tử cộng số)

Nếu đối số thứ hai phải là một chuỗi (+)thì nó sẽ là 87 byte

{my&b=::("&infix:<$^b.substr(1,1)>");$/=(b($^a,$^c),{[[&b]] .comb}...10>*);$/[*-1],+$/}

Giải trình:

# bare block lambda with 3 parameters declared using placeholder syntax
{
  # store list into 「$/」
  # ( used 「$/」 so that I don't have to declare a variable )
  $/ = (

    # declare second placeholder parameter, and call it
    &^b(
      # with the first and third placeholder parameters
      $^a, $^c
    ),

    # bare block lambda with implicit parameter 「$_」
    {
      # list reduce using the second parameter from outer block
      [[&b]]

      # a list of the digits of 「$_」 (implicit method call)
      .comb
    }

    # keep doing that until
    ...

    # it produces something smaller than 10
    # ( Whatever lambda )
    10 > *
  );

  # returns

  # final result ( last value from list )
  $/[ * - 1 ],
  # and count of values in list
  +$/
}

Kiểm tra:

#! /usr/bin/env perl6
use v6.c;
use Test;

my &anastasiya-math = {$/=(&^b($^a,$^c),{[[&b]] .comb}...10>*);$/[*-1],+$/}

my @test = (
  (  81, &[+], 31    ) => (4, 2),
  ( 351, &[+], 14568 ) => (6, 3),
  (  21, &[*], 111   ) => (8, 3),
  ( 136, &[*], 2356  ) => (0, 2),
);

plan +@test;

for @test -> $_ ( :key(@input), :value(@expected) ) {
  cmp-ok anastasiya-math(|@input), &[»==«], @expected;
}

Cách sử dụng thông thường:

# override built-in Bag operator 「(+)」 in current lexical scope
my &infix:<(+)> = &anastasiya-math.assuming: *, &[+], *;

# add a new operator
my &infix:<(*)> = &anastasiya-math.assuming: *, &[*], *;

say 12 (+) 123; # (9 2)
say 12 (*) 123; # (6 5)

2

Python 2, 107 97 byte

g=lambda x,o,i=1:x<10and[x,i]or g(eval(o.join(`x`)),o,i+1)
lambda a,o,b:g(eval('%s'*3%(a,o,b)),o)

Hàm ẩn danh nhận đầu vào thông qua đối số của toán hạng thứ nhất a, toán tử o( '+'hoặc '*') và toán hạng thứ hai bvà trả về danh sách biểu mẫu [result, steps].

Làm thế nào nó hoạt động

Hàm ẩn danh tạo ra một chuỗi bằng cách nối các toán hạng với toán tử giữa chúng và sau đó đánh giá nó; đây là bước đầu tiên được mô tả trong câu hỏi Sau đó, giá trị này và toán tử được chuyển đến hàm đệ quy g. Ở đây, một bộ đếm i, được tăng lên cho mỗi cuộc gọi đệ quy, được sử dụng. Nếu đầu vào nhỏ hơn 10, phải đạt được một chữ số duy nhất, vì vậy điều này và iđược trả về. Nếu không, đầu vào được chuyển đổi thành một chuỗi và mỗi ký tự trong chuỗi này được nối với toán tử, đưa ra phép tính mong muốn, sau đó được ước tính và chuyển cho hàm theo cách đệ quy.

Hãy thử nó trên Ideone


(+1) trong khi chờ giải thích :)
Anastasiya-Romanova ova

2

Groovy, 102 byte

def p,e,r;p={t,m,d->e=d*.toInteger();r=m<1?e.sum():e.inject{a,b->a*b};r>9?p(++t,m,""+r as List):[r,t]}

Bị khử

def p,e,r
p = { t, m, d ->
    e = d*.toInteger()
    r = (
            m<1
                ? e.sum()
                : e.inject { a, b -> a * b }
        )
    r > 9
        ? p(++t, m, "" + r as List)
        : [r,t]
}

Giải trình

Dựa trên giải pháp tuyệt vời của @Sean Bean cho Java.

  • p: Việc đóng (hàm, lambda, bất cứ điều gì) thực hiện giải pháp
  • t: Độ sâu cuộc gọi hiện tại (số lần lặp), pphải luôn được gọi vớit=1
  • m: Thao tác để thực hiện, 0cho "thêm", 1cho "nhân"
  • d: Danh sách các toán hạng, mỗi toán hạng là một đối tượng Chuỗi
  • e: Các phần tử của d, mỗi phần tử được chuyển đổi thành một số nguyên
  • r: Tổng hoặc sản phẩm của e, tùy thuộc vào hoạt độngm
  • tuyên bố kết quả, bắt đầu bằng r > 9:
    • Nếu nhiều chữ số ( r > 9), hãy khôi phục, tăng độ sâu tvà chuyển đổi rthành danh sách các chuỗi chữ số (và kết quả trả về).
    • Nếu một chữ số, trả về rtnhư một danh sách.

Chương trình kiểm tra

final ADD = 0
final MULTIPLY = 1
println p(1, ADD, ["12", "123"]) //9, 2
println p(1, MULTIPLY, ["12", "123"]) //6, 5
println p(1, ADD, ["2", "3"]) //5, 1

Các kết quả

[9, 2]
[6, 5]
[5, 1]

2

Haskell, 76 70 byte

 (x#y)f=until(<[10])(\[s,i]->[foldr(f.read.pure)0$show s,i+1])[f x y,1]

Trả về một danh sách hai phần tử với kết quả và số bước. Làm việc cho số lượng lớn tùy ý. Ví dụ sử dụng: (351#14568)(+)-> [6,3].

Chỉnh sửa: Cảm ơn @BlackCap cho 6 byte.


Bạn có thể thay thế (-48+).fromEnumbằngread.pure
BlackCap

2

R, 91 byte

Sử dụng mã của @ Vlo, sử dụng bộ chia của @ plannapus và một số ý tưởng tôi đã tạo khi chơi golf câu trả lời của @ Frédéric, đây là câu trả lời R ngắn nhất. (Một số lượng lớn câu trả lời R bất thường ở đây ngày hôm nay ...)

function(A,F,B){x=F(A,B);while(x>9){m=nchar(x);x=F(x%%10^(1:m)%/%10^(1:m-1));T=T+1};c(x,T)}

Điều quan trọng, điều này đòi hỏi đầu vào cho toán tử phải là sum(+) hoặc prodcho (*). Theo các quy tắc của thách thức, điều này dường như là ổn.

Với vết lõm:

function(A,F,B){
  x=F(A,B);
  while(x>9){
    m=nchar(x);
    x=F(x%%10^(1:m)%/%10^(1:m-1));
    T=T+1
  };
  c(x,T)
}

Sự khác biệt chính từ câu trả lời của @ Vlo là:

  1. Thay vì sử dụng Reduce, chúng tôi dựa vào đối số đầu vào là một hàm và chỉ gọi nó một cách rõ ràng. (Yay cho các chức năng là đối tượng hạng nhất!)
  2. Thay vì khởi tạo một biến mới làm bộ đếm của chúng tôi, chúng tôi lạm dụng các nội dung và sử dụng của R T, đánh giá thành TRUE(aka 1), nhưng vì đó không phải là một biến dành riêng, chúng tôi có thể sửa đổi nó. Như vậy T+T2. Vì vậy, chúng tôi sử dụng đó là truy cập của chúng tôi.
  3. Thay vì cating đầu ra, chúng tôi chỉ trả lại nó như một vector với c. Cũng như lưu hai byte, thực tế là đầu ra được buộc vào một vectơ đảm bảo rằng đó Tlà lớp numeric. Nếu chúng tôi sử dụng catTkhông được tăng lên, thì chúng tôi sẽ nhận được đầu ra sai như thế nào 1 TRUE.

bạn có thể cấu trúc lại whilevòng lặp như sau, thay đổi Fthành một thứ khác để tránh xung đột tên : function(A,O,B){x=O(A,B);while({F=F+1;x>9})x=O(x%/%10^(1:nchar(x)-1)%%10;c(x,F)}}. Thật đáng kinh ngạc khi có nhiều thủ thuật chơi golf R mà chúng tôi đã đưa ra trong vài năm qua :)
Giuseppe

@Giuseppe Tái cấu trúc tốt đẹp! Hiện tại tôi không thể tìm thấy sự đồng thuận meta, nhưng tôi tin tưởng một cách hợp lý rằng việc sử dụng thủ thuật Tvà bộ Fđếm trong một hàm thực sự không hợp lệ, vì điều đó có nghĩa là hàm này chỉ có thể được gọi một lần. Vì vậy, câu trả lời này (và một số câu hỏi khác của tôi!) Không hợp lệ, trừ khi có một câu rõ ràng rm(T)ở cuối. Tôi sẽ tiếp tục tìm kiếm bài đăng meta đó để tôi có thể chắc chắn rằng tôi đã không mơ về nó.
rturnbull

Tôi tin rằng TFmẹo là hoàn toàn hợp lệ miễn là bạn không sửa đổi Thoặc Ftrong môi trường toàn cầu. ví dụ, f=function(){T=T+1;T}liên tục trả về 2. Tôi nghĩ rằng đây là bài viết meta mà bạn giới thiệu.
Giuseppe

@Giuseppe À đúng rồi, bạn đúng cả hai tính. Cảm ơn!
rturnbull

1

Ruby, 55 byte

Gọi đệ quy. Được sử dụng rất khác so với câu trả lời JavaScript của @ edc65 nhưng khi tôi tối ưu hóa, cuối cùng nó đã trở thành một cổng trực tiếp được phát triển gần như độc lập với câu trả lời của họ, trừ đi một tối ưu hóa cuối cùng liên quan đến việc kiểm tra kết quả đánh giá thay vì độ dài của danh sách toán hạng được truyền vào , cho phép tôi vượt qua số byte của họ.

Đầu vào là một chuỗi đại diện cho toán tử và một mảng chứa các toán hạng.

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

f=->o,x,i=1{y=eval x*o;y>9?f[o,y.to_s.chars,i+1]:[y,i]}

Kết quả là chính xác, nhưng số bước cần thiết để có được một giá trị một chữ số là không chính xác. Bạn có thể chỉnh sửa mã của bạn?
Anastasiya-Romanova

@ Anastasiya-Romanova 秀 ah, bạn nói đúng. Logic cũ của tôi yêu cầu nó bắt đầu từ i=0và tôi đã quên khi tái cấu trúc.
Mực giá trị

1

Perl, 38 byte

Bao gồm +2 cho -ap

Chạy với đầu vào trên STDIN và khoảng trắng xung quanh toán tử:

amath.pl <<< "12 + 123"
amath.pl <<< "12 * 123"

Đầu ra là chữ số và các bước được phân tách bằng +A

amath.pl:

#!/usr/bin/perl -ap
1while++$\,$_=eval."+A",s/\B/$F[1]/g

Nếu xuất các bước trong unary thì ok, phiên bản 35 byte này hoạt động tốt hơn:

#!/usr/bin/perl -lap
1while$\.=1,$_=eval,s/\B/$F[1]/g

1

Toán học, 105 94 byte

Mã.

{x,y}=(c=0;f//.a_:>(c++;t=o@@IntegerDigits@a);{t,c})&/.{{f->#1+#2,o->Plus},{f->#1#2,o->Times}}

Sử dụng.

x[81, 31]
(* {4, 2} *)

x[351, 14568]
(* {6, 3} *)

y[21, 111]
(* {8, 3} *)

y[136, 2356]
(* {0, 2} *)

Giải trình.

Hai hàm x(for (+)) và y(for (*)) được tạo cùng lúc bằng cách thay thế các tham số fotrong

(c = 0;
 f //. a_ :> (c++; t = o@@ IntegerDigits@a);
 {t, c}
)&

với các giá trị phù hợp của họ. Vì x, ftrở thành #1 + #2otrở thành Plus; cho y, họ tương ứng trở thành #1 #2Times. Viết lại hàm xcho phần cuối của phần giải thích:

x = (
  c = 0;
  #1 + #2 //. a_ :> (c++; t = Plus@@IntegerDigits@a); 
  {t, c}
) &;

(* The symbol //. stands for ReplaceRepeated. 
   The rule a_ :> (c++; t = Plus@@IntegerDigits@a) is applied until the result no longer 
changed. Specifically, the rule increments the counter of 1 at each step (this is c++), 
then takes the sum of the digits of the previous result (this is Plus@@IntegerDigits@a). 
The rule stops to apply when the variable t is less than 10. We return the final result and 
the number of steps with {t, c}. *)

1

Java 7, 203 195 192 byte

int c=1;String c(long a,long b,int o){return p(((o<1?a+b:a*b)+"",o)+","+c;}long p(String n,int o){long x=o,q;for(String s:n.split("")){q=new Long(s);x=o<1?x+q:x*q}c++;return x<10?x:p(x+"",o);}

Nó sử dụng long(giá trị tối đa là 2 63 -1). Nếu nó sẽ sử dụng intthay thế (giá trị tối đa là 2 31 -1) thì nó sẽ chỉ còn ít hơn 1 byte ( 191 byte ):

int c=1;String c(int a,int b,int o){return p(((o<1?a+b:a*b)+"",o)+","+c;}int p(String n,int o){int x=o,q;for(String s:n.split("")){q=new Integer(s);x=o<1?x+q:x*q}c++;return x<10?x:p(x+"",o);}

Nó rất có thể được chơi golf nhiều hơn một chút. Phải in các bước cũng như câu trả lời cho cả hai toán tử mất một số byte, mặc dù ..
Sử dụng 0 (cho (+)) và 1 (cho (*)).

Mã thử nghiệm & mã hóa:

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

class Main{
  static int c = 1;
  static String c(long a, long b, int o){
    return p((o < 1 ? a+b : a*b) + "", o) + "," + c;
  }

  static long p(String n, int o){
    long x = o,
         q;
    for(String s : n.split("")){
      q = new Long(s);
      x = o < 1
           ? x + q
           : x * q;
    }
    c++;
    return x < 10
            ? x
            : p(x+"", o);
  }

  public static void main(String[] a){
    System.out.println(c(81, 31, true));
    c = 1;
    System.out.println(c(351, 14568, true));
    c = 1;
    System.out.println(c(21, 111, false));
    c = 1;
    System.out.println(c(136, 2356, false));
  }
}

Đầu ra:

4,2
6,3
8,3
0,2
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.