5 * This solutions simulates the game until the whole map state loops.
6 * then it figures out repeating part.
8 * @author Roman Elizarov
10 public class garbling_re_slow
{
11 private static final boolean FULL_SIMULATION
= false; // VERY SLOW MODE
13 static class Field
implements Cloneable
{
19 for (int i
= 0; i
< r
; i
++) {
20 for (int j
= 0; j
< c
; j
++) {
26 void garbleLeft(int i
, int j
) {
28 a
[i
][j
] = a
[i
][j
+ 1];
29 a
[i
][j
+ 1] = a
[i
+ 1][j
+ 1];
30 a
[i
+ 1][j
+ 1] = a
[i
+ 1][j
];
34 void garbleRight(int i
, int j
) {
36 a
[i
][j
] = a
[i
+ 1][j
];
37 a
[i
+ 1][j
] = a
[i
+ 1][j
+ 1];
38 a
[i
+ 1][j
+ 1] = a
[i
][j
+ 1];
43 public Field
clone() {
45 Field f
= (Field
)super.clone();
47 for (int i
= 0; i
< f
.a
.length
; i
++) {
48 f
.a
[i
] = f
.a
[i
].clone();
51 } catch (CloneNotSupportedException e
) {
52 throw new AssertionError(e
);
57 public boolean equals(Object obj
) {
58 if (!(obj
instanceof Field
))
60 int[][] b
= ((Field
)obj
).a
;
61 for (int i
= 0; i
< a
.length
; i
++) {
62 if (!Arrays
.equals(a
[i
], b
[i
]))
69 public int hashCode() {
72 result
= result
* 997 + Arrays
.hashCode(row
);
78 static class State
implements Cloneable
{
83 written
= new long[rc
];
87 public State
clone() {
89 State s
= (State
)super.clone();
90 s
.written
= s
.written
.clone();
92 } catch (CloneNotSupportedException e
) {
93 throw new AssertionError(e
);
103 public static void main(String
[] args
) throws FileNotFoundException
{
104 new garbling_re_slow().go();
107 void go() throws FileNotFoundException
{
114 private void read() throws FileNotFoundException
{
115 Scanner in
= new Scanner(new File("garbling.in"));
119 map
= new char[r
- 1][];
120 for (int i
= 0; i
< r
- 1; i
++) {
121 map
[i
] = in
.next().toCharArray();
126 private void write(State s
) throws FileNotFoundException
{
127 PrintWriter out
= new PrintWriter(new File("garbling.out"));
128 for (int i
= 0; i
< r
* c
; i
++) {
129 out
.println(s
.written
[i
]);
134 // private void stressTest() {
135 // Random rnd = new Random(1);
137 // r = rnd.nextInt(11) + 90;
138 // c = rnd.nextInt(11) + 90;
139 // map = new char[r - 1][c - 1];
140 // for (int i = 0; i < r - 1; i++) {
141 // for (int j = 0; j < c - 1; j++) {
142 // int t = rnd.nextInt(4);
143 // map[i][j] = t <= 1 ? 'N' : t == 2 ? 'L' : 'R';
152 Field f
= new Field(r
, c
);
153 State s
= new State(rc
);
154 Map
<Field
, State
> fields
= new HashMap
<Field
, State
>();
155 long time
= System
.currentTimeMillis();
156 while (FULL_SIMULATION
|| !fields
.keySet().contains(f
)) {
157 if (!FULL_SIMULATION
)
158 fields
.put(f
.clone(), s
.clone());
159 if (garbleFieldOnce(f
, s
))
162 System
.out
.printf("%d turns on %d x %d field in %d ms%n",
163 s
.turns
, r
, c
, System
.currentTimeMillis() - time
);
166 // whole field looped -- fastforward repeating part
167 State p
= fields
.get(f
);
168 long stretch
= s
.turns
- p
.turns
;
169 long times
= (n
- s
.turns
) / stretch
;
170 s
.turns
+= times
* stretch
;
171 for (int i
= 0; i
< rc
; i
++) {
172 s
.written
[i
] += times
* (s
.written
[i
] - p
.written
[i
]);
174 System
.out
.printf("Fast forward %d x %d turns%n", times
, stretch
);
175 // finish remaining steps
177 if (garbleFieldOnce(f
, s
))
183 private boolean garbleFieldOnce(Field f
, State s
) {
184 for (int i
= 0; i
< r
- 1; i
++) {
185 for (int j
= 0; j
< c
- 1; j
++) {
189 s
.written
[f
.a
[i
][j
] - 1]++;
191 case 'L': f
.garbleLeft(i
, j
); break;
192 case 'R': f
.garbleRight(i
, j
); break;
199 // private String showMap() {
200 // StringBuilder sb = new StringBuilder();
202 // for (char[] row : map) {
206 // return sb.toString();