[rec.puzzles] bugfix of perm

maart@cs.vu.nl (Maarten Litmaath) (08/30/90)

Thanks to Icarus Sparry <I.Sparry@gdt.bath.ac.uk> for pointing out the
erroneous calls to free().

: This is a shar archive.  Extract with sh, not csh.
: This archive ends with exit, so do not worry about trailing junk.
: --------------------------- cut here --------------------------
PATH=/bin:/usr/bin:/usr/ucb
echo Extracting 'perm.c'
sed 's/^X//' > 'perm.c' << '+ END-OF-FILE ''perm.c'
Xint	perm(n, nullperm, length, dest)
Xlong	n;
Xchar	*nullperm, *dest;
Xint	length;
X{
X	long	f;
X	int	d;
X	char	*orig, *p, *q, *r, *malloc();
X
X	if (!(orig = p = malloc(length)))
X		return -1;
X
X	strncpy(p, nullperm, length);
X
X	for (d = --length, f = 1; d > 0; d--)
X		f *= d;
X
X	while (length > 0) {
X		d = n / f;
X		*dest++ = p[d];
X		if (!d)
X			p++;
X		else
X			for (q = p + d, r = q + 1; *q++ = *r++; )
X				;
X		n -= f * d;
X		f /= length--;
X	}
X
X	*dest++ = *p;
X	*dest = '\0';
X
X	free(orig);
X
X	return 0;
X}
X
X
Xmain(argc, argv)
Xint	argc;
Xchar	**argv;
X{
X	char	buf[32];
X	long	atol();
X
X	if (argc > 2) {
X		perm(atol(argv[1]), argv[2], strlen(argv[2]), buf);
X		printf("%s\n", buf);
X	}
X}
+ END-OF-FILE perm.c
chmod 'u=rw,g=r,o=r' 'perm.c'
set `wc -c 'perm.c'`
count=$1
case $count in
661)	:;;
*)	echo 'Bad character count in ''perm.c' >&2
		echo 'Count should be 661' >&2
esac
echo Extracting 'perm_number.c'
sed 's/^X//' > 'perm_number.c' << '+ END-OF-FILE ''perm_number.c'
Xlong	perm_number(s, nullperm, n)
Xchar	*s, *nullperm;
Xint	n;
X{
X	long	number = 0;
X	char	*q, *r, *c_index, *orig, *t, *malloc(), *index();
X
X	if (!(orig = t = malloc(n)))
X		return -1;
X
X	strncpy(t, nullperm, n);
X
X	while (--n > 0) {
X		if (!(c_index = index(t, *s++))) {
X			number = -1;
X			break;
X		}
X		number += c_index - t;
X		number *= n;
X		if (c_index == t)
X			t++;
X		else
X			for (q = c_index, r = q + 1; *q++ = *r++; )
X				;
X	}
X
X	free(orig);
X
X	return number;
X}
X
X
Xmain(argc, argv)
Xint	argc;
Xchar	**argv;
X{
X	if (argc > 2)
X		printf("%ld\n",
X			perm_number(argv[1], argv[2], strlen(argv[2])));
X}
+ END-OF-FILE perm_number.c
chmod 'u=rw,g=r,o=r' 'perm_number.c'
set `wc -c 'perm_number.c'`
count=$1
case $count in
589)	:;;
*)	echo 'Bad character count in ''perm_number.c' >&2
		echo 'Count should be 589' >&2
esac
exit 0
--
     "What is a rabbit?  A particle that makes special tracks in the snow!"
                                (Paul M. Koloc)