Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Let's say I have a list, for instance {10,5,3}, indicating the bases for each digit of my 3-digit number. Using this basis, if I wanted to increment {8,4,1} a couple of times, here's what I would get:

{8,3,1} -> {9,3,1} -> {0,4,1} -> ... -> {9,4,1} -> {0,0,2} -> and so on

Now I can go ahead and do this using loops like one would normally do. But I'm sure there's a more elegant way of implementing this using some of Mathematica's already existing functions. Can anybody think of a sleek way to do this?

Thanks in advance,

share|improve this question
    
What happens when you increment {9,4,2}? What base is the fourth digit in? –  Rahul Nov 11 '12 at 9:11
4  
P.S. I like this question. It's like incrementing a time in ss:mm:hh-DD/MM/YYYY format. –  Rahul Nov 11 '12 at 9:14
2  
To aid in searches, I'd like to note that a number with different bases for each digit is commonly known as a mixed radix number. –  wxffles Nov 11 '12 at 20:41
    
@wxffles, thank you very much! I was just looking for that term (one of those you know it once you know things...) –  Dan McGrath May 2 '13 at 2:32

5 Answers 5

You have several options, either directly implementing incr

incr[digs_, base_] := Module[{carry = 1, ndigs = digs, k = 1, nd},
  While[k <= Length[digs],
   {carry, nd} = 
    QuotientRemainder[Part[ndigs, k] + carry, Part[base, k]];
   Part[ndigs, k] = nd;
   If[carry == 0, Break[]]; k++;
   ];
  ndigs
  ]

Or implementing FromMultpleBase and ToMultipleBase functions to make your tuple to a natural number, and back:

FromMultipleBase[digs_, base_] := digs.FoldList[Times, 1, Most[base]]

ToMultipleBase[num_, base_] := 
 Part[Rest[
   FoldList[QuotientRemainder[Last[#1], #2] &, {0, num}, 
    Reverse[FoldList[Times, 1, Most[base]]]]], 
  Range[Length[base], 1, -1], 1]

Here is the usage:

In[152]:= NestList[inc[#, {10, 5, 3}] &, {8, 3, 1}, 12]

Out[152]= {{8, 3, 1}, {9, 3, 1}, {0, 4, 1}, {1, 4, 1}, {2, 4, 1}, {3, 
  4, 1}, {4, 4, 1}, {5, 4, 1}, {6, 4, 1}, {7, 4, 1}, {8, 4, 1}, {9, 4,
   1}, {0, 0, 2}}

In[153]:= FromMultipleBase[#, {10, 5, 3}] & /@ %

Out[153]= {88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100}

In[154]:= NestList[
 ToMultipleBase[
   FromMultipleBase[#, {10, 5, 3}] + 1, {10, 5, 3}] &, {8, 3, 1}, 12]

Out[154]= {{8, 3, 1}, {9, 3, 1}, {0, 4, 1}, {1, 4, 1}, {2, 4, 1}, {3, 
  4, 1}, {4, 4, 1}, {5, 4, 1}, {6, 4, 1}, {7, 4, 1}, {8, 4, 1}, {9, 4,
   1}, {0, 0, 2}}
share|improve this answer

Let's see some beautiful answers pop up. For now, a not too sleek one to break the ice

fix[l_, base_] := 
 Module[{take = 0}, 
  Rest@FoldList[
    QuotientRemainder[#2[[1]] + take, #2[[2]]] /. {q_, 
        r_} :> (take = q; r) &, 0, Transpose@{l, base}]]

inc[{f_, rest___}, base_] := fix[{f + 1, rest}, base]

So

NestList[inc[#, {10, 5, 3}] &, {8, 3, 1}, 5]

(* {{8, 3, 1}, {9, 3, 1}, {0, 4, 1}, {1, 4, 1}, {2, 4, 1}, {3, 4, 1}} *)
share|improve this answer

Based on Rojo's answer:

add[base_][l_, x_] := 
 FoldList[QuotientRemainder @@ ({1, 0} # + #2) &, x, {l, base}\[Transpose]][[2 ;;, 2]]

NestList[add[{10, 5, 3}][#, 1] &, {8, 3, 1}, 15]

{{8, 3, 1}, {9, 3, 1}, {0, 4, 1}, {1, 4, 1}, {2, 4, 1}, {3, 4, 1}, {4, 4, 1}, {5, 4, 1}, {6, 4, 1}}

Alternate formulation:

base /: base[l_, blst_] + x_Integer := 
 FoldList[QuotientRemainder @@ ({1, 0} # + #2) &, x, {l, blst}\[Transpose]][[2 ;;, 2]]

base[{8, 3, 1}, {10, 5, 3}] + Range[8]

{{9, 3, 1}, {0, 4, 1}, {1, 4, 1}, {2, 4, 1}, {3, 4, 1}, {4, 4, 1}, {5, 4, 1}, {6, 4, 1}}

share|improve this answer
    
Nice touches +1 –  Rojo Nov 11 '12 at 20:20

@cartonn's clock:

 Dynamic[Thread[Mod[{Clock[{8, 17, 1}, 5], Clock[{3, 7, 1}, 25],
       Clock[{1, 3, 1}, 75]}, {10, 5, 3}]]]

:)

share|improve this answer
    
At first I thought synchronization might be a problem for three independent instances of Clock but looking at 'More Information' it seems this should be all right (The base for all times used by Clock is the creation time of the cell in which Clock appears.) –  Sjoerd C. de Vries Nov 11 '12 at 15:12
    
@Sjoerd, I thought I could concoct something with DatePlus but this, although it does not quite work yet (it needs finer tuning to avoid some skips), was hard to resist. Still DatePlus seems more promising. –  kguler Nov 11 '12 at 15:44
    
Interesting. Didn't think DatePlus could be (ab)used for that. Can you give it units other than "Day" etc. to work with? –  Sjoerd C. de Vries Nov 11 '12 at 15:51
    
I think you can only use combinations of built-in date/time units, but day,hour,minute values can be non-integers. –  kguler Nov 11 '12 at 16:19

I may be missing the point here, but I think in this case functional programming may drag efficiency down...

incr[list_, {a_, b_, c_}, n_ : 1] :=
   With[ {check = {Mod[#[[1]], a] , Mod[#[[2]], b] + Quotient[ #[[1]],a], Mod[#[[3]], c] 
         + Quotient[#[[2]],b]} &},
         NestList[check[{#[[1]] + 1, #[[2]], #[[3]]}] &, list, n]]

Quotient added on J.M.'s suggestion.

share|improve this answer
    
The Floor[p/q] bits in your code can of course be done as Quotient[p, q]. –  J. M. Nov 11 '12 at 10:07
    
@J.M. I should have seen that, thanks. –  VF1 Nov 11 '12 at 18:10

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.