chiark / gitweb /
Monoalphabetic match filter.
[anag] / mono.c
CommitLineData
fe9969ff 1/* -*-c-*-
2 *
3 * $Id: mono.c,v 1.1 2003/09/15 02:48:54 mdw Exp $
4 *
5 * Monoalphabetic matcher
6 *
7 * (c) 2003 Mark Wooding
8 */
9
10/*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of Anag: a simple wordgame helper.
13 *
14 * Anag is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * Anag is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Anag; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29/*----- Revision history --------------------------------------------------*
30 *
31 * $Log: mono.c,v $
32 * Revision 1.1 2003/09/15 02:48:54 mdw
33 * Monoalphabetic match filter.
34 *
35 */
36
37/*----- Header files ------------------------------------------------------*/
38
39#include "anag.h"
40
41/*----- Data structures ---------------------------------------------------*/
42
43typedef struct node_mono {
44 node n;
45 unsigned len;
46 unsigned char *p;
47} node_mono;
48
49/*----- Main code ---------------------------------------------------------*/
50
51/* --- Matching --- */
52
53static int n_mono(node *nn, const char *p, size_t sz)
54{
55 node_mono *n = (node_mono *)nn;
56 unsigned map[UCHAR_MAX], imap[UCHAR_MAX];
57 const unsigned char *q = n->p;
58 int ch, i;
59
60 if (sz != n->len)
61 return (0);
62 memset(map, 0, sizeof(map));
63 memset(imap, 0, sizeof(imap));
64 while (*p) {
65 ch = *p++;
66 i = *q++;
67 if (!map[i]) {
68 if (imap[ch])
69 return (0);
70 map[i] = ch;
71 imap[ch] = 1;
72 } else if (map[i] != ch)
73 return (0);
74 }
75 return (1);
76}
77
78/* --- Node creation --- */
79
80node *mono(const char *const *av)
81{
82 unsigned char map[UCHAR_MAX];
83 unsigned max;
84 int ch;
85 const char *p;
86 unsigned char *q;
87
88 node_mono *n = xmalloc(sizeof(*n));
89 n->n.func = n_mono;
90 memset(map, UCHAR_MAX, sizeof(map));
91 max = 0;
92 p = av[0];
93 n->len = strlen(p);
94 q = xmalloc(n->len);
95 n->p = q;
96 while (*p) {
97 ch = *p++;
98 if (map[ch] >= max)
99 map[ch] = max++;
100 *q++ = map[ch];
101 }
102 return (&n->n);
103}
104
105/*----- That's all, folks -------------------------------------------------*/