/src/gov/nih/ncgc/util/GrayCode.java
Java | 184 lines | 123 code | 21 blank | 40 comment | 24 complexity | f99df966718495c4b7f9f4fc67b1fee2 MD5 | raw file
1// $Id: GrayCode.java 2707 2009-06-22 09:29:24Z nguyenda $
2
3package gov.nih.ncgc.util;
4
5import java.util.Observer;
6import java.util.Observable;
7
8// rip this off of wikipedia; knuth's vol. 4 algorithm M doesn't require
9// all these auxilary arrays.... don't have it with me right now.
10public class GrayCode extends Observable {
11
12 private int maxsize = 0, size = 0;
13 private int[] n, g, u, c;
14
15 public GrayCode (int N, int k) {
16 init (N, k);
17 }
18
19 public GrayCode (int[] N) {
20 init (N);
21 }
22
23 protected void init (int N, int k) {
24 n = new int[k+1];
25 g = new int[k+1];
26 u = new int[k+1];
27 c = new int[k]; // copy of g
28
29 for (int i = 0; i <= k; ++i) {
30 g[i] = 0;
31 u[i] = 1;
32 n[i] = N;
33 }
34 size = 0;
35 }
36
37 protected void init (int[] N) {
38 int k = N.length;
39 n = new int[k+1];
40 g = new int[k+1];
41 u = new int[k+1];
42 c = new int[k]; // copy of g
43
44 int min = Integer.MAX_VALUE;
45 for (int i = 0; i < k; ++i) {
46 g[i] = 0;
47 u[i] = 1;
48 n[i] = N[i];
49 if (N[i] < min) {
50 min = N[i];
51 }
52 }
53 g[k] = 0;
54 u[k] = 1;
55 n[k] = min;
56 size = 0;
57 }
58
59 public void generate () {
60 for(int i, j; g[c.length] == 0;) {
61 System.arraycopy(g, 0, c, 0, c.length);
62
63 setChanged ();
64 notifyObservers (c);
65
66 i = 0;
67 j = g[0] + u[0];
68 while (((j >= n[i]) || (j < 0)) && (i < c.length)) {
69 u[i] = -u[i];
70 ++i;
71 j = g[i] + u[i];
72 }
73 g[i] = j;
74
75 ++size;
76 if (countObservers() == 0
77 || (maxsize > 0 && size >= maxsize)) {
78 break;
79 }
80 }
81 }
82
83 public void setMaxSize (int maxsize) {
84 this.maxsize = maxsize;
85 }
86 public int getMaxSize () { return maxsize; }
87
88 public int size () { return size; }
89
90 public static GrayCode createBinaryGrayCode (int size) {
91 return new GrayCode (2, size);
92 }
93
94 public static class Enum {
95 public static void main (final String[] argv) throws Exception {
96 // all possible subsets = 2^k
97 GrayCode g = createBinaryGrayCode (argv.length);
98 g.addObserver(new Observer () {
99 public void update (Observable o, Object arg) {
100 int[] c = (int[])arg;
101 int j = 0;
102 for (int i = 0; i < c.length; ++i) {
103 if (c[i] != 0) {
104 if (j == 0) {
105 System.out.print("[");
106 }
107 else if (j > 0) {
108 System.out.print(",");
109 }
110 System.out.print(argv[i]);
111 ++j;
112 }
113 }
114 if (j > 0) {
115 System.out.println("]");
116 }
117 }
118 });
119 g.generate();
120 }
121 }
122
123 public static void main (String[] argv) throws Exception {
124 if (argv.length == 0) {
125 System.out.println("Usage: GrayCode [N k | n0 n1...]\n");
126 System.exit(1);
127 }
128
129 /*
130 if (argv.length >= 2) {
131 final int N = Integer.parseInt(argv[0]);
132 int k = Integer.parseInt(argv[1]);
133
134 System.out.println("Gray Code ("+N+","+k+")");
135 GrayCode g = new GrayCode (N, k);
136 Observer obs = new Observer () {
137 int index = 0;
138 public void update (Observable o, Object arg) {
139 int[] c = (int[])arg;
140 System.out.printf("%1$5d: ", ++index);
141 if (N == 2 && c.length < 64) {
142 long x = 0;
143 for (int i = 0; i < c.length; ++i) {
144 System.out.print(c[i]+ " ");
145 if (c[i] == 1) {
146 x |= 1 << (c.length-i-1);
147 }
148 }
149 System.out.print("=> "+x);
150 }
151 else {
152 System.out.print(c[0]);
153 for (int i = 1; i < c.length; ++i) {
154 System.out.print(" " + c[i]);
155 }
156 }
157 System.out.println();
158 }
159 };
160 g.addObserver(obs);
161 g.generate();
162 System.out.println("--");
163 }
164 */
165
166 int[] a = new int[argv.length];
167 for (int i = 0; i < a.length; ++i) {
168 a[i] = Integer.parseInt(argv[i]);
169 }
170 GrayCode g = new GrayCode (a);
171 g.addObserver(new Observer () {
172 public void update (Observable o, Object arg) {
173 int[] c = (int[])arg;
174 System.out.print(c[0]);
175 for (int i = 1; i < c.length; ++i) {
176 System.out.print(" " + c[i]);
177 }
178 System.out.println();
179 }
180 });
181 g.generate();
182 System.out.println("** "+g.size()+" values generated!");
183 }
184}