Anastasiya dünyasında matematik nasıl çalışır?


44

Arka fon:

Gerçek dünyada temel toplama ve çarpma gibi standart işlem matematik aşağıdaki gibi çalışır:

12 + 123 = 135

ve

12 * 123 = 1476

Bu ilginç ve sıkıcı değil! Pek çok okul zaten bunu resmi algoritmaların pratik, pratik, pratik olarak yorumluyor. Bu oldukça katı ve sıkıcı bir matematiksel diyet anlamına gelir ve bu zorlukla amaçlanan şey değildir. Sevgili sitemizde biraz eğlenmeye hazır olun.

İki pozitif tamsayı numarası ekleme işlemini, ardından sonucunun tüm rakamlarını tekrar ekleme işlemini düşünün. Sadece tek bir rakam elde edilinceye kadar ilavesi ile tekrarlama. Örneğin:

  1. Sonucu 12 + 123135 olduğunu.
  2. 135 rakamının hepsini ekleyerek elde ediyoruz 1 + 3 + 5 = 9.

Bu tekrarlanan ilavede tek bir rakam 9 elde etmek için gerekli adım sayısı 2'dir.

Eklemenin önceki işlemlerinde olduğu gibi, iki pozitif tamsayı sayısının çarpımı aynı işlemi izler. Sonucunun tüm rakamlarını çarpın ve sonra bu işlemi sadece bir rakam kalana kadar tekrarlayın. Yukarıdaki örneği ele alalım:

  1. Sonucu 12 * 1231476 olduğunu.
  2. Elde ettiğimiz 1476 rakamlarının hepsini çarp 1 * 4 * 7 * 6 = 168.
  3. Elde ettiğimiz 168 hanenin tekrarını çarpın 1 * 6 * 8 = 48.
  4. Elde ettiğimiz 48 rakamın tüm rakamlarını tekrar çarpın 4 * 8 = 32.
  5. Elde ettiğimiz 32 hanenin tümü bir kez daha çarpılır 3 * 2 = 6.

Bu tekrarlanan çarpma işleminin bir tek basamaklı 6 değerini elde etmek için gerekli adım sayısı 5'tir.

Bu zorluğun uğruna ve herhangi bir matematik gösteriminin kötüye kullanılmasından kaçınılması için, bu iki sahte gösterimi tanıtıyorum: (+)ve (*), ancak , aşağıdaki gibi çalışan, istediğiniz herhangi bir gösterimi kullanabilirsiniz :

  1. Tek bir değer elde etmek için tekrarlanan ekleme işleminin çalışmasıdır 12 (+) 123 = 9.
  2. Tek bir değer elde etmek için tekrarlanan çarpma işleminin işlemidir 12 (*) 123 = 6.

Meydan okuma:

Zorluk, arka plan bölümünde açıklandığı gibi her iki işlemi de gerçekleştirebilecek bir program veya fonksiyon yazmaktır : (+)ve (*).

Giriş:

Program veya fonksiyon girişleri ya da iki pozitif tamsayılar ve bir işlem olup (+)ve (*). Girişin formatı, programcının keyfi bir seçimidir . Sen girişi, örneğin, biçimlendirmek edebilir a (+) bya F(a, (+), b)veya istediğiniz herhangi biçimi.

Çıktı:

Programın veya fonksiyonun çıktısı, işlemin sonucunu ve istediğiniz şekilde serbest biçimli biçimde gereken adım sayısını içermelidir.

Test Durumları (giriş ve çıkış formatlarını dikkate almayın):

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

Genel kurallar:

  • Bu , bu yüzden byte cinsinden en kısa cevap mücadeleyi kazanıyor.
    Esolangs'ın sizi normal dillerle cevap göndermekten caydırmasına izin vermeyin. Programlama dilinizle mümkün olduğunca kısa bir cevap vererek bu zorluğun tadını çıkarın. Akıllıca bir cevap ve net bir açıklama gönderirseniz, kullandığınız programlama diline bakılmaksızın cevabınız takdir edilecektir (dolayısıyla önyüklemeler).
  • Cevabınız için standart kurallar geçerlidir , bu nedenle STDIN / STDOUT, uygun parametrelerle fonksiyon / yöntem, tam programlar vb. Kullanmanıza izin verilir. Seçim sizin.
  • Mümkünse, programınız büyük sayıları doğru şekilde kullanabilir. Değilse, bu sadece iyi olacak.

Oyun başlasın!!


Tekrarlanan ekleme kısmı ( dijital kök ) aslında codegolf.stackexchange.com/q/1128/194
Peter Taylor

4
Harika bir ilk soru! Ve genel kurallar biçimini ve kendi Sorularımdaki cümleleri tanıyorum. ;)
Kevin Cruijssen

4
@KevinCruijssen Yup. doğru. Telif hakkı olmadığı için izniniz olmadan kopyalarım. Hehehe: D
Anastasiya-Romanova 秀

4
@ Anastasiya-Romanova 秀 "telif hakkı yok"? XXI yüzyılda? Hayır; Burada her şey CC-BY-SA 3.0. İçerik gönderildiğinde izin verilir. Site altbilgisini kontrol edin.
Mindwin

1
@ BradGilbertb2gills Evet, elbette. Bu arada postayla belirtildi. Alıntı: "Girişin formatı, programcının keyfi bir seçimidir".
Anastasiya-Romanova 秀

Yanıtlar:


11

Dyalog APL , 33 32 30 29 bayt

Bu, APL'yi önek notasyonu +/A n₁ n₂ve ×/A n₁ n₂. (Aslında, solundaki herhangi bir işlemi kullanabilirsiniz /A.) {Result, repetition count} listesinin bir listesini döndürür.

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

A←{sol fonksiyon ve sağ argüman açısından daha üst düzey bir fonksiyon tanımlayın.⍺⍺

(⊃,≢) ilk elemanı, ardından

⍺⍺{verilen fonksiyon ( +/toplam veya ×/ürün için) üst düzey fonksiyona beslenir

benzersiz unsurları

⍵,⍨ eklenen argüman

⍺⍺ uygulanan fed işlevi

⍎¨ Her karakterin değerlendirilmesi

karakter gösterimi

⊃⍵ argümanın ilk elemanı

}⍣≡ Sonuç argüman ile aynı olana kadar tekrar tekrar uygulanır,

⍺⍺⍵orijinal argümana uygulanan başlangıçta beslenen işlev ( +/veya ×/)

} [yüksek dereceli fonksiyon tanımının sonu]

TryAPL çevrimiçi! ( güvenlik nedeniyle taklit edilmiştir e.)

Bir bayt tasarrufu için @ngn teşekkürler.


0 bayt (hareket halinde)

Dyalog APL aslında Anastasiyan matematiğine tam destek veriyor; yerine (+)ve (×)kullanır +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}ve ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}.

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


Cevap için teşekkürler, (+1). Çok sayıdaki girişi kaldırabilir mi?
Anastasiya-Romanova 秀

1
Eğer ayarlarsanız ⎕FR←1287(yani, IEEE 754-2008 128 bit ondalık kullanmak F loating noktalı R ve ePresentation) ⎕PP←34(yani kullanım 34 karakterlerin P rint P resizyonunu) kullanarak, 10³⁴ altında tamsayılar kullanabilirsiniz.
Adám

Hmm, tam desteğine sahip olsa bile, değil +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}ve ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}epeyce bayt hala? Bunun 0 bayt olduğu hakkında kafam karıştı ..: S
Kevin Cruijssen 24:16

3
@KevinCruijssen OP, herhangi bir giriş göstergesine izin verir. Bu yüzden, eğer bir dil varsayılan gösterimde bulunmazsa Anastasiyan matematiği kutusundan çıkarsa, çok karakterli glif (+)Anastasiyan + olur. Dyalog APL, Anastasiyan matematiğini desteklemektedir, ancak tıpkı *güç anlamına gelir ve ×çarpma için ihtiyaç duyduğunuz gibi , /çoğaltma ve ÷bölme için ihtiyaç duyduğunuz gibi farklı bir çok karakterli glif kullanır .
Adám

1
@ Adám Ah tamam, bu mantıklı. OP'nin kurallarını esnetiyor, ama onları kırmıyor. Giriş yerine sahip (+)olmanız oldukça garip +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}, ancak OP gerçekten herhangi bir giriş biçiminin yapılacağını belirttiğinden, işlevi parametre olarak kullanabilirsiniz. Hmm, bunun da giriş işlevi gören diğer programlama dillerinde de mümkün olup olmadığını merak ediyorum.
Kevin Cruijssen

8

Haskell, 108 bayt

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

Fonksiyon tanımlar #ilk alır ave bdaha sonra operatör ve o. Eğlenceli gerçek: Bu istediğiniz herhangi bir operatörle (aslında, herhangi bir fonksiyonla) çalışır!


Cevap için teşekkürler, (+1). Çok sayıdaki girişi kaldırabilir mi?
Anastasiya-Romanova 秀

4
@ Anastasiya-Romanova 秀 Evet, Haskell'in Integertürü sınırsız olduğundan RAM'iniz kadar büyük sayıları yönetebilir .
ThreeFx

8

Pyke, 16 bayt

RE`DltImbRoKr)oh

Burada dene!

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

Olarak çarpın Bve ekleyin s. İki sayısal giriş virgül ile ayrılır.


1
Güzel! Bir açıklama alabilir miyiz?
Emigna,

Cevap için teşekkürler, (+1). Çok sayıdaki girişi kaldırabilir mi?
Anastasiya-Romanova 秀

Anastasiya-Romanova @秀o gerektiğini keyfi sayılar idare edebilmek
Mavi

Kodunuzu test edemiyorum çünkü web engellendi çünkü ebeveynlerimin internet kullanım politikasını ihlal ediyor. T_T
Anastasiya-Romanova 秀

Bunun gibi bir şey: Web Sayfası Engellendi! İnternet kullanım politikanızı ihlal eden bir web sayfasına erişmeye çalıştınız. URL: pyke.catbus.co.uk/?code=RE%60DltImbRoKr%29oh&input=B%0A21%2C+111&warnings=0 Kategori: Derecelendirilmemiş
Anastasiya-Romanova

8

JavaScript (ES6), 59

Özyinelemeli işlev, giriş biçimi özyinelemeli aramayı kolaylaştırmak için uyarlanmıştır:

  • operatör: '+' veya '*'
  • operands: iki değer dizisi
f=(o,v,s=1,t=eval(v.join(o)))=>t>9?f(o,[...t+''],s+1):[t,s]

Ölçek

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


Cevap için teşekkürler, (+1). Çok sayıdaki girişi kaldırabilir mi?
Anastasiya-Romanova 秀

1
@ Anastasiya-Romanova 秀 javascript sayısal formatının sınırına kadar, 53 hassasiyet biti (17 ondalık basamak)
edc65

8

Python 2,60 bayt

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

Giriş bir dizedir 81+31, çıktı bir singleton dizesinin bir dizisi ve bir sayıcıdır (ör ('4', 2).

İdeone üzerinde test et .


Bir dizge dizisi olarak girdi almaya ve tek bir dizgeye izin verilirse, örneğin, f(['81', '31'],'+')başka bir bayt kaydedilebilir, ancak bu kuralları biraz fazla germek gibi hissettirir ...
Dennis


... bu durumda bile ileriye gidip geçmeyi operator.addya da operator.mulsırasıyla
düşünmeyi düşünürdüm

7

Pyth, 16

eJ.uvjhQ`N.vQ)lJ

Toplama "+ 123 12"ve "* 123 12"çarpma gibi girdiler alır . Çıkışlar gibi result<linefeed>steps.

Burada deneyin ya da bir Test Suite çalıştırın , ancak bunun değerlendirmenin yapıldığına dikkat edin, bu nedenle yalnızca ekleme varyantı çevrimiçi tercümanda çalışacaktır. Çarpma çevrimdışı tercüman ile düzgün çalışır.

Bu nedenle için, ara sonuçların listesini oluşturmak için kümülatif azaltma işlevini kullanır "+ 351 14568"elde ederiz [14919, 24, 6]. Bu işe yarıyor, çünkü tek haneli sayılar Anastasiya toplama ve çarpma işleminin sabit bir noktası. Sonra dizinin uzunluğunun yanı sıra dizinin son elemanını da alırız.

Bu, en azından hafızanız tükenene kadar keyfi olarak büyük sayılar için işe yarar.


7

R, 175 167 164 140 134 127 126 119 bayt

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

Ungolfed:

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

ifelsegeri döndü ! Evet!
Nop

Kullanım:

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

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

@Plannapus'a 24 byte'lık golf attığınız için çok teşekkür ederiz ! @Vlo'dan iyi bir fikir sayesinde
-7 bayt !


Evet, R'yi sevdiğim için lütfen açıklamalar ekleyin! Bu, VBA'dan sonraki ikinci dilim. (+1)
Anastasiya-Romanova 秀

1
@ Anastasiya-Romanova 秀: Yapıldı!
Frédéric,

@plannapus: Gerçekten güzel! Çok teşekkürler !
Frédéric,

1
@ Frédéric güzel kullanımı strtoi! 4 bayt daha beni yendi.
plannapus

1
İlk işlemde, x atamasında O tanımını ekleyerek bir bayttan daha fazla golf oynayabileceğiniz anlaşılıyor: x = (O = anahtar (S, toplam, `*`)) (G, D) ;.
rturnbull

6

05AB1E , 20 15 bayt

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

açıklama

[       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

Operatör toplama için 1, çarpma için 0'dır.

Çevrimiçi deneyin


Cevap için teşekkürler, (+1). Çok sayıdaki girişi kaldırabilir mi?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova why Neden olmasın bir sebep görmüyorum. Bir örnek var mı
Emigna

Programınız bu tür girdiler için test edilmiştir, bu yüzden mükemmel olur :)
Anastasiya-Romanova 秀

6

Jöle , 11 10 bayt

Dj⁹VµÐĿḊĖṪ

Girdi numaraları ve ya bir çift +ya ×.

Çevrimiçi deneyin! veya tüm test durumlarını doğrulayın .

Nasıl çalışır

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

ARM Makine Kodu, 48 bayt

Hex dökümü:

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

Bu işlev hiçbir sistem çağrısına veya kütüphane işlevine bağlı değildir. Bu, 32 bit ARM için değişken uzunluklu bir talimat kodlaması (2 veya 4 bayt) olan Thumb-2 kodudur. Dolayısıyla, işleyebileceği maksimum değer 2 ^ 32-1'dir. AAPCS'ye ( 46 byte ) uygun değilse 2 byte atılabilir , çünkü başlangıçta kayıtları istiflememiz gerekmez.

Ungolfed derleme (GNU sözdizimi):

.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

C'deki test komut dosyası:

#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

@ Frédéric'ten biraz farklı bir yaklaşım :

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

Newlines ile girintili:

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
    }

Satır 4 muhtemelen daha fazla açıklama gerektirir:

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

Test durumları:

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

Talihsiz bir şekilde bu cevaba geç kaldınız, ancak benim artı oyum var. Bunu
R.'da

Neden talihsiz?
plannapus

Çünkü eğer ilk önce gelseydin daha fazla oy hakkın olurdu
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 Yeterli fuar :)
plannapus

fHem fonksiyon ismi hem de argümanlarından biri olduğu için bonus puanları :)
JDL

4

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

Doğrudan İndekslemeden ve kapasite artırımından yararlanmak için bunu Octace'ye çevirmeye karar verdim. Formdaki girdiyi alır:, f(a,operator)nerede a = [number1, number2]ve operator==1ürünü operator==2verir ve toplamı verir.

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

açıklamalar:

g={@prod,@sum}{o} : Uygun işlevi, ürünü veya toplamı seçer ve atar. g

x=g(a) girdilerin toplamını veya ürününü alır

i=1; ... i++ : Adım sayısını saymak için artırı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

İki yeni satır kaldırıldı, bir boşluk bırakıldı ve her iki giriş numarasını ayrı argümanlar yerine bir vektöre yerleştirdi. Bu 9 bayt kurtardı, pajonk sayesinde! k=@(x)...Beher ile 11 byte daha tasarruf etmek için kaldırıldı =) Sonunda 9 byte kurtarmak için her şeyi Octave'ye çevirdik ...


4

Java, 164 159 146 bayt

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

İlk argüman sadece sayaç, her zaman 0

İkinci argüman ADD için 0, MULTIPLY için 1 metodudur.

Üçüncü argüman, eklenecek / çarpılacak değerleri içeren bir Dizge dizisidir.

Ungolfed

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

@Kevin Cruijssen'e birkaç byte'lık kesimleri için teşekkür ederiz.

5 byte tıraş için @milk sayesinde.

Test programı

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

Güzel, Java cevabımdan daha kısa . Ancak, şu anda cevabınızdaki cevapları cevaplayacağınız gibi, basamakları da yazmanız gerekiyor ..
Kevin Cruijssen

@KevinCruijssen Ahh. Bu sıkıcı .. Şimdi düzeltmeye çalışacağım.
Shaun Wild

BTW, şu anki cevabınızı biraz golf oynayabilirsiniz. m==0olabilir m<1ve Integer.parseIntolabilir Integer.decode.
Kevin Cruijssen

Java'yı pek kullanmıyorum, ama jsonunda buna ihtiyacın var mı? (r+"")İki kere eğilmek birkaç byte'ı tıraş edecek gibi görünüyor.
Süt

1
Gelecekteki yayınlarımı değiştiremez miyiz? Bir düzenleme önermek istiyorsanız yorumlarda bunu yapın.
Shaun Wild

3

Jöle , 17 bayt

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

Çevrimiçi deneyin!

x y 1Bu gibi argümanlar verildiğinde , bu Anastasiya toplamını hesaplar x (+) y.

x y 0Bu gibi argümanlar verildiğinde , bu Anastasiya ürününü hesaplar x (*) y.

Çıktı olarak verilir [number of steps, result].


Cevabınız için teşekkürler, ancak program çıktınız gerekli olan kısım sayısını içermiyor mu? Burada bir şey mi eksik?
Anastasiya-Romanova 秀

3

Python, 160 146 129 bayt

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

Yakında bir açıklama gönderir.

Girdi biçimindedir 12+12veya 5*35(normal +ve *işaretlerle) ve bunların yalnızca iki operatör olduğunu varsayar.

Bilgisayarınızın belleğinin izin verdiği kadar sayı girişi yapabilir.

Neredeyse kesinlikle bunun daha fazla olabileceğine eminim.

EDIT: @Copper sayesinde 16 31 bayt kaydedildi.


Cevap için teşekkürler, (+1). Çok sayıdaki girişi kaldırabilir mi?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 Uhmmm ... Yapabileceklerinden oldukça eminim. Bana büyük girdilerden örnekler verebilir misiniz? Onlardan hesaplamaya çalışacağım.
Clismique

Belki: 3218753647208435810122106 * 29349566754?
Anastasiya-Romanova 秀

1
@ Anastasiya-Romanova 秀 Evet, ~ 0.5 saniye içinde çalıştı, zamanı gelmedi.
clismique

Değişebilirsin "+" if "+" in s else "*"için "*+"["+"in s], ve sonra yerine onu atama t, sadece satır içi eklemek execçağrı.
Bakır,

3

R, 110 bayt

@Plannapus 'splitter kullanma.

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

Çıktı

> 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

düzenleme: sayamıyorum.


R harika çünkü işlevini kısaltmamıza izin veriyor, golf oynamak için değerli bir şey. (+1)
Anastasiya-Romanova 秀

3

Clojure 126 bayt

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

İşlev şöyle denir:

(f + 81 31)

İşte kodlanmış kod:

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

Clojure'un benim için hala yeni olduğunu unutmayın, bu yüzden bu muhtemelen en iyi çözüm değil. Sorun aynı şekilde eğlenceliydi. Ek olarak, kod çok büyük rakamlarla herhangi bir zorluk çekmeden çalıştırıldı.


Bu çok geç, ama oradaki alanların çoğunu azaltabilirsiniz.
Clismique

2

Perl 6 53 bayt

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

( 12, &[+], 123 )Giriş için kabul edilebilir olduğundan , onu 53 bayta indirebilirim.
( sayısal infix ekleme operatörüne "saygı" olan &[+]kısadır &infix:<+>)

İkinci argümanın bir dize (+)olması gerekiyorsa, 87 bayt olacaktır.

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

Açıklama:

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

Ölçek:

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

Normal kullanım:

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

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)

İlk işlenenin a, bir işlecin o( '+'veya '*') ve ikinci işlenenin argümanını kullanarak girdi alan bve formun bir listesini döndüren adsız bir işlev [result, steps].

Nasıl çalışır

Anonim işlev, işlenenleri aralarında işleçle birleştirerek bir dize oluşturur ve sonra değerlendirir; Bu, soruda açıklanan ilk adımdır. Ardından, bu değer ve operatör özyinelemeli işleve geçirilir g. Burada, iher özyinelemeli çağrı için artırılan bir sayaç kullanılır. Girdiden küçükse 10, tek bir rakama ulaşılmış olmalıdır, bu nedenle bu idöndürülür. Değilse, giriş bir dizgeye dönüştürülür ve bu dizgideki her karakter operatör ile birleştirilir, istenen hesaplama yapılır ve ardından tekrar tekrar değerlendirilir ve fonksiyona aktarılır.

Ideone'da dene


(+1) açıklama beklerken :)
Anastasiya-Romanova 秀

2

Groovy, 102 bayt

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

Degolfed

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

açıklama

@Sean Bean'in Java için mükemmel çözümüne dayanarak.

  • p: Çözüm uygulayan kapatma (fonksiyon, lambda, her neyse)
  • t: Geçerli arama derinliği (yineleme sayısı), pdaimat=1
  • m: 0"Add", 1"multiply" için gerçekleştirilecek işlem
  • d: İşlenenlerin listesi, her işlenen bir String nesnesidir
  • e: dHer biri bir tamsayıya dönüştürülen öğeleri
  • r: eOperasyona bağlı olarak toplamı veya ürünüm
  • sonuç ifadesi, ile başlayan r > 9:
    • Çok basamaklı ( r > 9) ise, yeniden derle, derinlik arttırma tve rbasamak dizeleri listesine dönüştürme (ve sonuç döndür ).
    • Tek basamaklıysa, rve tbir liste olarak geri dönün .

Test programı

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

Sonuçlar

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

2

Haskell, 76 70 bayt

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

Sonuç ve adım sayısı ile birlikte iki öğe listesi döndürür. Keyfi büyük sayılar için çalışır. Kullanım örneği: (351#14568)(+)-> [6,3].

Düzenleme: 6 byte için @ BlackCap'e teşekkürler.


Sen yerini alabilir (-48+).fromEnumileread.pure
blackcap

2

R, 91 bayt

@ Plannapus'un bölücüsünü ve @ Frédéric'in cevabını golf yaparken ürettiğim bazı fikirleri kullanan @ Vlo kodunu kullanarak, bu henüz en kısa R cevabı. (Alışılmadık derecede çok sayıda R bugün burada cevaplar ...)

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

En önemlisi, bu operatör girişinin sum(+) veya prod(*) olmasını gerektirir. Mücadelenin kuralları uyarınca, bu tamam gibi görünüyor.

Girintili:

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

@ Vlo'nun cevabındaki ana farklar:

  1. Kullanmak yerine Reduce, girdi argümanının bir işlev olduğuna güveniyoruz ve açıkça onu çağırıyoruz. (Birinci sınıf nesneler olan işlevler için Yay!)
  2. Sayacımız olarak yeni bir değişken başlatmak yerine, (aka ) olarak Tdeğerlendiren R'nin yerleşiklerini ve kullanımını kötüye kullanıyoruz , ancak ayrılmış bir değişken olmadığından onu değiştirebiliriz. Bu nedenle bir . Bu yüzden bunu sayacımız olarak kullanıyoruz.TRUE1T+T2
  3. catÇıktıyı yerleştirmek yerine , onu sadece bir vektör olarak döndürürüz c. İki bayt kurtarmanın yanı sıra, çıkışın bir vektöre zorlanması gerçeği, bunun Tsınıf olmasını sağlar numeric. Eğer kullanırsak catve Tarttırılmadıysak, bunun gibi hatalı çıktılar alırız 1 TRUE.

Eğer yeniden yapılandırabilir whileaşağıdaki gibi değiştirilmesi, döngü Fönlemek adı çatışmalara başka bir şey olmak: 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)}}. Son birkaç yılda kaç tane R golf
Giuseppe

@Giuseppe Güzel yeniden yapılandırma! Şu anda meta konsensüsünü bulamıyorum, ancak bir işlev içinde Tand Fcounter hilesini kullanmanın aslında geçersiz olduğundan eminim , çünkü işlev yalnızca bir kez çağrılabilir. Öyleyse bu cevap (ve diğerleri benim!) rm(T)Sonunda açık bir şey olmadığı sürece geçersiz . Bu meta postayı aramaya devam edeceğim, böylece sadece hayal etmediğimden emin olabilirim.
rturnbull

Sizce Tve Fhile, siz değiştirmediğiniz sürece Tveya Fküresel ortamda tamamen geçerli olduğuna inanıyorum . örneğin, f=function(){T=T+1;T}sürekli döner 2. Bence bu sizin bahsettiğiniz meta yazı.
Giuseppe

@Giuseppe Ah evet, her iki durumda da haklısın. Teşekkürler!
rturnbull

1

Ruby, 55 bayt

Özyinelemeli arama. @ Edc65'in JavaScript yanıtından çok farklıydı, ancak optimize ettikten sonra, yanıtlarından neredeyse bağımsız bir şekilde geliştirilen doğrudan bir bağlantı noktası haline geldi; eksi, içinde geçirilen opera listesinin uzunluğu yerine değerlendirilen sonucun kontrol edilmesini içeren son bir optimizasyon oldu. Bu da onların bayt sayısını aşmamı sağladı.

Giriş, işleci temsil eden bir dize ve işlenenleri içeren bir dizidir.

Çevrimiçi deneyin.

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

Sonuç doğrudur, ancak tek basamaklı bir değer elde etmek için gereken adım sayısı yanlış. Kodunu düzeltebilir misin?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 ah, haklısın. Eski mantığım baştan başlamasını gerektiriyordu i=0ve yeniden yapılanmayı yaparken unutmuşum.
Value Ink

1

Perl, 38 bayt

İçin +2 içerir -ap

STDIN üzerindeki giriş ile ve operatörün etrafındaki boşluklarla çalıştırın:

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

Çıktı rakamdır ve adımlarla ayrılır +A

amath.pl:

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

Adımları unary'de çıkarmak tamamsa, bu 35 byte sürümü daha iyi çalışır:

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

1

Mathematica, 105 94 bayt

Kod.

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

Kullanımı.

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

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

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

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

Açıklama.

İki işlev xve ((+) için) y((*) için) parametrelerini değiştirerek aynı anda oluşturulur fve oiçinde

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

uygun değerleri ile. İçin x, folur #1 + #2ve oolur Plus; için y, bunlar sırasıyla haline #1 #2ve Times. xAçıklamanın son kısmı için işlevi yeniden yazma :

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 bayt

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

Kullanır long(maksimum 2 63 -1 değeri ). Bu kullanmak durumunda intyerine (2 maksimum değeri 31 -1) sadece 1 bayt daha az (olacaktır 191 bayt ):

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

Büyük olasılıkla biraz daha golf oynayabilir. Her iki operatörün cevabının yanı sıra adımları yazdırmak zorunda olsa da, bazı baytları alır.
0 (for (+)) ve 1 (for (*)) kullanır.

Ungolfed ve test kodu:

Burada dene.

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

Çıktı:

4,2
6,3
8,3
0,2
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.