@@ -9,16 +9,17 @@ extern crate quickcheck;
9
9
#[ cfg( test) ]
10
10
#[ macro_use( quickcheck) ]
11
11
extern crate quickcheck_macros;
12
+ use std:: isize:: { MAX , MIN } ;
12
13
13
14
struct Difference < ' a , X , Y > {
14
15
xv : & ' a [ X ] ,
15
16
yv : & ' a [ Y ] ,
16
17
17
18
// working memory for forward path
18
- vf : Vec < usize > ,
19
+ vf : Vec < isize > ,
19
20
// working memory for backward path
20
- vb : Vec < usize > ,
21
- offset_d : i64 ,
21
+ vb : Vec < isize > ,
22
+ offset_d : isize ,
22
23
}
23
24
24
25
impl < ' a , X , Y > Difference < ' a , X , Y >
27
28
{
28
29
fn new ( xv : & ' a [ X ] , yv : & ' a [ Y ] ) -> Self {
29
30
let dmax = xv. len ( ) + yv. len ( ) + 1 ;
30
- let offset_d = yv. len ( ) as i64 ;
31
- let vf = vec ! [ 0usize ; dmax] ;
32
- let vb = vec ! [ ! 0usize ; dmax] ;
31
+ let offset_d = yv. len ( ) as isize ;
32
+ let vf = vec ! [ MIN ; dmax] ;
33
+ let vb = vec ! [ MAX ; dmax] ;
33
34
Self {
34
35
xv,
35
36
yv,
@@ -45,15 +46,22 @@ where
45
46
( xl, xr) : ( usize , usize ) ,
46
47
( yl, yr) : ( usize , usize ) ,
47
48
) -> ( usize , ( usize , usize ) , ( usize , usize ) ) {
48
- let kmin = xl as i64 - yr as i64 ;
49
- let kmax = xr as i64 - yl as i64 ;
50
- let kmidf = xl as i64 - yl as i64 ; // center diag in this fragment for forwad snake
51
- let kmidb = xr as i64 - yr as i64 ;
52
- let delta = ( ( xr - xl) as i64 ) - ( ( yr - yl) as i64 ) ;
49
+ let xl = xl as isize ;
50
+ let xr = xr as isize ;
51
+ let yl = yl as isize ;
52
+ let yr = yr as isize ;
53
+
54
+ let kmin = xl - yr;
55
+ let kmax = xr - yl;
56
+ let kmidf = xl - yl; // center diag in this fragment for forwad snake
57
+ let kmidb = xr - yr;
58
+ let delta = ( xr - xl) - ( yr - yl) ;
53
59
let is_odd = ( delta & 1 ) == 1 ;
60
+
61
+ // convert k to index of working memory (vf, vb)
54
62
let ktoi = {
55
63
let offset = self . offset_d ;
56
- move |k : i64 | -> usize { ( k + offset) as usize }
64
+ move |k : isize | -> usize { ( k + offset) as usize }
57
65
} ;
58
66
59
67
self . vf [ ktoi ( kmidf) ] = xl;
@@ -64,25 +72,22 @@ where
64
72
let mut kminb = kmidb;
65
73
let mut kmaxb = kmidb;
66
74
67
- let gety = |x : usize , k : i64 | ( x as i64 - k) as usize ;
75
+ let gety = |x : isize , k : isize | x - k;
76
+
68
77
for d in 0i64 .. {
69
78
// forward
70
79
{
71
80
// update range
72
81
if d > 0 {
73
82
if kminf > kmin {
74
83
kminf -= 1 ;
75
- if let Some ( x) = self . vf . get_mut ( ktoi ( kminf - 1 ) ) {
76
- * x = 0
77
- }
84
+ self . vf . get_mut ( ktoi ( kminf - 1 ) ) . map ( |x| * x = MIN ) ;
78
85
} else {
79
86
kminf += 1 ;
80
87
}
81
88
if kmaxf < kmax {
82
89
kmaxf += 1 ;
83
- if let Some ( x) = self . vf . get_mut ( ktoi ( kmaxf + 1 ) ) {
84
- * x = 0 ;
85
- }
90
+ self . vf . get_mut ( ktoi ( kmaxf + 1 ) ) . map ( |x| * x = MIN ) ;
86
91
} else {
87
92
kmaxf -= 1
88
93
}
@@ -98,37 +103,45 @@ where
98
103
max ( lo. map ( |x| x + 1 ) , hi) . unwrap ( )
99
104
} ;
100
105
let y = gety ( x, k) ;
106
+ if !( xl <= x && x <= xr && yl <= y && y <= yr) {
107
+ continue ;
108
+ }
109
+
101
110
let mut u = x;
102
111
let mut v = y;
103
- while u < xr && v < yr && self . xv [ u] == self . yv [ v] {
112
+
113
+ while u < xr && v < yr && self . xv [ u as usize ] == self . yv [ v as usize ] {
104
114
u += 1 ;
105
115
v += 1 ;
106
116
}
117
+
118
+ debug_assert ! ( xl <= u && u <= xr) ;
119
+ debug_assert ! ( yl <= v && v <= yr) ;
120
+
107
121
self . vf [ ik] = u;
108
122
if is_odd && kminb <= k && k <= kmaxb && self . vb [ ik] <= u {
109
- return ( 2 * d as usize - 1 , ( x, y) , ( u, v) ) ;
123
+ return (
124
+ 2 * d as usize - 1 ,
125
+ ( x as usize , y as usize ) ,
126
+ ( u as usize , v as usize ) ,
127
+ ) ;
110
128
}
111
129
}
112
130
}
113
- println ! ( "vf {:?}" , self . vf) ;
114
131
115
132
// backward
116
133
{
117
134
if d > 0 {
118
135
// update range
119
136
if kminb > kmin {
120
137
kminb -= 1 ;
121
- if let Some ( x) = self . vb . get_mut ( ktoi ( kminb - 1 ) ) {
122
- * x = !0usize ;
123
- }
138
+ self . vb . get_mut ( ktoi ( kminb - 1 ) ) . map ( |x| * x = MAX ) ;
124
139
} else {
125
140
kminb += 1 ;
126
141
}
127
142
if kmaxb < kmax {
128
143
kmaxb += 1 ;
129
- if let Some ( x) = self . vb . get_mut ( ktoi ( kmaxb + 1 ) ) {
130
- * x = !0usize ;
131
- }
144
+ self . vb . get_mut ( ktoi ( kmaxb + 1 ) ) . map ( |x| * x = MAX ) ;
132
145
} else {
133
146
kmaxb -= 1
134
147
}
@@ -147,20 +160,32 @@ where
147
160
}
148
161
} ;
149
162
let y = gety ( x, k) ;
163
+ if !( xl <= x && x <= xr && yl <= y && y <= yr) {
164
+ continue ;
165
+ }
166
+
150
167
let mut u = x;
151
168
let mut v = y;
152
- while xl < u && yl < v && self . xv [ u - 1 ] == self . yv [ v - 1 ] {
169
+ while xl < u && yl < v && self . xv [ ( u - 1 ) as usize ] == self . yv [ ( v - 1 ) as usize ]
170
+ {
153
171
u -= 1 ;
154
172
v -= 1 ;
155
173
}
174
+
175
+ debug_assert ! ( xl <= u && u <= xr) ;
176
+ debug_assert ! ( yl <= v && v <= yr) ;
177
+
156
178
let ik = ktoi ( k) ;
157
179
self . vb [ ik] = u;
158
180
if !is_odd && kminf <= k && k <= kmaxf && self . vf [ ik] >= u {
159
- return ( 2 * d as usize , ( u, v) , ( x, y) ) ;
181
+ return (
182
+ 2 * d as usize ,
183
+ ( u as usize , v as usize ) ,
184
+ ( x as usize , y as usize ) ,
185
+ ) ;
160
186
}
161
187
}
162
188
}
163
- println ! ( "vb {:?}" , self . vb) ;
164
189
}
165
190
166
191
unreachable ! ( ) ;
@@ -172,18 +197,18 @@ fn find_mid() {
172
197
use std:: array:: IntoIter ;
173
198
let testcases = IntoIter :: new ( [
174
199
( vec ! [ 0 ] , vec ! [ 1 , 1 , 1 ] , ( 4 , ( 0 , 2 ) , ( 0 , 2 ) ) ) ,
175
- // (vec![0], vec![1, 1], (3, (0, 2), (0, 2))),
176
- // (vec![0], vec![0, 1, 0], (2, (1, 2 ), (1, 2 ))),
177
- // (vec![0], vec![0, 0, 0], (2, (0, 1), (1, 2 ))),
178
- // (vec![0], vec![], (1, (1, 0), (1, 0))),
179
- // (vec![], vec![0], (1, (0, 1), (0, 1))),
180
- // (vec![], vec![], (0, (0, 0), (0, 0))),
181
- // (vec![0, 1, 2], vec![0, 1, 1, 2], (1, (2, 3), (3, 4))),
182
- // (vec![0, 1, 1, 2], vec![0, 1, 2], (1, (3, 2), (4, 3))),
183
- // (vec![0, 1, 2, 3], vec![0, 1, 2], (1, (4, 3), (4, 3))),
184
- // (vec![0, 1, 2], vec![0, 2, 2], (2, (1, 2), (1, 2))),
185
- // (vec![0, 2, 2], vec![0, 1, 2], (2, (1, 2), (1, 2))),
186
- // (vec![0, 1, 2], vec![0, 1, 2], (0, (0, 0), (3, 3))),
200
+ ( vec ! [ 0 ] , vec ! [ 1 , 1 ] , ( 3 , ( 0 , 2 ) , ( 0 , 2 ) ) ) ,
201
+ ( vec ! [ 0 ] , vec ! [ 0 , 1 , 0 ] , ( 2 , ( 0 , 1 ) , ( 0 , 1 ) ) ) ,
202
+ ( vec ! [ 0 ] , vec ! [ 0 , 0 , 0 ] , ( 2 , ( 0 , 1 ) , ( 0 , 1 ) ) ) ,
203
+ ( vec ! [ 0 ] , vec ! [ ] , ( 1 , ( 1 , 0 ) , ( 1 , 0 ) ) ) ,
204
+ ( vec ! [ ] , vec ! [ 0 ] , ( 1 , ( 0 , 1 ) , ( 0 , 1 ) ) ) ,
205
+ ( vec ! [ ] , vec ! [ ] , ( 0 , ( 0 , 0 ) , ( 0 , 0 ) ) ) ,
206
+ ( vec ! [ 0 , 1 , 2 ] , vec ! [ 0 , 1 , 1 , 2 ] , ( 1 , ( 2 , 3 ) , ( 3 , 4 ) ) ) ,
207
+ ( vec ! [ 0 , 1 , 1 , 2 ] , vec ! [ 0 , 1 , 2 ] , ( 1 , ( 3 , 2 ) , ( 4 , 3 ) ) ) ,
208
+ ( vec ! [ 0 , 1 , 2 , 3 ] , vec ! [ 0 , 1 , 2 ] , ( 1 , ( 4 , 3 ) , ( 4 , 3 ) ) ) ,
209
+ ( vec ! [ 0 , 1 , 2 ] , vec ! [ 0 , 2 , 2 ] , ( 2 , ( 1 , 2 ) , ( 1 , 2 ) ) ) ,
210
+ ( vec ! [ 0 , 2 , 2 ] , vec ! [ 0 , 1 , 2 ] , ( 2 , ( 1 , 2 ) , ( 1 , 2 ) ) ) ,
211
+ ( vec ! [ 0 , 1 , 2 ] , vec ! [ 0 , 1 , 2 ] , ( 0 , ( 0 , 0 ) , ( 3 , 3 ) ) ) ,
187
212
] ) ;
188
213
for ( xv, yv, expected) in testcases {
189
214
let n = xv. len ( ) ;
0 commit comments