Message-ID: <32B70C77.2D97@domosys.com>
Date: Tue, 17 Dec 1996 13:11:19 -0800
From: Adrian Dunn <adunn@domosys.com>
Reply-To: dunn@mad.scientist.com
X-Mailer: Mozilla 3.0Gold (Win95; I; 16bit)
MIME-Version: 1.0
Newsgroups: alt.sb.programmer,comp.ai.edu,comp.ai.games,comp.lang.pascal,comp.lang.pascal.misc,comp.msdos.programmer,comp.programming,comp.programming.contests,comp.programming.literate,comp.programming.threads,comp.sys.ibm.pc.programmer,k12.education.math
To: Hamlet <david01@netvision.net.il>
Subject: Re: Help needed
References: <01bbe900$418c34c0$LocalHost@msreg>
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
NNTP-Posting-Host: 205.236.100.226
Organization: TotalNet Inc.
Lines: 70
Path: cantaloupe.srv.cs.cmu.edu!rochester!hood.cc.rochester.edu!news.acsu.buffalo.edu!dsinc!spool.mu.edu!newspump.sol.net!mindspring!cpk-news-hub1.bbnplanet.com!news.bbnplanet.com!cam-news-hub1.bbnplanet.com!news.mathworks.com!uunet!in3.uu.net!198.161.84.3!scanner.worldgate.com!news.insinc.net!news.total.net!205.236.100.226
Xref: glinda.oz.cs.cmu.edu comp.ai.edu:3856 comp.ai.games:7424 comp.lang.pascal.misc:11092 comp.programming:37916 comp.programming.contests:2388 comp.programming.literate:3829 comp.programming.threads:3252

Hamlet wrote:

> I'm want to write a function that get a base (let's say 7-16), length of
> number (let's say 4-6) and another number call him "pos" (let's say
> 1-(base!/(base-length)!).
> 
> It return a number is the base u entered in the length u entered that none
> of it digits return twice. There are many numbers like this the "pos" is
> the specific number I search.
> 
> Find(base:10,length:4,pos:3) will return '1236'
> 1236 it is the third number that none of is digit is twice in base 10 and
> length 4 (The first is 1234)
> Find(base:16,length:5,pos:7) will return '1234B'
> Find(base:16,length:5,pos:17) will return '1235A'
> 
> The problem is I do not want to run over all the numbers (Think a much time
> it will take to find (base:16,length:6,pos:5765755) for example)
> 
> I need a function that will calculate the answer not run over all the
> numbers.
> 
No guarantees, but the following should probably work.  The answer is
returned digit by digit in Number_Out, which should be a character array
with at least MAX_LENGTH elements.  Note that the digit '0' is never
used... using it will make the program somewhat more complicated. 
Therefore the number after 1239 in base 10 is 1243.

CalculateBase (char Base, char Length, unsigned long Pos, char
*Number_Out)
{
	char i;
	char Digits[15] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
	unsigned long Temp_Ulong;

	while (Pos)
	{
		i = 0;
		Temp_Ulong = FactorialDiv (Base - 2, Base - Length - 1);
		if (Temp_Ulong > Pos)
		{
			/* Find 1st available digit */
			while (Digits[i] == 0)
				i++;
		}
		else
		{
			/* Find appropriate digit */
			while (Temp_Ulong < Pos)
			{
				Pos -= Temp_Ulong;
				i++;
				while (Digits[i] == 0)
					i++;
			}
		}
		*Number_Out++ = Digits[i];
		Digits[i] = 0;
		Base--;
		Length--;
	}
}

unsigned long FactorialDiv (char a, char b)
{
	unsigned char c = 1;
	while (b < a)
		c *= ++b;
	return c;
}
