[Question]
  [
# Background:
Standard operation math like basic addition and multiplication in the real world work like these:
```
12 + 123 = 135
```
and
```
12 * 123 = 1476
```
*That's not interesting and boring!* Many schools are already interpreting this as practice, practice, practice of formal algorithms. That implies a pretty rigid and boring mathematical diet and is not what is intended in this challenge. Get ready to play some fun on our beloved site.
Consider the process of adding two positive integer numbers, then adding again all the digits of its result. Repeating with the addition until only a single digit is obtained. For example:
1. The result of `12 + 123` is 135.
2. Adding all the digits of 135 we obtain `1 + 3 + 5 = 9`.
The number of steps required to obtain a single digit value 9 in this repeated addition is 2.
As with the previous process of the addition, the multiplication of two positive integer numbers follows the same process. Multiply all the digits of its result and then repeating this process until only a single digit remains. Take the above example:
1. The result of `12 * 123` is 1476.
2. Multiply all the digits of 1476 we obtain `1 * 4 * 7 * 6 = 168`.
3. Multiply again all the digits of 168 we obtain `1 * 6 * 8 = 48`.
4. Multiply again all the digits of 48 we obtain `4 * 8 = 32`.
5. Multiply once again all the digits of 32 we obtain `3 * 2 = 6`.
The number of steps required to obtain a single digit value 6 this repeated multiplication is 5.
For this challenge's sake and avoiding any misuse of math notations, I introduce these two dummy notations: `(+)` and `(*)`, **but you may use any notation you like**, which work like the followings:
1. The operation of repeated addition process to obtain a single value is `12 (+) 123 = 9`.
2. The operation of repeated multiplication process to obtain a single value is `12 (*) 123 = 6`.
# Challenge:
The challenge is to write either a program or a function which can perform **both of operations** as explained in the background section: `(+)` and `(*)`. 
# Input:
The inputs of the program or the function are two positive integers and one operation either `(+)` and `(*)`. **The format of the input is an arbitrary choice of the programmer**. You may format the input, for example, `a (+) b` or `F(a, (+), b)` or any format you wish.
# Output:
The output of the program or the function must contain the result of operation and the number of steps required with freestyle format as you wish.
Test Cases (ignore the input and output format):
```
    81 (+) 31       -->   (4 ; 2)
    351 (+) 14568   -->   (6 ; 3)
    21 (*) 111      -->   (8 ; 3)
    136 (*) 2356    -->   (0 ; 2)
```
# General rules:
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest answer in bytes wins the challenge.  
Don't let esolangs discourage you from posting an answer with regular languages. Enjoy this challenge by providing an answer as short as possible with your programming language. If you post a clever answer and a clear explanation, your answer will be appreciated (hence the upvotes) regardless of the programming language you use.
* [Standard rules apply](http://meta.codegolf.stackexchange.com/questions/2419/default-for-code-golf-program-function-or-snippet/2422#2422) for your answer, so you are allowed to use STDIN/STDOUT, functions/ method with the proper parameters, full programs, etc. The choice is yours.
* If possible, your program can properly handle large numbers. If not, that will just be fine.
---
[***Let the game begin!!***](http://pre10.deviantart.net/f372/th/pre/i/2013/159/9/4/let_the_game_begin__by_synergy14-d6893ns.jpg) 
  
[Answer]
# [Dyalog APL](http://goo.gl/9KrKoM), ~~33~~ ~~32~~ ~~30~~ 29 [bytes](https://codegolf.meta.stackexchange.com/a/9429/43319)
This extends APL to include the prefix notation `+/A n₁ n₂` and `×/A n₁ n₂`. (In fact, you can use any operation to the left of the `/A`.) Returns a list of {result, repetition count}.
```
A←{(⊃,≢)⍺⍺{∪⍵,⍨⍺⍺⍎¨⍕⊃⍵}⍣≡⍺⍺⍵}
```
> 
> `A←{` define a [higher-order function](https://en.wikipedia.org/wiki/Higher-order_function) in terms of left-hand function `⍺⍺`, and right-hand argument `⍵`
> 
> 
> 
> > 
> > `(⊃,≢)` the first element of, followed by the count of
> > 
> > 
> > `⍺⍺{` the supplied function (`+/` for sum or `×/` for product) fed to the higher-order function
> > 
> > 
> > 
> > > 
> > > `∪` the unique elements of
> > > 
> > > 
> > > `⍵,⍨` the argument appended to
> > > 
> > > 
> > > `⍺⍺` the fed function applied to
> > > 
> > > 
> > > `⍎¨` the evaluation of each character of
> > > 
> > > 
> > > `⍕` the character representation of
> > > 
> > > 
> > > `⊃⍵` the first element of the argument
> > > 
> > > 
> > > 
> > 
> > 
> > `}⍣≡` applied repeatedly until the result is identical to the argument, beginning with
> > 
> > 
> > `⍺⍺⍵` the originally fed function (`+/` or `×/`) applied to the original argument
> > 
> > 
> > 
> 
> 
> `}` [end of higher-order function definition]
> 
> 
> 
[TryAPL online!](http://tryapl.org/?a=e%u2190%7B%7B1%3D%u2374%u2375%3A%u236C%u2374%u2375%u22C4%u2375%7D%u2283%7B%u237A/%u2375%7D/%u2395VFI%20%u2375%7D%20%u22C4%20A%u2190%7B%28%u2283%2C%u2262%29%u237A%u237A%7B%u222A%u2375%2C%u2368%u237A%u237Ae%A8%u2355%u2283%u2375%7D%u2363%u2261%u237A%u237A%u2375%7D%20%u22C4%20+/A%2081%2031%20%u22C4%20+/A%20351%2014568%20%u22C4%20%D7/A%2021%20111%20%u22C4%20%D7/A%20136%202356&run) (`⍎` has been emulated with `e` for security reasons.)
Thanks to @ngn for saving a byte.
---
# 0 bytes (in jest)
Dyalog APL actually already has full support for Anastasiyan math; instead of `(+)` and `(×)`, it uses `+{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}` and `×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}`.
Try [`81 +{(⊃,≢)⍺⍺{∪⍵,⍨⍺⍺e¨⍕⊃⍵}⍣≡⍺⍺/⍺⍵} 31`](http://tryapl.org/?a=e%u2190%7B%7B1%3D%u2374%u2375%3A%u236C%u2374%u2375%u22C4%u2375%7D%u2283%7B%u237A/%u2375%7D/%u2395VFI%20%u2375%7D%20%u22C4%2081%20+%7B%28%u2283%2C%u2262%29%u237A%u237A%7B%u222A%u2375%2C%u2368%u237A%u237Ae%A8%u2355%u2283%u2375%7D%u2363%u2261%u237A%u237A/%u237A%u2375%7D%2031&run) and [`21 ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/e¨⍕⍵}⍣=⍵⍺⍺⍨⍺} 111`](http://tryapl.org/?a=e%u2190%7B%7B1%3D%u2374%u2375%3A%u236C%u2374%u2375%u22C4%u2375%7D%u2283%7B%u237A/%u2375%7D/%u2395VFI%20%u2375%7D%20%u22C4%2021%20%D7%7Bn%u21900%u22C4n%2C%u237A%u237A%7Bn+%u21901%u22C4%u237A%u237A/e%A8%u2355%u2375%7D%u2363%3D%u2375%u237A%u237A%u2368%u237A%7D%20111&run).
[Answer]
## Haskell, 108 bytes
```
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
```
Defines the function `#` which first takes `a` and `b` and then the operator `o`. Fun fact: this works with any operator (actually, any function) you want!
[Answer]
## Pyke, 16 bytes
```
RE`DltImbRoKr)oh
```
[Try it here!](http://pyke.catbus.co.uk/?code=RE%60DltImbRoKr%29oh&input=B%0A21%2C+111&warnings=0)
```
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
```
Takes multiply as `B` and add as `s`. The two numerical inputs are separated by commas.
[Answer]
# JavaScript (ES6), 59
Recursive function, the input format is tailored to simplify the recursive call:
* operator : '+' or '\*'
* operands : array of two values
```
f=(o,v,s=1,t=eval(v.join(o)))=>t>9?f(o,[...t+''],s+1):[t,s]
```
**Test**
```
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)
})  
  
```
[Answer]
# Python 2, 60 bytes
```
f=lambda s,c=0:s[1:]and f(min(s).join(`eval(s)`),c+1)or(s,c)
```
Input is a string like `81+31`, output is a tuple of a singleton string and a counter (e.g., `('4', 2)`.
Test it on [Ideone](http://ideone.com/uC30St).
[Answer]
## Pyth, 16
```
eJ.uvjhQ`N.vQ)lJ
```
Takes input like `"+ 123 12"` for addition, and `"* 123 12"` for multiplication. Outputs like `result<linefeed>steps`.
[Try it here](http://pyth.herokuapp.com/?code=eJ.uvjhQ%60N.vQ%29lJ&input=%22%2B%20123%2012%22&debug=0), or run a [Test Suite](http://pyth.herokuapp.com/?code=eJ.uvjhQ%60N.vQ%29lJ&test_suite=1&test_suite_input=%22%2B%20123%2012%22%0A%22%2B%2081%2031%22%0A%22%2B%20351%2014568%22&debug=0), but note that this relies on eval, so only the addition variant will work in the online interpreter. Multiplication works correctly with the offline interpreter.
This uses the cumulative reduction function to create a list of intermediate results, so for `"+ 351 14568"` we get `[14919, 24, 6]`. This works because single digit numbers are a fixed point of the Anastasiya addition and multiplication. Then we just get the last element of the array as well as the length of the array.
This will work for arbitrarily large numbers, at least until you run out of memory.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~11~~ 10 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
Dj⁹VµÐĿḊĖṪ
```
Input is a pair of numbers and either `+` or `×`.
[Try it online!](http://jelly.tryitonline.net/#code=RGrigblWwrXDkMS_4biKxJbhuao&input=&args=MjEsIDExMQ+w5c) or [verify all test cases](http://jelly.tryitonline.net/#code=RGrigblWwrXDkMS_4biKxJbhuaoKw6ciRw&input=&args=WzgxLCAzMV0sIFszNTEsIDE0NTY4XSwgWzIxLCAxMTFdLCBbMTM2LCAyMzU2XQ+KyvDl8OX).
### How it works
```
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.
```
[Answer]
# ARM Machine Code, 48 bytes
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
```
This function doesn't depend any system calls or library functions. This is Thumb-2 code, which is a variable-length instruction encoding (2 or 4 bytes) for 32-bit ARM. Thus, the maximum value it can process is 2^32-1. 2 bytes could be dropped if it didn't conform to the AAPCS (**46 bytes**), since we wouldn't have to stack registers at the beginning.
Ungolfed assembly (GNU syntax):
```
.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
```
Testing script in 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));
}
```
[Answer]
# R, ~~175~~ ~~167~~ ~~164~~ ~~140~~ ~~134~~ ~~127~~ ~~126~~ 119 bytes
```
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
```
~~`ifelse` is back ! *Yeah !*~~  
*Nop*
**Usage :**
```
Special addition
> f(31,"+",81)
[1] 4 2
Special multiplication
> f(136,"*",2356)
[1] 0 2
```
Thanks a lot to **@plannapus** for golfing out *24* bytes !  
*-7* bytes thanks to a good idea from **@Vlo** !
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/), ~~20~~ 15 bytes
```
[¼¹iOëP}Dg#S]¾‚
```
**Explanation**
```
[       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 is 1 for addition, 0 for multiplication.
[Try it online](http://05ab1e.tryitonline.net/#code=W8K8wrlpT8OrUH1EZyNTXcK-4oCa&input=MQpbMTIsMTIzXQ)
[Answer]
# [Jelly](http://github.com/DennisMitchell/jelly), 17 bytes
```
+×⁵?µDSP⁵?$ÐĿµL;Ṫ
```
[Try it online!](http://jelly.tryitonline.net/#code=K8OX4oG1P8K1RFNQ4oG1PyTDkMS_wrVMO-G5qg&input=MA&args=ODE+MzE+MQ)
Given arguments like `x y 1`, this computes the Anastasiya sum `x (+) y`.
Given arguments like `x y 0`, this computes the Anastasiya product `x (*) y`.
Output is given as `[number of steps, result]`.
[Answer]
# R, ~~130~~ 124 chars
A somewhat different approach from [@Frédéric](https://codegolf.stackexchange.com/a/90925/6741)'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)}
```
Indented, with newlines:
```
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
    }
```
Line 4 probably needs more explanations:
```
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 cases:
```
> f(12,"(+)",123)
[1] 9 2
> f(12,"(*)",123)
[1] 6 5
> f(351,"(+)",14568)
[1] 6 3
```
[Answer]
# Octave, 85 bytes ~~MATLAB, 123, 114, 105, 94 bytes~~
Decided to translate this to Octace, to take advantage of the direct indexing, and incrementing capabilitites. Takes the input on the form: `f(a,operator)`, where `a = [number1, number2]`, and `operator==1` gives the product, and `operator==2` gives the sum.
```
function[x,i]=f(a,o)
g={@prod,@sum}{o};x=g(a);i=1;while(x=g(num2str(x)-48))>9;i++;end
```
Explanations:
`g={@prod,@sum}{o}` : Chooses the appropriate function, product or sum and assigns it to `g`
`x=g(a)` takes the sum or product of the inputs
`i=1; ... i++` : Incrementer to count the number of steps
```
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
```
Removed two newlines, a space, and placed both input numbers in a vector instead of separate arguments. This saved 9 bytes, thanks to pajonk!
Removed `k=@(x)...` to save another 11 bytes thanks to beaker =) Finally, translated the whole thing to Octave to save another 9 bytes...
[Answer]
# Java, ~~164~~ ~~159~~ 146 bytes
```
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};}
```
First argument is just the counter, always 0
Second argument is method, 0 for ADD and 1 for MULTIPLY.
Third argument is an array of Strings, which contains the values to add/multiply.
# 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};
}
```
thanks to @Kevin Cruijssen for cutting a few bytes.
thanks to @milk for shaving 5 bytes.
# 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};
}
```
[Answer]
# Python, ~~160~~ ~~146~~ 129 bytes
```
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
```
Will post an explanation soon.
Input is in the form `12+12` or `5*35` (with normal `+` and `*` signs), and assumes that those are the only two operators.
It can handle number inputs as large as your computer's memory allows.
I'm almost certainly confident that this can be further.
**EDIT:** *~~16~~ 31 bytes saved thanks to @Copper.*
[Answer]
# R, 110 bytes
Using @plannapus' splitter.
`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
```
Output
```
> 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
```
edit: I can't count.
[Answer]
# Clojure 126 bytes
```
(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)))))
```
Function is called like so:
```
(f + 81 31)
```
Here is the code ungolfed:
```
(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])
```
Bear in mind that Clojure is still new to me, so this is likely not the best solution. The challenge was fun all the same. Additionally, the code ran with very large numbers without any difficulty.
[Answer]
# [Perl 6](http://perl6.org) 53 bytes
```
{$/=(&^b($^a,$^c),{[[&b]] .comb}...10>*);$/[*-1],+$/}
```
Since `( 12, &[+], 123 )` is acceptable for the input, I can get it down to 53 bytes.  
( `&[+]` is short for `&infix:<+>` which is a "reverence" to the numeric infix addition operator )
If the second argument had to be a string `(+)` it would be 87 bytes
```
{my&b=::("&infix:<$^b.substr(1,1)>");$/=(b($^a,$^c),{[[&b]] .comb}...10>*);$/[*-1],+$/}
```
## Explanation:
```
# 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
  +$/
}
```
## Test:
```
#! /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 Usage:
```
# 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)
```
[Answer]
# Python 2, ~~107~~ 97 bytes
```
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)
```
An anonymous function that takes input via argument of a first operand `a`, an operator `o` (`'+'` or `'*'`) and a second operand `b`, and returns a list of the form `[result, steps]`.
**How it works**
The anonymous function creates a string by concatenating the operands with the operator between them, and then evaluates it; this is the first step described in the question. Then, this value and the operator are passed to the recursive function `g`. Here, a counter `i`, which is incremented for every recursive call, is used. If the input is less than `10`, a single digit must have been reached, so this and `i` are returned. If not, the input is converted to a string and each character in this string is joined with the operator, giving the desired calculation, which is then evaluated and passed to the function recursively.
[Try it on Ideone](http://ideone.com/rmjobD)
[Answer]
# Groovy, 102 bytes
```
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]
}
```
### Explanation
Based on @Sean Bean 's excellent solution for Java.
* `p`: The closure (function, lambda, whatever) that implements the solution
* `t`: The current call depth (number of iterations), `p` should always be invoked with `t=1`
* `m`: The operation to perform, `0` for "add", `1` for "multiply"
* `d`: The list of operands, each operand is a String object
* `e`: The elements of `d`, each converted to an Integer
* `r`: The sum or product of `e`, depending on the operation `m`
* result statement, starting with `r > 9`:
	+ If multi-digit (`r > 9`), reinvoke, incrementing depth `t` and converting `r` to a list of digit strings (and return result).
	+ If single-digit, return `r` and `t` as a list.
### 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
```
### Results
```
[9, 2]
[6, 5]
[5, 1]
```
[Answer]
## Haskell, ~~76~~ 70 bytes
```
 (x#y)f=until(<[10])(\[s,i]->[foldr(f.read.pure)0$show s,i+1])[f x y,1]
```
Returns a two element list with the result and number of steps. Works for arbitrary large numbers. Usage example: `(351#14568)(+)` -> `[6,3]`.
Edit: Thanks to @BlackCap for 6 bytes.
[Answer]
# R, 91 bytes
Using @Vlo's code, which makes use of @plannapus's splitter, and some ideas I generated while golfing @Frédéric's answer, this is the shortest R answer yet. (An unusually large number of R answers here today...)
```
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)}
```
Crucially, this requires that the input for the operator be either `sum` for (+) or `prod` for (\*). Under the rules of the challenge, this seems to be okay.
With indentation:
```
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)
}
```
Main differences from @Vlo's answer are:
1. Instead of using `Reduce`, we rely on the input argument being a function, and just call it explicitly. (Yay for functions being first-class objects!)
2. Instead of initializing a new variable as our counter, we abuse R's builtins and use `T`, which evaluates to `TRUE` (aka `1`), but since it's not a reserved variable we can modify it. Thus `T+T` is `2`. So we use that as our counter.
3. Instead of `cat`ing the output, we just return it as a vector with `c`. As well as saving two bytes, the fact that the output is forced into a vector ensures that `T` is of class `numeric`. If we use `cat`, and `T` hasn't been incremented, then we get erroneous output like `1 TRUE`.
[Answer]
# Ruby, 55 bytes
Recursive call. Used to be very different from @edc65's JavaScript answer but as I optimized it eventually became a direct port developed almost independently from their answer, minus one final optimization involving checking the eval'ed result instead of the length of the list of operands being passed in, which allowed me to surpass their byte count.
Input is a string representing the operator, and an array containing the operands.
[Try it online.](https://repl.it/CrXP/2)
```
f=->o,x,i=1{y=eval x*o;y>9?f[o,y.to_s.chars,i+1]:[y,i]}
```
[Answer]
# Perl, 38 bytes
Includes +2 for `-ap`
Run with the input on STDIN and spaces around the operator:
```
amath.pl <<< "12 + 123"
amath.pl <<< "12 * 123"
```
The output is digit and steps separated by `+A`
`amath.pl`:
```
#!/usr/bin/perl -ap
1while++$\,$_=eval."+A",s/\B/$F[1]/g
```
If outputting the steps in unary is ok this 35 byte version works better:
```
#!/usr/bin/perl -lap
1while$\.=1,$_=eval,s/\B/$F[1]/g
```
[Answer]
## Mathematica, ~~105~~ 94 bytes
*Code.*
```
{x,y}=(c=0;f//.a_:>(c++;t=o@@IntegerDigits@a);{t,c})&/.{{f->#1+#2,o->Plus},{f->#1#2,o->Times}}
```
*Usage.*
```
x[81, 31]
(* {4, 2} *)
x[351, 14568]
(* {6, 3} *)
y[21, 111]
(* {8, 3} *)
y[136, 2356]
(* {0, 2} *)
```
*Explanation.*
The two functions `x` (for (+)) and `y` (for (\*)) are created at the same time by replacing the parameters `f` and `o` in
```
(c = 0;
 f //. a_ :> (c++; t = o@@ IntegerDigits@a);
 {t, c}
)&
```
with their appropriate values. For `x`, `f` becomes `#1 + #2` and `o` becomes `Plus`; for `y`, they respectively become `#1 #2` and `Times`. Rewriting the function `x` for the last part of the explanation:
```
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}. *)
```
[Answer]
# Java 7, ~~203~~ ~~195~~ 192 bytes
```
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);}
```
It uses `long` (maximum value of 263-1). If it would use `int` instead (maximum value of 231-1) it would only be 1 byte less (**191 bytes**):
```
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);}
```
It can most likely be golfed a bit more. Having to print the steps as well as the answer for both operators takes some bytes, though..  
Uses 0 (for `(+)`) and 1 (for `(*)`).
**Ungolfed & test code:**
[Try it here.](https://ideone.com/bw0D5Y)
```
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));
  }
}
```
**Output:**
```
4,2
6,3
8,3
0,2
```
]