Ruud H.G. van Tol on Wed, 29 Dec 2021 20:25:43 +0100


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: factor(x+1)




On 2021-12-29 14:55, Ruud H.G. van Tol wrote:
On 2021-12-29 14:38, Bill Allombert wrote:
On Wed, Dec 29, 2021 at 02:12:14PM +0100, Ruud H.G. van Tol wrote:

Example:
103
-> 2^3*13
-> 2^3*(2*7-1)
-> 2^3*(2*(2^3-1)-1)

It seems to me you should only keep the exponents and work backward:
Try this:

tofp1(x)=my(v=valuation(x,2));x>>=v;if(x==1,return([v]),concat(v,tofp1(x+1)))
fromfp1(v)=my(n=1);v=Vecrev(v);for(i=1,#v,n=2^v[i]*n-1);n+1

? tofp1(103)
%18 = [0,3,1,3]
? 2^0*(2^3*(2^1*(2^3-1)-1)-1)
%20 = 103
? fromfp1([0,3,1,3])
%21 = 103

Thanks, that really helps!

I forgot to mention
that I'd like to stop at some minimal factor,
being 3 in my example. (so no 3 -> 2^2-1 step)

A 2,3 specific variant:

- - - - -
tofp23(x0, m= 0)= {
  if( x0 < 1, return([]) );

  my
  ( x= x0 + m
  , v2= valuation(x, 2)
  , v3= valuation(x, 3)
  );
  x/= 2^v2;
  x/= 3^v3;

  if
  ( x == 1
  , if
    ( m
    , [v2,v3]
    , [[v2,v3]]
    );
  , [ [v2,v3]
    , tofp23(x,1)
    ];
  );
}

fromfp23(v)= {
  if( !#v, return(0) );

  my( n= 1 );
  v= Vecrev(v);

  for
  ( i= 1, #v-1
  , my
    ( w= v[i]
    , f= if
         ( type(w[1]) == "t_VEC"
         , fromfp23(w);
         , (2^w[1] * 3^w[2]);
         );
    );
    n*= f - 1;
  );
  ( n * (2^v[#v][1] * 3^v[#v][2]) );
}

for(i=1, 12, my(v=tofp23(i)); print(i,": ", v, " -> ", fromfp23(v)))

- - - - -

My next step could be to use a t_INT when there is a zero.

I have no specific use for this yet,
it is still mainly a personal code exercise.

-- Ruud