R J Cano on Thu, 11 May 2017 07:29:16 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Proposing "isperm()" (user featured routine) |
Greetings. Briefly, Motivation, source code, explanation/documentation, and examples in the attachment. Cheers, Remy
/* (PARI) _R. J. Cano_, May 11 2017 isperm(n,{strict=0},{allowRep=1},{stopAt=+oo},{resumeFrom=0}); Description/Purpose: Find (if exists) the least base "beta" where n is written as a permutation for some of its digits (with/without allowing digits repetition). Note: An "strict" search (usually also quite slower) means to search only those permutations of 0..k-1 with some k>1; where for some m<=k, all the first m digits enter (a leading zero, inclusive). */ isperm(n,{strict=1},{allowRep=0},{stopAt=+oo},{resumeFrom=0})={ my(theDigits:vec,tryThese:vecsmall,piano,touch,pass:small,pattern:vecsmall,leadingzero:small); forstep(Beta=max(2,resumeFrom),max(2,n-1),1, piano*=0*(pass=1); theDigits=digits(n,Beta); tryThese=Vecsmall(theDigits); for(i=1,#tryThese, touch=1<<tryThese[i]; if(bitand(touch,piano),if(!allowRep,pass=0;break),piano+=touch) ); if(pass, leadingzero=!(piano%2); pattern=Vecsmall(vecsort(concat([0],theDigits),,8)); if(#pattern==leadingzero+hammingweight(piano),if((strict&&(#pattern==sum(u=1,#pattern,pattern[u]==u-1)))||!strict,return(Beta))) ); if(Beta>stopAt,return(-1)) ); /* Nothing found, incomplete search */ return(0) } /* Nothing found, complete search */ \\ Example: 1) Strict search \\ isperm(27,1) returns 4 since 27 = 123[4] (with/without a leading zero) \\ isperm(123,1) returns 10 since 123 = 123[10] (Also with/without a leading zero) \\ In both cases above, respectively 4, and 10 are the least bases where it is possible \\ to represent n as a permutation, entering all the digits although leading zeros are not written. \\ 2) Non strict search: x = 314159265358979323; \\ Some few digits borrowed from Pi. y = isperm(x,0); \\ returns 34 for this example. R=digits(x,y); z=Set(concat([0],R)); t=concat(if(#R<#z,[0],[]),vector(#R,i,-1+vecsearch(z,R[i]))); \\ Appends a leading zero to complete all the digits, if required. human=concat(vector(#t,j,Strchr(if(0<=t[j]&&t[j]<=9,48,55)+t[j]))); \\ Returns "026435A891BC7" for this example. \\ As long as we keep stored the map (for this example, in z), we can recover x from "human". Dictionary(x:str)={my(data=Vec("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"));for(k=1,#data,if(x==data[k],return(k)));return(0)}; \\ By 0 here we mean: Not found. fromHuman=fromdigits(apply(q->z[q],apply(Dictionary,Vec(human))),y); \\ (The End?) /* Sample execution. Output dump: bash-4.3$ clear; cd ~/gp; gp2c -g isperm.txt > isperm.txt.c; gp2c-run ./isperm.txt.c Warning:isperm.txt:11: Assignement to a less precise type: vec<-gen theDigits=digits(n,Beta) Reading GPRC: /etc/gprc ...Done. GP/PARI CALCULATOR Version 2.9.2 (released) amd64 running linux (x86-64/GMP-6.1.1 kernel) 64-bit version compiled: May 6 2017, gcc version 5.3.0 (GCC) threading engine: single (readline v6.3 enabled, extended help enabled) Copyright (C) 2000-2017 The PARI Group PARI/GP is free software, covered by the GNU General Public License, and comes WITHOUT ANY WARRANTY WHATSOEVER. Type ? for help, \q to quit. Type ?15 for how to get moral (and possibly technical) support. parisizemax = 4096000000, primelimit = 10000000 (May 11 2017, 00:31 VET) gp > isperm(1231132) \\ Strict search. time = 1min, 55,095 ms. %1 = 1231130 (May 11 2017, 00:33 VET) gp > digits(1231132,1231130) \\ Don't forget the leading zero. Must actually be read "012" %2 = [1, 2] (May 11 2017, 00:33 VET) gp > */