1 | /* |
2 | * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * |
8 | * -Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. |
10 | * |
11 | * -Redistribution in binary form must reproduct the above copyright |
12 | * notice, this list of conditions and the following disclaimer in |
13 | * the documentation and/or other materials provided with the distribution. |
14 | * |
15 | * Neither the name of Sun Microsystems, Inc. or the names of contributors |
16 | * may be used to endorse or promote products derived from this software |
17 | * without specific prior written permission. |
18 | * |
19 | * This software is provided "AS IS," without a warranty of any kind. ALL |
20 | * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING |
21 | * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE |
22 | * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT |
23 | * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT |
24 | * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS |
25 | * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST |
26 | * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, |
27 | * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY |
28 | * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN |
29 | * IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. |
30 | * |
31 | * You acknowledge that Software is not designed, licensed or intended for |
32 | * use in the design, construction, operation or maintenance of any nuclear |
33 | * facility. |
34 | */ |
35 | |
36 | /* |
37 | * @(#)Permuter.java 1.6 03/01/23 |
38 | */ |
39 | |
40 | |
41 | |
42 | import java.util.Random; |
43 | |
44 | /** |
45 | * An object that implements a cheesy pseudorandom permutation of the integers |
46 | * from zero to some user-specified value. (The permutation is a linear |
47 | * function.) |
48 | * |
49 | * @version 1.6 01/23/03 |
50 | * @author Josh Bloch |
51 | */ |
52 | class Permuter { |
53 | /** |
54 | * The size of the permutation. |
55 | */ |
56 | private int modulus; |
57 | |
58 | /** |
59 | * Nonnegative integer less than n that is relatively prime to m. |
60 | */ |
61 | private int multiplier; |
62 | |
63 | /** |
64 | * Pseudorandom nonnegative integer less than n. |
65 | */ |
66 | private int addend = 22; |
67 | |
68 | public Permuter(int n) { |
69 | if (n<0) { |
70 | throw new IllegalArgumentException(); |
71 | } |
72 | modulus = n; |
73 | if (n==1) { |
74 | return; |
75 | } |
76 | |
77 | // Initialize the multiplier and offset |
78 | multiplier = (int) Math.sqrt(n); |
79 | while (gcd(multiplier, n) != 1) { |
80 | if (++multiplier == n) { |
81 | multiplier = 1; |
82 | } |
83 | } |
84 | } |
85 | |
86 | /** |
87 | * Returns the integer to which this permuter maps the specified integer. |
88 | * The specified integer must be between 0 and n-1, and the returned |
89 | * integer will be as well. |
90 | */ |
91 | public int map(int i) { |
92 | return (multiplier * i + addend) % modulus; |
93 | } |
94 | |
95 | /** |
96 | * Calculate GCD of a and b, which are assumed to be non-negative. |
97 | */ |
98 | private static int gcd(int a, int b) { |
99 | while(b != 0) { |
100 | int tmp = a % b; |
101 | a = b; |
102 | b = tmp; |
103 | } |
104 | return a; |
105 | } |
106 | |
107 | /** |
108 | * Simple test. Takes modulus on command line and prints out permutation. |
109 | */ |
110 | public static void main(String[] args) { |
111 | int modulus = Integer.parseInt(args[0]); |
112 | Permuter p = new Permuter(modulus); |
113 | for (int i=0; i<modulus; i++) { |
114 | System.out.print(p.map(i)+" "); |
115 | } |
116 | System.out.println(); |
117 | } |
118 | } |
119 | |