Bagaimana cara kerja matematika di dunia Anastasiya?


44

Latar Belakang:

Matematika operasi standar seperti penjumlahan dasar dan perkalian di dunia nyata bekerja seperti ini:

12 + 123 = 135

dan

12 * 123 = 1476

Itu tidak menarik dan tidak membosankan! Banyak sekolah sudah menafsirkan ini sebagai praktik, praktik, praktik algoritma formal. Itu menyiratkan diet matematika yang cukup kaku dan membosankan dan bukan yang dimaksudkan dalam tantangan ini. Bersiaplah untuk bersenang-senang di situs tercinta kami.

Pertimbangkan proses menambahkan dua bilangan bulat positif, lalu tambahkan lagi semua digit hasilnya. Mengulangi dengan penambahan sampai hanya satu digit yang diperoleh. Sebagai contoh:

  1. Hasilnya 12 + 123adalah 135.
  2. Menambahkan semua angka 135 kita dapatkan 1 + 3 + 5 = 9.

Jumlah langkah yang diperlukan untuk mendapatkan nilai satu digit 9 dalam penambahan berulang ini adalah 2.

Seperti halnya proses penambahan sebelumnya, perkalian dua bilangan bulat positif mengikuti proses yang sama. Lipat gandakan semua digit hasilnya dan ulangi proses ini sampai hanya satu digit yang tersisa. Ambil contoh di atas:

  1. Hasilnya 12 * 123adalah 1476.
  2. Lipat gandakan semua angka 1476 yang kita dapatkan 1 * 4 * 7 * 6 = 168.
  3. Kalikan lagi semua angka 168 yang kita dapatkan 1 * 6 * 8 = 48.
  4. Kalikan lagi semua angka 48 yang kita dapatkan 4 * 8 = 32.
  5. Kalikan sekali lagi semua angka 32 yang kita peroleh 3 * 2 = 6.

Jumlah langkah yang diperlukan untuk mendapatkan nilai satu digit 6 perkalian berulang ini adalah 5.

Demi tantangan ini dan menghindari penyalahgunaan notasi matematika, saya memperkenalkan dua notasi dummy ini: (+)dan (*), tetapi Anda dapat menggunakan notasi yang Anda suka , yang berfungsi seperti berikut:

  1. Operasi proses penambahan berulang untuk mendapatkan nilai tunggal adalah 12 (+) 123 = 9.
  2. Pengoperasian proses multiplikasi berulang untuk mendapatkan nilai tunggal adalah 12 (*) 123 = 6.

Tantangan:

Tantangannya adalah untuk menulis baik program atau fungsi yang dapat melakukan kedua operasi seperti yang dijelaskan di bagian latar belakang: (+)dan (*).

Memasukkan:

Input dari program atau fungsi adalah dua bilangan bulat positif dan satu operasi baik (+)dan (*). Format input adalah pilihan sewenang-wenang dari programmer . Anda dapat memformat input, misalnya, a (+) batau F(a, (+), b)format apa pun yang Anda inginkan.

Keluaran:

Output dari program atau fungsi harus berisi hasil operasi dan jumlah langkah yang diperlukan dengan format gaya bebas seperti yang Anda inginkan.

Kasus Uji (abaikan format input dan output):

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

Aturan umum:

  • Ini adalah , jadi jawaban tersingkat dalam byte memenangkan tantangan.
    Jangan biarkan esolang mencegah Anda mengirim jawaban dengan bahasa biasa. Nikmati tantangan ini dengan memberikan jawaban sesingkat mungkin dengan bahasa pemrograman Anda. Jika Anda memposting jawaban yang cerdas dan penjelasan yang jelas, jawaban Anda akan dihargai (karenanya upvotes) terlepas dari bahasa pemrograman yang Anda gunakan.
  • Aturan standar berlaku untuk jawaban Anda, jadi Anda diperbolehkan menggunakan STDIN / STDOUT, fungsi / metode dengan parameter yang tepat, program lengkap, dll. Pilihan ada di tangan Anda.
  • Jika memungkinkan, program Anda dapat menangani jumlah besar dengan benar. Jika tidak, itu akan baik-baik saja.

Ayo mulai permainan!!


Bagian tambahan yang diulang ( akar digital ) pada dasarnya adalah duplikat dari codegolf.stackexchange.com/q/1128/194
Peter Taylor

4
Pertanyaan pertama yang bagus! Dan saya mengenali format aturan umum dan kalimat dari Pertanyaan saya sendiri. ;)
Kevin Cruijssen

4
@KevinCruijssen Yup. tepat sekali. Karena tidak memiliki hak cipta, maka saya menggandakannya tanpa izin Anda. Hehehe: D
Anastasiya-Romanova 秀

4
@ Anastasiya-Romanova 秀 "tidak ada hak cipta"? Di abad XXI? Nggak; semuanya di sini adalah CC-BY-SA 3.0. Izin diberikan ketika konten dikirimkan. Periksa catatan kaki situs.
Mindwin

1
@ BradGilbertb2gills Ya, tentu saja. Itu dinyatakan dalam pos dengan cara. Kutipan: "Format input adalah pilihan sewenang-wenang dari programmer".
Anastasiya-Romanova 秀

Jawaban:


11

Dyalog APL , 33 32 30 29 byte

Ini meluas APL untuk memasukkan notasi awalan +/A n₁ n₂dan ×/A n₁ n₂. (Bahkan, Anda dapat menggunakan operasi apa pun di sebelah kiri /A.) Mengembalikan daftar {result, count pengulangan}.

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

A←{mendefinisikan fungsi tingkat tinggi dalam hal fungsi tangan kiri ⍺⍺, dan argumen tangan kanan

(⊃,≢) elemen pertama, diikuti oleh hitungan

⍺⍺{fungsi yang disediakan ( +/untuk jumlah atau ×/untuk produk) diumpankan ke fungsi tingkat tinggi

elemen unik dari

⍵,⍨ argumen ditambahkan ke

⍺⍺ fungsi umpan diterapkan ke

⍎¨ evaluasi setiap karakter

representasi karakter

⊃⍵ elemen pertama dari argumen

}⍣≡ diterapkan berulang kali hingga hasilnya identik dengan argumen, dimulai dengan

⍺⍺⍵fungsi yang semula diumpankan ( +/atau ×/) diterapkan pada argumen asli

} [akhir dari definisi fungsi tingkat tinggi]

TryAPL online! ( telah ditiru dengan ealasan keamanan.)

Terima kasih kepada @ngn untuk menghemat satu byte.


0 byte (bercanda)

Dyalog APL sebenarnya sudah memiliki dukungan penuh untuk matematika Anastasiyan; bukannya (+)dan (×), itu menggunakan +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}dan ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}.

Coba 81 +{(⊃,≢)⍺⍺{∪⍵,⍨⍺⍺e¨⍕⊃⍵}⍣≡⍺⍺/⍺⍵} 31dan 21 ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/e¨⍕⍵}⍣=⍵⍺⍺⍨⍺} 111.


Terima kasih atas jawabannya, (+1). Bisakah ia menangani input dalam jumlah besar?
Anastasiya-Romanova 秀

1
Jika Anda menyetel ⎕FR←1287(yaitu menggunakan IEEE 754-2008 128-bit desimal F representasi titik rating-titik R ) dan ⎕PP←34(yaitu menggunakan resi P rint P P karakter 34 karakter ), Anda dapat menggunakan bilangan bulat di bawah 10³⁴.
Adám

Hmm, meskipun memiliki dukungan penuh, bukan +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}dan ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}masih beberapa byte? Saya bingung tentang bagaimana ini 0 byte ..: S
Kevin Cruijssen

3
@KevinCruijssen OP memungkinkan notasi input apa pun. Jadi, jika suatu bahasa terjadi untuk mendukung default-notation matematika Anastasiyan out-of-the-box, multi-char glyph (+)akan menjadi Anastasiyan +. Dyalog APL memang mendukung matematika Anastasiyan, tetapi ia menggunakan multi-char glyph yang berbeda, sama seperti *kekuatan dan Anda perlu ×untuk perkalian, sementara itu /berarti replikasi dan Anda perlu ÷untuk pembagian.
Adám

1
@ Adám Ah ok, itu masuk akal. Ini agak membengkokkan aturan OP, tetapi tidak melanggar mereka. Masih cukup aneh bahwa alih-alih (+)Anda +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}sebagai input, tetapi karena OP memang menyatakan format input apa pun akan dilakukan, Anda dapat menggunakan fungsi sebagai parameter. Hmm, saya bertanya-tanya apakah ini juga mungkin dalam bahasa pemrograman lain yang mendukung fungsi sebagai input.
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

Mendefinisikan fungsi #yang pertama mengambil adan bkemudian operator o. Fakta menyenangkan: ini berfungsi dengan semua operator (sebenarnya, fungsi apa pun) yang Anda inginkan!


Terima kasih atas jawabannya, (+1). Bisakah ia menangani input dalam jumlah besar?
Anastasiya-Romanova 秀

4
@ Anastasiya-Romanova 秀 Ya, ini dapat menangani angka sebesar RAM Anda karena Integertipe Haskell tidak terikat.
ThreeFx

8

Pyke, 16 byte

RE`DltImbRoKr)oh

Coba di sini!

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

Mengambil multiply as Bdan add as s. Dua input numerik dipisahkan oleh koma.


1
Bagus! Bisakah kita mendapatkan penjelasan?
Emigna

Terima kasih atas jawabannya, (+1). Bisakah ia menangani input dalam jumlah besar?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀harus bisa menangani angka yang berubah-ubah
Biru

Saya tidak dapat menguji kode Anda karena web diblokir karena melanggar kebijakan penggunaan internet orang tua saya. T_T
Anastasiya-Romanova 秀

Sesuatu seperti ini: Halaman Web Diblokir! Anda telah mencoba mengakses halaman web yang melanggar kebijakan penggunaan internet Anda. URL: pyke.catbus.co.uk/?code=RE%60DltImbRoKr%29oh&input=B%0A21%2C+111&warnings=0 Kategori: Belum diberi peringkat
Anastasiya-Romanova 秀

8

JavaScript (ES6), 59

Fungsi rekursif, format input dirancang untuk menyederhanakan panggilan rekursif:

  • operator: '+' atau '*'
  • operan: array dua nilai
f=(o,v,s=1,t=eval(v.join(o)))=>t>9?f(o,[...t+''],s+1):[t,s]

Uji

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


Terima kasih atas jawabannya, (+1). Bisakah ia menangani input dalam jumlah besar?
Anastasiya-Romanova 秀

1
@ Anastasiya-Romanova 秀 hingga batas format angka javascript, 53 bit presisi (17 angka desimal)
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)

Input adalah string seperti 81+31, output adalah tupel dari string tunggal dan penghitung (misalnya ('4', 2),.

Uji di Ideone .


Jika mengambil input sebagai array string dan string tunggal diizinkan, misalnya, f(['81', '31'],'+')byte lebih lanjut dapat disimpan, tetapi rasanya seperti meregangkan aturan agak terlalu jauh ...
Dennis


... dalam hal ini saya bahkan melangkah lebih jauh dan mempertimbangkan untuk lulus operator.addatau operator.mulmasing - masing;)
Tobias Kienzler

7

Pyth, 16

eJ.uvjhQ`N.vQ)lJ

Mengambil input seperti "+ 123 12"untuk penambahan, dan "* 123 12"untuk perkalian. Output seperti result<linefeed>steps.

Cobalah di sini , atau jalankan Test Suite , tetapi perhatikan bahwa ini bergantung pada eval, jadi hanya varian tambahan yang akan berfungsi di penerjemah online. Perkalian bekerja dengan benar dengan penerjemah offline.

Ini menggunakan fungsi reduksi kumulatif untuk membuat daftar hasil antara, jadi untuk "+ 351 14568"kita dapatkan [14919, 24, 6]. Ini berfungsi karena angka satu digit adalah titik tetap dari penambahan dan perkalian Anastasiya. Kemudian kita hanya mendapatkan elemen terakhir dari array serta panjang array.

Ini akan bekerja untuk jumlah besar yang sewenang-wenang, setidaknya sampai Anda kehabisan memori.


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

Tidak Disatukan:

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

ifelsekembali ! Ya!
Tidak

Penggunaan:

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

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

Terima kasih banyak kepada @plannapus karena bermain golf 24 byte!
-7 byte berkat ide bagus dari @Vlo !


Ya, tolong tambahkan penjelasan karena saya suka R! Ini adalah bahasa kedua saya setelah VBA. (+1)
Anastasiya-Romanova 秀

1
@ Anastasiya-Romanova 秀: Selesai!
Frédéric

@plannapus: Sangat bagus! Terima kasih banyak !
Frédéric

1
@ Frédéric, penggunaan yang bagus strtoi! 4 byte lagi, Anda telah mengalahkan saya.
plannapus

1
Sepertinya Anda dapat melanjutkan golf dari byte dengan memasukkan definisi O dalam penugasan x dalam operasi pertama: x = (O = sakelar (S, jumlah, `*`)) (G, D) ;.
rturnbull

6

05AB1E , 20 15 byte

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

Penjelasan

[       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

Operator adalah 1 untuk penambahan, 0 untuk perkalian.

Cobalah online


Terima kasih atas jawabannya, (+1). Bisakah ia menangani input dalam jumlah besar?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 Saya tidak melihat alasan mengapa tidak. Apakah kamu punya contoh?
Emigna

Program Anda telah diuji untuk input semacam itu, sehingga sempurna :)
Anastasiya-Romanova

6

Jelly , 11 10 byte

Dj⁹VµÐĿḊĖṪ

Input adalah sepasang angka dan salah satu +atau ×.

Cobalah online! atau verifikasi semua kasus uji .

Bagaimana itu bekerja

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

Kode Mesin ARM, 48 byte

Hex dump:

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

Fungsi ini tidak bergantung pada panggilan sistem atau fungsi pustaka. Ini adalah kode Thumb-2, yang merupakan pengodean instruksi panjang variabel (2 atau 4 byte) untuk ARM 32-bit. Dengan demikian, nilai maksimum yang dapat diproses adalah 2 ^ 32-1. 2 byte dapat dihapus jika tidak sesuai dengan AAPCS ( 46 byte ), karena kita tidak perlu menumpuk register di awal.

Perakitan tidak disatukan (sintaksis 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

Skrip pengujian dalam 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 karakter

Pendekatan yang agak berbeda dari @ Frédéric :

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

Diindentasi, dengan baris baru:

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
    }

Baris 4 mungkin perlu penjelasan lebih lanjut:

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

Kasus uji:

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

Sangat disayangkan Anda datang terlambat dengan jawaban ini, tetapi Anda punya jawaban saya. Terima kasih telah membuat ini di R.
Anastasiya-Romanova 秀

Kenapa disayangkan?
plannapus

Karena jika Anda datang lebih dulu, maka Anda akan mendapatkan lebih banyak suara positif
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 Cukup adil :)
plannapus

Poin bonus karena fmenjadi nama fungsi dan salah satu argumennya :)
JDL

4

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

Memutuskan untuk menerjemahkan ini ke Octace, untuk mengambil keuntungan dari pengindeksan langsung, dan meningkatkan kapabilitit. Mengambil input pada formulir:, di f(a,operator)mana a = [number1, number2], dan operator==1memberikan produk, dan operator==2memberikan jumlahnya.

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

Penjelasan:

g={@prod,@sum}{o} : Memilih fungsi, produk, atau jumlah yang sesuai dan menugaskannya g

x=g(a) mengambil jumlah atau produk dari input

i=1; ... i++ : Incrementer untuk menghitung jumlah langkah

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

Menghapus dua baris baru, spasi, dan menempatkan kedua angka input dalam vektor, bukan argumen terpisah. Ini menghemat 9 byte, terima kasih untuk pajonk! Dihapus k=@(x)...untuk menyimpan 11 byte lagi berkat gelas kimia =) Akhirnya, terjemahkan semuanya ke Octave untuk menyimpan 9 byte lagi ...


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

Argumen pertama hanyalah penghitung, selalu 0

Argumen kedua adalah metode, 0 untuk ADD dan 1 untuk MULTIPLY.

Argumen ketiga adalah array dari Strings, yang berisi nilai-nilai untuk ditambahkan / dikalikan.

Tidak disatukan

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

terima kasih kepada @Kevin Cruijssen karena telah memotong beberapa byte.

terima kasih kepada @milk untuk mencukur 5 byte.

Program Tes

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

Bagus, lebih pendek dari jawaban Java saya . Namun, Anda juga harus mencetak langkah-langkah serta jawaban yang saat ini hilang dari jawaban Anda ..
Kevin Cruijssen

@KevinCruijssen Ahh. Itu membosankan .. Saya akan coba memperbaikinya sekarang.
Shaun Wild

Btw, Anda bisa sedikit golf jawaban Anda saat ini. m==0bisa m<1, dan Integer.parseIntbisa Integer.decode.
Kevin Cruijssen

Saya tidak banyak menggunakan Java, tetapi apakah Anda membutuhkan jvar pada akhirnya? Inlining (r+"")dua kali kelihatannya akan mencukur beberapa byte.
susu

1
Bisakah kita tidak mengubah posting saya di masa depan? Jika Anda ingin menyarankan edit lakukan di komentar.
Shaun Wild

3

Jelly , 17 byte

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

Cobalah online!

Diberikan argumen seperti x y 1, ini menghitung jumlah Anastasiya x (+) y.

Diberikan argumen seperti x y 0, ini menghitung produk Anastasiya x (*) y.

Output diberikan sebagai [number of steps, result].


Terima kasih atas jawabannya, tetapi output program Anda tidak mengandung jumlah langkah yang diperlukan? Apakah saya melewatkan sesuatu di sini?
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

Akan segera memposting penjelasan.

Input dalam bentuk 12+12atau 5*35(dengan tanda +dan normal *), dan mengasumsikan bahwa hanya dua operator itu.

Ia dapat menangani input angka sebesar yang dimungkinkan oleh memori komputer Anda.

Saya hampir pasti yakin bahwa ini bisa lebih jauh.

EDIT: 16 31 byte disimpan berkat @ Kopper.


Terima kasih atas jawabannya, (+1). Bisakah ia menangani input dalam jumlah besar?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 Uhmmm ... Saya cukup yakin mereka bisa. Bisakah Anda memberi saya contoh input besar? Saya akan mencoba dan menghitung dari itu.
clismique

Mungkin: 3218753647208435810122106 * 29349566754?
Anastasiya-Romanova 秀

1
@ Anastasiya-Romanova 秀 Ya, itu bekerja dalam ~ 0,5 detik, tidak tepat waktu.
clismique

Anda dapat mengubah "+" if "+" in s else "*"ke "*+"["+"in s], dan alih-alih menugaskannya t, tambahkan saja inline dalam execpanggilan.
Tembaga

3

R, 110 byte

Menggunakan splitter @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

Keluaran

> 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

sunting: Saya tidak bisa menghitung.


R luar biasa karena memungkinkan kita mempersingkat fungsinya, sesuatu yang berharga dalam bermain 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)))))

Fungsi disebut seperti ini:

(f + 81 31)

Berikut adalah kode yang tidak ditandai:

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

Ingatlah bahwa Clojure masih baru bagi saya, jadi ini mungkin bukan solusi terbaik. Tantangannya sama-sama menyenangkan. Selain itu, kode dijalankan dengan angka yang sangat besar tanpa kesulitan.


Ini sangat terlambat, tetapi Anda dapat mengurangi sebagian besar ruang di sana.
clismique

2

Perl 6 53 byte

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

Karena ( 12, &[+], 123 )dapat diterima untuk input, saya bisa turun ke 53 byte.
( &[+]kependekan &infix:<+>yang merupakan "penghormatan" kepada operator penjumlahan infiks numerik)

Jika argumen kedua harus berupa string, (+)itu akan menjadi 87 byte

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

Penjelasan:

# 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
  +$/
}

Uji:

#! /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;
}

Penggunaan Normal:

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

Fungsi anonim yang mengambil input melalui argumen dari operan pertama a, operator o( '+'atau '*') dan operan kedua b, dan mengembalikan daftar formulir [result, steps].

Bagaimana itu bekerja

Fungsi anonim membuat string dengan menggabungkan operan dengan operator di antara mereka, dan kemudian mengevaluasinya; ini adalah langkah pertama yang dijelaskan dalam pertanyaan. Kemudian, nilai ini dan operator diteruskan ke fungsi rekursif g. Di sini, penghitung i, yang ditambahkan untuk setiap panggilan rekursif, digunakan. Jika input kurang dari 10, satu digit pasti telah tercapai, jadi ini dan idikembalikan. Jika tidak, input dikonversi ke string dan setiap karakter dalam string ini digabungkan dengan operator, memberikan perhitungan yang diinginkan, yang kemudian dievaluasi dan diteruskan ke fungsi secara rekursif.

Cobalah di Ideone


(+1) sambil menunggu penjelasan :)
Anastasiya-Romanova 秀

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

Merosot

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

Penjelasan

Berbasis pada solusi @Sean Bean untuk Java.

  • p: Penutupan (fungsi, lambda, apa pun) yang mengimplementasikan solusi
  • t: Kedalaman panggilan saat ini (jumlah iterasi), pharus selalu dipanggil dengant=1
  • m: Operasi untuk melakukan, 0untuk "tambah", 1untuk "multiply"
  • d: Daftar operan, setiap operan adalah objek String
  • e: Elemen-elemen dari d, masing-masing dikonversi ke Integer
  • r: Jumlah atau produk e, tergantung pada operasinyam
  • pernyataan hasil, dimulai dengan r > 9:
    • Jika multi-digit ( r > 9), pasang kembali, tambah kedalaman tdan konversi rke daftar string digit (dan kembalikan hasil).
    • Jika satu digit, kembali rdan tsebagai daftar.

Program Tes

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

Hasil

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

Mengembalikan daftar dua elemen dengan hasil dan jumlah langkah. Bekerja untuk jumlah besar yang sewenang-wenang. Contoh penggunaan: (351#14568)(+)-> [6,3].

Sunting: Terima kasih kepada @BlackCap selama 6 byte.


Anda dapat menggantinya (-48+).fromEnumdenganread.pure
BlackCap

2

R, 91 byte

Menggunakan kode @ Vlo, yang menggunakan splitter @ plannapus, dan beberapa ide yang saya hasilkan saat bermain golf jawaban @ Frédéric, ini adalah jawaban R terpendek. (Sejumlah besar jawaban R di sini hari ini ...)

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

Yang terpenting, ini mensyaratkan bahwa input untuk operator adalah sumuntuk (+) atau produntuk (*). Di bawah aturan tantangan, ini tampaknya baik-baik saja.

Dengan lekukan:

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

Perbedaan utama dari jawaban @ Vlo adalah:

  1. Alih-alih menggunakan Reduce, kami mengandalkan argumen input sebagai fungsi, dan sebut saja secara eksplisit. (Yay untuk fungsi menjadi objek kelas satu!)
  2. Alih-alih menginisialisasi variabel baru sebagai penghitung kami, kami menyalahgunakan bawaan dan penggunaan R T, yang dievaluasi menjadi TRUE(alias 1), tetapi karena itu bukan variabel cadangan kami dapat memodifikasinya. Dengan demikian T+Tadalah 2. Jadi kami menggunakannya sebagai penghitung kami.
  3. Alih-alih catmenggunakan output, kami hanya mengembalikannya dengan vektor c. Serta menghemat dua byte, fakta bahwa output dipaksa menjadi vektor memastikan Tkelas numeric. Jika kami menggunakan cat, dan Tbelum bertambah, maka kami mendapatkan output yang salah seperti 1 TRUE.

Anda dapat merestrukturisasi whilelingkaran sebagai berikut, mengubah Fmenjadi sesuatu yang lain untuk konflik nama menghindari: 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)}}. Sungguh menakjubkan betapa banyak trik golf R yang kami buat dalam beberapa tahun terakhir :)
Giuseppe

@Giuseppe Restrukturisasi yang bagus! Saya tidak dapat menemukan konsensus meta saat ini, tetapi saya cukup yakin bahwa menggunakan trik Tdan Fkontra dalam suatu fungsi sebenarnya tidak valid, karena itu berarti bahwa fungsi tersebut hanya dapat dipanggil sekali. Jadi jawaban ini (dan beberapa jawaban saya yang lain!) Tidak valid, kecuali ada yang eksplisit rm(T)di bagian akhir. Aku akan terus mencari posting meta itu jadi aku bisa yakin aku tidak hanya memimpikannya.
rturnbull

Saya percaya bahwa Tdan Ftrik benar-benar berlaku selama Anda tidak mengubah Tatau Fdalam lingkungan global. misalnya, f=function(){T=T+1;T}secara konsisten kembali 2. Saya pikir ini adalah pos meta yang Anda referensikan.
Giuseppe

@ Giuseppe Ah ya, Anda benar dalam kedua hal. Terima kasih!
rturnbull

1

Ruby, 55 byte

Panggilan rekursif. Dulu sangat berbeda dari jawaban JavaScript @ edc65, tetapi ketika saya mengoptimalkannya akhirnya menjadi port langsung yang dikembangkan hampir secara independen dari jawaban mereka, minus satu optimasi akhir yang melibatkan memeriksa hasil yang dievaluasi alih-alih panjang daftar operan yang dilewatkan dalam , yang memungkinkan saya untuk melampaui jumlah byte mereka.

Input adalah string yang mewakili operator, dan array yang berisi operan.

Cobalah online.

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

Hasilnya benar, tetapi jumlah langkah yang diperlukan untuk mendapatkan nilai satu digit tidak benar. Bisakah Anda memperbaiki kode Anda?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 ah, kau benar. Logika lama saya mengharuskannya untuk memulai i=0dan saya agak lupa ketika refactoring.
Nilai Tinta

1

Perl, 38 byte

Termasuk +2 untuk -ap

Jalankan dengan input pada STDIN dan spasi di sekitar operator:

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

Outputnya digit dan langkah dipisahkan oleh +A

amath.pl:

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

Jika mengeluarkan langkah-langkah di unary adalah ok, versi 35 byte ini berfungsi lebih baik:

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

1

Mathematica, 105 94 byte

Kode.

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

Pemakaian.

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

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

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

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

Penjelasan.

Dua fungsi x(untuk (+)) dan y(untuk (*)) diciptakan pada saat yang sama dengan mengganti parameter fdan odi

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

dengan nilai-nilai yang sesuai. Karena x, fmenjadi #1 + #2dan omenjadi Plus; karena y, mereka masing-masing menjadi #1 #2dan Times. Menulis ulang fungsi xuntuk bagian terakhir dari penjelasan:

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

Ini menggunakan long(nilai maksimum 2 63 -1). Jika itu akan digunakan intsebagai gantinya (nilai maksimum 2 31 -1) itu hanya akan menjadi 1 byte lebih sedikit ( 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);}

Kemungkinan besar bisa bermain golf lebih banyak. Namun, harus mencetak langkah-langkah serta jawaban untuk kedua operator memerlukan beberapa byte.
Menggunakan 0 (untuk (+)) dan 1 (untuk (*)).

Tidak digabungkan & kode uji:

Coba di sini.

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

Keluaran:

4,2
6,3
8,3
0,2
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.