/* * $Header: /home/gene/library/website/docsrc/salt/RCS/salt.c,v 395.1 2008/04/20 17:25:50 gene Exp $ * * Copyright (C) 2004 Gene Michael Stover. * * This file is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * As a special exception to the GNU General Public License, if you * distribute this file as part of a program that contains a * configuration script generated by Autoconf, you may include it under * the same distribution terms that you use for the rest of that program. */ /* Catholic C */ #include #include #include #include #include /* unix */ #include extern int getopt (); extern char *optarg; extern int optidx; static int S_count = 100; static int S_quantity = 100; static int S_pinch = 10; static int S_Init () { int rc = 0; srand (time (NULL)); return rc; } static int S_CommandLine (argc, argv) int argc; char *argv[]; { int rc = 0; int c; while (rc == 0 && (c = getopt (argc, argv, "c:q:p:")) != -1) { switch (c) { case 'c': S_count = atoi (optarg); break; case 'p': S_pinch = atoi (optarg); break; case 'q': S_quantity = atoi (optarg); break; default: fprintf (stderr, "\n%s:%d: unexpected command line opt '%c'", __FILE__, __LINE__, c); rc = 42; } } return rc; } /* * Return the number of items of TYPE in the container. */ static int S_Count (container, type, len) char container[]; char type; int len; { int count = 0, i; for (i = 0; i < len; ++i) { if (container[i] == type) { ++count; } } return count; } /* * Fill the container with one kind of item */ static void S_FillContainer (container, type, len) char container[]; char type; int len; { memset (container, type, len); } static void S_SwapChar (x, y) char *x; char *y; { char tmp; tmp = *x; *x = *y; *y = tmp; } static void S_Shuffle (container, len) char container[]; int len; { int i, j; for (i = 0; i < len; ++i) { j = rand () % (len - i); j += i; S_SwapChar (&container[i], &container[j]); } fprintf (stderr, "\n%s:%d: shuffle debug: ", __FILE__, __LINE__); for (i = 0; i < len; ++i) { fprintf (stderr, "%c", container[i]); } } static void S_Trial (salt, pepper) char salt[]; char pepper[]; { /* Fill the pepper container with pepper. */ S_FillContainer (pepper, 'p', S_quantity); /* Append some salt to the pepper. */ S_FillContainer (&pepper[S_quantity], 's', S_pinch); /* Shake the pepper container */ S_Shuffle (pepper, S_quantity + S_pinch); /* Fill the salt -- but it lacks one pinch */ S_FillContainer (salt, 's', S_quantity - S_pinch); /* Append to the salt a pinch from the pepper container. */ bcopy (&pepper[S_quantity], &salt[S_quantity - S_pinch], S_pinch); } static double S_Rate (container, type, len) char container[]; char type; int len; { return S_Count (container, type, len) / (double) len; } static void S_Print (i, salt, pepper, len) int i; char salt[]; char pepper[]; int len; { printf ("\n(salt %d, %d, %.3f), (pepper %d, %d, %.3f)", S_Count (salt, 's', len), S_Count (salt, 'p', len), S_Rate (salt, 's', len), S_Count (pepper, 's', len), S_Count (pepper, 'p', len), S_Rate (pepper, 'p', len)); if (S_Rate (salt, 's') != S_Rate (pepper, 'p')) { printf (" *"); } } static char * S_NewContainer () { return (char *) malloc ((S_quantity + S_pinch) * sizeof *salt); } static int S_Run () { int rc = 0; int i; char *salt, *pepper; salt = S_NewContainer (); pepper = S_NewContainer (); for (i = 0; i < S_count; ++i) { S_Trial (salt, pepper); S_Print (i, salt, pepper, S_quantity); } free (pepper); free (salt); return rc; } int main (argc, argv) int argc; char *argv[]; { int rc = 0; if (S_Init () == 0) { if (S_CommandLine (argc, argv) == 0) { if (S_Run () == 0) { /* success */ } else { fprintf (stderr, "\n%s:%d: run failed", __FILE__, __LINE__); rc = 1010; } } else { fprintf (stderr, "\n%s:%d: command line error", __FILE__, __LINE__); rc = 3; } } else { fprintf (stderr, "\n%s:%d: init failed", __FILE__, __LINE__); rc = -234; } printf ("\n"); return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } /* --- end of file --- */