From 3680bb180de889b8d209fdc898f4c1b2c17d5afa Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 13:59:59 -0500 Subject: [PATCH 01/23] update one functino --- examples/strings/suf_ary_find_str_aizu.rs | 15 +++++++++++---- src/strings/suf_ary.rs | 19 ++++++++----------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/examples/strings/suf_ary_find_str_aizu.rs b/examples/strings/suf_ary_find_str_aizu.rs index 9cc8846c..cb2a1736 100644 --- a/examples/strings/suf_ary_find_str_aizu.rs +++ b/examples/strings/suf_ary_find_str_aizu.rs @@ -9,11 +9,18 @@ fn main() { t: String } - let s_vec = s.chars().map(|x| x as usize).collect::>(); - let t_vec = t.chars().map(|x| x as usize).collect::>(); + let s = s.chars().map(|x| x as usize).collect::>(); + let t = t.chars().map(|x| x as usize).collect::>(); - let suf_ary = SufAry::new(&s_vec, 255); - let range = suf_ary.find_str(&t_vec); + let suf_ary = SufAry::new(&s, 255); + + let mut range = 0..s.len(); + for (i, &c) in t.iter().enumerate() { + range = suf_ary.push_char(c, range, i); + if range.is_empty() { + break; + } + } let mut res: Vec = Vec::new(); res.extend_from_slice(&suf_ary.sa[range]); res.sort(); diff --git a/src/strings/suf_ary.rs b/src/strings/suf_ary.rs index af6a217b..4f714537 100644 --- a/src/strings/suf_ary.rs +++ b/src/strings/suf_ary.rs @@ -135,17 +135,14 @@ impl SufAry { } } - /// Gets range r such that: - /// - for all i in sa\[r\] s\[i..i + t.len()\] == t - /// - r.len() is the number of matches of t in s - /// - /// # Complexity - /// - Time: O(|t| * log(|s|)) - /// - Space: O(1) - pub fn find_str(&self, t: &[usize]) -> Range { - let le = self.sa.partition_point(|&i| &self.s[i..] < t); - let ri = - self.sa[le..].partition_point(|&i| &self.s[i..(i + t.len()).min(self.n)] == t) + le; + pub fn push_char(&self, c: usize, sa_range: Range, lcp_len: usize) -> Range { + if !sa_range.is_empty() { + assert!(lcp_len <= self.len_lcp(self.sa[sa_range.start], self.sa[sa_range.end - 1])); + } + let le = self.sa[sa_range.clone()] + .partition_point(|&i| i + lcp_len == self.n || self.s[i + lcp_len] < c) + + sa_range.start; + let ri = self.sa[le..sa_range.end].partition_point(|&i| self.s[i + lcp_len] == c) + le; le..ri } From 8a5d9042366fdaf30276c2807d13d5a5e59a16d8 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 14:17:17 -0500 Subject: [PATCH 02/23] rename --- examples/strings/suf_ary_find_str_aizu.rs | 2 +- src/strings/suf_ary.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/strings/suf_ary_find_str_aizu.rs b/examples/strings/suf_ary_find_str_aizu.rs index cb2a1736..dff4dda6 100644 --- a/examples/strings/suf_ary_find_str_aizu.rs +++ b/examples/strings/suf_ary_find_str_aizu.rs @@ -16,7 +16,7 @@ fn main() { let mut range = 0..s.len(); for (i, &c) in t.iter().enumerate() { - range = suf_ary.push_char(c, range, i); + range = suf_ary.push_back_char(c, range, i); if range.is_empty() { break; } diff --git a/src/strings/suf_ary.rs b/src/strings/suf_ary.rs index 4f714537..dc47e254 100644 --- a/src/strings/suf_ary.rs +++ b/src/strings/suf_ary.rs @@ -135,7 +135,7 @@ impl SufAry { } } - pub fn push_char(&self, c: usize, sa_range: Range, lcp_len: usize) -> Range { + pub fn push_back_char(&self, c: usize, sa_range: Range, lcp_len: usize) -> Range { if !sa_range.is_empty() { assert!(lcp_len <= self.len_lcp(self.sa[sa_range.start], self.sa[sa_range.end - 1])); } From 705bcfe6fbfc87f7fb4951ccc95419f59d29f818 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 15:05:49 -0500 Subject: [PATCH 03/23] saving progress --- src/strings/suf_ary.rs | 60 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/src/strings/suf_ary.rs b/src/strings/suf_ary.rs index dc47e254..9cf3cad5 100644 --- a/src/strings/suf_ary.rs +++ b/src/strings/suf_ary.rs @@ -69,6 +69,7 @@ pub struct SufAry { /// longest common prefix array pub lcp: Vec, rmq: RMQ usize>, + cnt: Vec, } impl SufAry { @@ -87,6 +88,13 @@ impl SufAry { for (i, &elem) in sa.iter().enumerate() { sa_inv[elem] = i; } + let mut cnt = vec![0; max_val + 1]; + for &c in s { + cnt[c + 1] += 1; + } + for i in 1..cnt.len() { + cnt[i] += cnt[i - 1]; + } Self { n: sa.len(), s: s.to_vec(), @@ -94,6 +102,7 @@ impl SufAry { rmq: RMQ::new(&lcp, std::cmp::min), lcp, sa, + cnt, } } @@ -146,18 +155,59 @@ impl SufAry { le..ri } + pub fn push_front_char( + &self, + c: usize, + sa_range: Range, + lcp_len: usize, + ) -> Range { + if !sa_range.is_empty() { + assert!(lcp_len <= self.len_lcp(self.sa[sa_range.start], self.sa[sa_range.end - 1])); + } + if sa_range.is_empty() { + sa_range + } else { + self.push_back_substr( + sa_range.start..sa_range.start + lcp_len, + self.cnt[c]..self.cnt[c + 1], + 1, + ) + } + } + + pub fn push_back_substr( + &self, + s_substr: Range, + sa_range: Range, + lcp_len: usize, + ) -> Range { + if !sa_range.is_empty() { + assert!(lcp_len <= self.len_lcp(self.sa[sa_range.start], self.sa[sa_range.end - 1])); + } + if s_substr.is_empty() { + sa_range + } else { + let le = self.sa[sa_range.clone()].partition_point(|&i| { + self.cmp_substrs(i + lcp_len..i + lcp_len + s_substr.len(), s_substr.clone()) + == Ordering::Less + }) - sa_range.start; + //let ri = + le..le + } + } + /// Gets range r such that: - /// - for all i in sa\[r\] s\[i..i + substr.len()\] == s\[substr\] - /// - r.len() is the number of matches of s\[substr\] in s + /// - for all i in sa\[r\] s\[i..i + s_substr.len()\] == s\[s_substr\] + /// - r.len() is the number of matches of s\[s_substr\] in s /// /// # Complexity /// - Time: O(log(|s|)) /// - Space: O(1) - pub fn find_substr(&self, substr: Range) -> Range { + pub fn find_substr(&self, s_substr: Range) -> Range { let cmp = |i: usize, flip: bool| -> bool { - flip ^ (self.len_lcp(i, substr.start) < substr.len()) + flip ^ (self.len_lcp(i, s_substr.start) < s_substr.len()) }; - let idx = self.sa_inv[substr.start]; + let idx = self.sa_inv[s_substr.start]; let le = self.sa[..idx].partition_point(|&i| cmp(i, false)); let ri = self.sa[idx + 1..].partition_point(|&i| cmp(i, true)) + idx + 1; le..ri From fddbb4424ee4549d16c89046631eddd3e1dae82e Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 18:12:44 -0500 Subject: [PATCH 04/23] finish methods; need to test them now --- examples/strings/suf_ary_find_str_aizu.rs | 15 ++--- src/strings/suf_ary.rs | 81 ++++++++++++++++------- 2 files changed, 60 insertions(+), 36 deletions(-) diff --git a/examples/strings/suf_ary_find_str_aizu.rs b/examples/strings/suf_ary_find_str_aizu.rs index dff4dda6..9cc8846c 100644 --- a/examples/strings/suf_ary_find_str_aizu.rs +++ b/examples/strings/suf_ary_find_str_aizu.rs @@ -9,18 +9,11 @@ fn main() { t: String } - let s = s.chars().map(|x| x as usize).collect::>(); - let t = t.chars().map(|x| x as usize).collect::>(); + let s_vec = s.chars().map(|x| x as usize).collect::>(); + let t_vec = t.chars().map(|x| x as usize).collect::>(); - let suf_ary = SufAry::new(&s, 255); - - let mut range = 0..s.len(); - for (i, &c) in t.iter().enumerate() { - range = suf_ary.push_back_char(c, range, i); - if range.is_empty() { - break; - } - } + let suf_ary = SufAry::new(&s_vec, 255); + let range = suf_ary.find_str(&t_vec); let mut res: Vec = Vec::new(); res.extend_from_slice(&suf_ary.sa[range]); res.sort(); diff --git a/src/strings/suf_ary.rs b/src/strings/suf_ary.rs index 9cf3cad5..66fcd820 100644 --- a/src/strings/suf_ary.rs +++ b/src/strings/suf_ary.rs @@ -144,6 +144,37 @@ impl SufAry { } } + /// Gets range r such that: + /// - for all i in sa\[r\] s\[i..i + t.len()\] == t + /// - r.len() is the number of matches of t in s + /// + /// # Complexity + /// - Time: O(|t| * log(|s|)) + /// - Space: O(1) + pub fn find_str(&self, t: &[usize]) -> Range { + let le = self.sa.partition_point(|&i| &self.s[i..] < t); + let ri = + self.sa[le..].partition_point(|&i| &self.s[i..(i + t.len()).min(self.n)] == t) + le; + le..ri + } + + /// Gets range r such that: + /// - for all i in sa\[r\] s\[i..i + s_substr.len()\] == s\[s_substr\] + /// - r.len() is the number of matches of s\[s_substr\] in s + /// + /// # Complexity + /// - Time: O(log(|s|)) + /// - Space: O(1) + pub fn find_substr(&self, s_substr: Range) -> Range { + let cmp = |i: usize, flip: bool| -> bool { + flip ^ (self.len_lcp(i, s_substr.start) < s_substr.len()) + }; + let idx = self.sa_inv[s_substr.start]; + let le = self.sa[..idx].partition_point(|&i| cmp(i, false)); + let ri = self.sa[idx + 1..].partition_point(|&i| cmp(i, true)) + idx + 1; + le..ri + } + pub fn push_back_char(&self, c: usize, sa_range: Range, lcp_len: usize) -> Range { if !sa_range.is_empty() { assert!(lcp_len <= self.len_lcp(self.sa[sa_range.start], self.sa[sa_range.end - 1])); @@ -184,32 +215,32 @@ impl SufAry { if !sa_range.is_empty() { assert!(lcp_len <= self.len_lcp(self.sa[sa_range.start], self.sa[sa_range.end - 1])); } - if s_substr.is_empty() { - sa_range - } else { - let le = self.sa[sa_range.clone()].partition_point(|&i| { - self.cmp_substrs(i + lcp_len..i + lcp_len + s_substr.len(), s_substr.clone()) - == Ordering::Less - }) - sa_range.start; - //let ri = - le..le - } - } - - /// Gets range r such that: - /// - for all i in sa\[r\] s\[i..i + s_substr.len()\] == s\[s_substr\] - /// - r.len() is the number of matches of s\[s_substr\] in s - /// - /// # Complexity - /// - Time: O(log(|s|)) - /// - Space: O(1) - pub fn find_substr(&self, s_substr: Range) -> Range { - let cmp = |i: usize, flip: bool| -> bool { - flip ^ (self.len_lcp(i, s_substr.start) < s_substr.len()) + let cmp = |i: usize| -> Ordering { + self.cmp_substrs( + i + lcp_len..(i + lcp_len + s_substr.len()).min(self.n), + s_substr.clone(), + ) }; - let idx = self.sa_inv[s_substr.start]; - let le = self.sa[..idx].partition_point(|&i| cmp(i, false)); - let ri = self.sa[idx + 1..].partition_point(|&i| cmp(i, true)) + idx + 1; + let le = self.sa[sa_range.clone()].partition_point(|&i| cmp(i) == Ordering::Less) + - sa_range.start; + let ri = self.sa[le..sa_range.end].partition_point(|&i| cmp(i) == Ordering::Equal) - le; le..ri } + + pub fn push_front_substr( + &self, + s_substr: Range, + sa_range: Range, + lcp_len: usize, + ) -> Range { + if !sa_range.is_empty() { + assert!(lcp_len <= self.len_lcp(self.sa[sa_range.start], self.sa[sa_range.end - 1])); + } + //TODO: maybe special case when sa_range is empty + self.push_back_substr( + self.sa[sa_range.start]..self.sa[sa_range.start] + lcp_len, + self.find_substr(s_substr.clone()), + s_substr.len(), + ) + } } From d84085ddc0bdc2a25e05a9fc6c577afe39127adf Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 18:17:37 -0500 Subject: [PATCH 05/23] nit --- examples/strings/suf_ary_find_str_aizu.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/strings/suf_ary_find_str_aizu.rs b/examples/strings/suf_ary_find_str_aizu.rs index 9cc8846c..ec1c645a 100644 --- a/examples/strings/suf_ary_find_str_aizu.rs +++ b/examples/strings/suf_ary_find_str_aizu.rs @@ -9,11 +9,11 @@ fn main() { t: String } - let s_vec = s.chars().map(|x| x as usize).collect::>(); - let t_vec = t.chars().map(|x| x as usize).collect::>(); + let s = s.chars().map(|x| x as usize).collect::>(); + let t = t.chars().map(|x| x as usize).collect::>(); - let suf_ary = SufAry::new(&s_vec, 255); - let range = suf_ary.find_str(&t_vec); + let suf_ary = SufAry::new(&s, 255); + let range = suf_ary.find_str(&t); let mut res: Vec = Vec::new(); res.extend_from_slice(&suf_ary.sa[range]); res.sort(); From f4c28217047bdb39f6a202d88af3089290982087 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 19:00:27 -0500 Subject: [PATCH 06/23] now AC's --- examples/strings/suf_ary_find_str_aizu.rs | 36 +++++++++++++++++++++++ src/strings/suf_ary.rs | 24 +++++++-------- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/examples/strings/suf_ary_find_str_aizu.rs b/examples/strings/suf_ary_find_str_aizu.rs index ec1c645a..b84e96c8 100644 --- a/examples/strings/suf_ary_find_str_aizu.rs +++ b/examples/strings/suf_ary_find_str_aizu.rs @@ -14,6 +14,42 @@ fn main() { let suf_ary = SufAry::new(&s, 255); let range = suf_ary.find_str(&t); + + let mut push_pop_sa_range = 0..s.len(); + //let mut push_pop_t_range = t.len() / 2..t.len() / 2; //TODO: revert + let mut push_pop_t_range = 0..0; + //let mut push_pop_t_range = 0..0; // this AC's + loop { + let mut found = false; + + if push_pop_t_range.start > 0 { + found = true; + let lcp_len = push_pop_t_range.len(); + push_pop_t_range.start -= 1; + push_pop_sa_range = + suf_ary.push_front_char(t[push_pop_t_range.start], push_pop_sa_range, lcp_len); + } + + if push_pop_t_range.end < t.len() { + found = true; + push_pop_sa_range = suf_ary.push_back_char( + t[push_pop_t_range.end], + push_pop_sa_range, + push_pop_t_range.len(), + ); + push_pop_t_range.end += 1; + } + + assert!(push_pop_sa_range.start <= range.start); + assert!(range.end <= push_pop_sa_range.end); + + if !found { + break; + } + } + + assert_eq!(range, push_pop_sa_range); + let mut res: Vec = Vec::new(); res.extend_from_slice(&suf_ary.sa[range]); res.sort(); diff --git a/src/strings/suf_ary.rs b/src/strings/suf_ary.rs index 66fcd820..0bc06823 100644 --- a/src/strings/suf_ary.rs +++ b/src/strings/suf_ary.rs @@ -112,8 +112,9 @@ impl SufAry { /// - Time: O(1) /// - Space: O(1) pub fn len_lcp(&self, i1: usize, i2: usize) -> usize { - if i1 == i2 { - return self.n - i1; + let mx = std::cmp::max(i1, i2); + if i1 == i2 || mx == self.n { + return self.n - mx; } let (mut le, mut ri) = (self.sa_inv[i1], self.sa_inv[i2]); if le > ri { @@ -198,11 +199,8 @@ impl SufAry { if sa_range.is_empty() { sa_range } else { - self.push_back_substr( - sa_range.start..sa_range.start + lcp_len, - self.cnt[c]..self.cnt[c + 1], - 1, - ) + let i = self.sa[sa_range.start]; + self.push_back_substr(i..i + lcp_len, self.cnt[c]..self.cnt[c + 1], 1) } } @@ -215,15 +213,13 @@ impl SufAry { if !sa_range.is_empty() { assert!(lcp_len <= self.len_lcp(self.sa[sa_range.start], self.sa[sa_range.end - 1])); } - let cmp = |i: usize| -> Ordering { - self.cmp_substrs( - i + lcp_len..(i + lcp_len + s_substr.len()).min(self.n), - s_substr.clone(), - ) + let cmp = |mut i: usize| -> Ordering { + i += lcp_len; + self.cmp_substrs(i..(i + s_substr.len()).min(self.n), s_substr.clone()) }; let le = self.sa[sa_range.clone()].partition_point(|&i| cmp(i) == Ordering::Less) - - sa_range.start; - let ri = self.sa[le..sa_range.end].partition_point(|&i| cmp(i) == Ordering::Equal) - le; + + sa_range.start; + let ri = self.sa[le..sa_range.end].partition_point(|&i| cmp(i) == Ordering::Equal) + le; le..ri } From b995c03641165c138331747d35c3467763ac0711 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 19:03:32 -0500 Subject: [PATCH 07/23] actually still wa/rte --- examples/strings/suf_ary_find_str_aizu.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/strings/suf_ary_find_str_aizu.rs b/examples/strings/suf_ary_find_str_aizu.rs index b84e96c8..b3211bce 100644 --- a/examples/strings/suf_ary_find_str_aizu.rs +++ b/examples/strings/suf_ary_find_str_aizu.rs @@ -16,9 +16,7 @@ fn main() { let range = suf_ary.find_str(&t); let mut push_pop_sa_range = 0..s.len(); - //let mut push_pop_t_range = t.len() / 2..t.len() / 2; //TODO: revert - let mut push_pop_t_range = 0..0; - //let mut push_pop_t_range = 0..0; // this AC's + let mut push_pop_t_range = t.len() / 2..t.len() / 2; loop { let mut found = false; @@ -40,8 +38,10 @@ fn main() { push_pop_t_range.end += 1; } - assert!(push_pop_sa_range.start <= range.start); - assert!(range.end <= push_pop_sa_range.end); + if !range.is_empty() { + assert!(push_pop_sa_range.start <= range.start); + assert!(range.end <= push_pop_sa_range.end); + } if !found { break; From 4d91fc2907bbd8ded954a11b6591bdab8896f383 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 19:16:36 -0500 Subject: [PATCH 08/23] now ACs --- examples/strings/suf_ary_find_str_aizu.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/examples/strings/suf_ary_find_str_aizu.rs b/examples/strings/suf_ary_find_str_aizu.rs index b3211bce..8deddf5f 100644 --- a/examples/strings/suf_ary_find_str_aizu.rs +++ b/examples/strings/suf_ary_find_str_aizu.rs @@ -38,17 +38,15 @@ fn main() { push_pop_t_range.end += 1; } - if !range.is_empty() { - assert!(push_pop_sa_range.start <= range.start); - assert!(range.end <= push_pop_sa_range.end); - } - if !found { break; } } - assert_eq!(range, push_pop_sa_range); + assert_eq!(range.is_empty(), push_pop_sa_range.is_empty()); + if !range.is_empty() { + assert_eq!(range, push_pop_sa_range); + } let mut res: Vec = Vec::new(); res.extend_from_slice(&suf_ary.sa[range]); From c3d24ba742ea84a1f2ad8ceb39070267ce27cc76 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 19:22:54 -0500 Subject: [PATCH 09/23] move asserts into function --- examples/strings/suf_ary_find_str_aizu.rs | 36 ++-------------- .../strings/suf_ary_push_pop_char_asserts.rs | 41 +++++++++++++++++++ 2 files changed, 45 insertions(+), 32 deletions(-) create mode 100644 examples/strings/suf_ary_push_pop_char_asserts.rs diff --git a/examples/strings/suf_ary_find_str_aizu.rs b/examples/strings/suf_ary_find_str_aizu.rs index 8deddf5f..a11aee9f 100644 --- a/examples/strings/suf_ary_find_str_aizu.rs +++ b/examples/strings/suf_ary_find_str_aizu.rs @@ -3,6 +3,9 @@ use proconio::input; use programming_team_code_rust::strings::suf_ary::SufAry; +mod suf_ary_push_pop_char_asserts; +use suf_ary_push_pop_char_asserts::suf_ary_push_pop_char_asserts; + fn main() { input! { s: String, @@ -15,38 +18,7 @@ fn main() { let suf_ary = SufAry::new(&s, 255); let range = suf_ary.find_str(&t); - let mut push_pop_sa_range = 0..s.len(); - let mut push_pop_t_range = t.len() / 2..t.len() / 2; - loop { - let mut found = false; - - if push_pop_t_range.start > 0 { - found = true; - let lcp_len = push_pop_t_range.len(); - push_pop_t_range.start -= 1; - push_pop_sa_range = - suf_ary.push_front_char(t[push_pop_t_range.start], push_pop_sa_range, lcp_len); - } - - if push_pop_t_range.end < t.len() { - found = true; - push_pop_sa_range = suf_ary.push_back_char( - t[push_pop_t_range.end], - push_pop_sa_range, - push_pop_t_range.len(), - ); - push_pop_t_range.end += 1; - } - - if !found { - break; - } - } - - assert_eq!(range.is_empty(), push_pop_sa_range.is_empty()); - if !range.is_empty() { - assert_eq!(range, push_pop_sa_range); - } + suf_ary_push_pop_char_asserts(s.len(), &suf_ary, &range, &t); let mut res: Vec = Vec::new(); res.extend_from_slice(&suf_ary.sa[range]); diff --git a/examples/strings/suf_ary_push_pop_char_asserts.rs b/examples/strings/suf_ary_push_pop_char_asserts.rs new file mode 100644 index 00000000..d13984a5 --- /dev/null +++ b/examples/strings/suf_ary_push_pop_char_asserts.rs @@ -0,0 +1,41 @@ +use programming_team_code_rust::strings::suf_ary::SufAry; +use std::ops::Range; +pub fn suf_ary_push_pop_char_asserts( + n: usize, + suf_ary: &SufAry, + range: &Range, + t: &[usize], +) { + let mut push_pop_sa_range = 0..n; + let mut push_pop_t_range = t.len() / 2..t.len() / 2; + loop { + let mut found = false; + + if push_pop_t_range.start > 0 { + found = true; + let lcp_len = push_pop_t_range.len(); + push_pop_t_range.start -= 1; + push_pop_sa_range = + suf_ary.push_front_char(t[push_pop_t_range.start], push_pop_sa_range, lcp_len); + } + + if push_pop_t_range.end < t.len() { + found = true; + push_pop_sa_range = suf_ary.push_back_char( + t[push_pop_t_range.end], + push_pop_sa_range, + push_pop_t_range.len(), + ); + push_pop_t_range.end += 1; + } + + if !found { + break; + } + } + + assert_eq!(range.is_empty(), push_pop_sa_range.is_empty()); + if !range.is_empty() { + assert_eq!(*range, push_pop_sa_range); + } +} From e44e027edeaf85433e8aff900887f8abd68e358b Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 19:25:26 -0500 Subject: [PATCH 10/23] call asserts in other test now --- examples/strings/suf_ary_find_many_strs_aizu.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/strings/suf_ary_find_many_strs_aizu.rs b/examples/strings/suf_ary_find_many_strs_aizu.rs index 466a47dc..d07358d3 100644 --- a/examples/strings/suf_ary_find_many_strs_aizu.rs +++ b/examples/strings/suf_ary_find_many_strs_aizu.rs @@ -3,6 +3,9 @@ use proconio::input; use programming_team_code_rust::strings::suf_ary::SufAry; +mod suf_ary_push_pop_char_asserts; +use suf_ary_push_pop_char_asserts::suf_ary_push_pop_char_asserts; + fn main() { input! { s: String, @@ -16,8 +19,9 @@ fn main() { input! { t: String } - let t_vec = t.chars().map(|x| x as usize).collect::>(); - let range = suf_ary.find_str(&t_vec); + let t = t.chars().map(|x| x as usize).collect::>(); + let range = suf_ary.find_str(&t); + suf_ary_push_pop_char_asserts(s.len(), &suf_ary, &range, &t); println!("{}", !range.is_empty() as usize); } } From b91a922ae740e7e828964a6f9d6516519b55b232 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 19:29:51 -0500 Subject: [PATCH 11/23] simplify test --- examples/strings/suf_ary_cmp_aizu.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/examples/strings/suf_ary_cmp_aizu.rs b/examples/strings/suf_ary_cmp_aizu.rs index 196d2bd1..94975235 100644 --- a/examples/strings/suf_ary_cmp_aizu.rs +++ b/examples/strings/suf_ary_cmp_aizu.rs @@ -7,26 +7,23 @@ use programming_team_code_rust::strings::suf_ary::SufAry; fn main() { input! { n: usize, - mut a: [i32; n], + mut a: [usize; n], m: usize, - b: [i32; m] + b: [usize; m] } let are_equal = a == b; - a.push(-1); a.extend(b); let (cmps, max_val) = compress(&a); let suf_ary = SufAry::new(&cmps, max_val); - let res = suf_ary.cmp_substrs(0..n, n + 1..n + 1 + m); + let res = suf_ary.cmp_substrs(0..n, n..n + m); if are_equal { assert_eq!(res, std::cmp::Ordering::Equal); - assert_eq!(suf_ary.cmp_sufs(0, n + 1), std::cmp::Ordering::Greater); println!("0"); } else { - assert_eq!(res, suf_ary.cmp_sufs(0, n + 1)); println!("{}", (res == std::cmp::Ordering::Less) as usize); } } From b823110b5e51599a26a9c351dcef45315d8d242a Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 19:33:29 -0500 Subject: [PATCH 12/23] saving --- examples/strings/suf_ary_find_substr_aizu.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/strings/suf_ary_find_substr_aizu.rs b/examples/strings/suf_ary_find_substr_aizu.rs index 9f41f620..4d92482c 100644 --- a/examples/strings/suf_ary_find_substr_aizu.rs +++ b/examples/strings/suf_ary_find_substr_aizu.rs @@ -14,7 +14,8 @@ fn main() { both.extend(s.chars().map(|x| x as usize).collect::>()); let suf_ary = SufAry::new(&both, 255); - let mut res = suf_ary.sa[suf_ary.find_substr(0..m)] + let range = suf_ary.find_substr(0..m); + let mut res = suf_ary.sa[range] .iter() .copied() .filter(|&i| i >= m) From eeeb1706199e058e3f944c8e0618b48e2d2fca7b Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 19:52:09 -0500 Subject: [PATCH 13/23] now ACs --- examples/strings/suf_ary_find_substr_aizu.rs | 48 ++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/examples/strings/suf_ary_find_substr_aizu.rs b/examples/strings/suf_ary_find_substr_aizu.rs index 4d92482c..30a82e08 100644 --- a/examples/strings/suf_ary_find_substr_aizu.rs +++ b/examples/strings/suf_ary_find_substr_aizu.rs @@ -9,12 +9,60 @@ fn main() { t: String } + let n = s.chars().count(); let m = t.chars().count(); let mut both = t.chars().map(|x| x as usize).collect::>(); both.extend(s.chars().map(|x| x as usize).collect::>()); let suf_ary = SufAry::new(&both, 255); let range = suf_ary.find_substr(0..m); + + { + let mut splits = (0..6) + .map(|_| rand::random::() % (m + 1)) + .collect::>(); + splits.push(0); + splits.push(m); + splits.sort(); + let subarrays = (1..splits.len()) + .map(|i| splits[i - 1]..splits[i]) + .collect::>(); + let mut push_pop_range = 0..both.len(); + let mut push_pop_lcp_len = 0; + let mut range_subarray = subarrays.len() / 2..subarrays.len() / 2; + loop { + let mut found = false; + if range_subarray.start > 0 { + found = true; + range_subarray.start -= 1; + let curr_substr = &subarrays[range_subarray.start]; + push_pop_range = suf_ary.push_front_substr( + curr_substr.clone(), + push_pop_range, + push_pop_lcp_len, + ); + push_pop_lcp_len += curr_substr.len(); + } + + if range_subarray.end < subarrays.len() { + found = true; + let curr_substr = &subarrays[range_subarray.end]; + push_pop_range = + suf_ary.push_back_substr(curr_substr.clone(), push_pop_range, push_pop_lcp_len); + push_pop_lcp_len += curr_substr.len(); + range_subarray.end += 1; + } + + if !found { + break; + } + } + assert_eq!(range.is_empty(), push_pop_range.is_empty()); + if !range.is_empty() { + assert_eq!(range, push_pop_range); + } + } + let mut res = suf_ary.sa[range] .iter() .copied() From 5b143f30d9113958583cc76f35fe74440f49b382 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 19:52:55 -0500 Subject: [PATCH 14/23] better assert --- examples/strings/suf_ary_find_substr_aizu.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/strings/suf_ary_find_substr_aizu.rs b/examples/strings/suf_ary_find_substr_aizu.rs index 30a82e08..d18790af 100644 --- a/examples/strings/suf_ary_find_substr_aizu.rs +++ b/examples/strings/suf_ary_find_substr_aizu.rs @@ -57,10 +57,7 @@ fn main() { break; } } - assert_eq!(range.is_empty(), push_pop_range.is_empty()); - if !range.is_empty() { - assert_eq!(range, push_pop_range); - } + assert_eq!(range, push_pop_range); } let mut res = suf_ary.sa[range] From 21cd8fd373954a0de81048c0da3c8a4c3cfdfccb Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 20:03:47 -0500 Subject: [PATCH 15/23] refactor into function --- examples/strings/suf_ary_find_substr_aizu.rs | 47 ++---------------- .../suf_ary_push_pop_substr_asserts.rs | 48 +++++++++++++++++++ 2 files changed, 52 insertions(+), 43 deletions(-) create mode 100644 examples/strings/suf_ary_push_pop_substr_asserts.rs diff --git a/examples/strings/suf_ary_find_substr_aizu.rs b/examples/strings/suf_ary_find_substr_aizu.rs index d18790af..790267af 100644 --- a/examples/strings/suf_ary_find_substr_aizu.rs +++ b/examples/strings/suf_ary_find_substr_aizu.rs @@ -3,13 +3,15 @@ use proconio::input; use programming_team_code_rust::strings::suf_ary::SufAry; +mod suf_ary_push_pop_substr_asserts; +use suf_ary_push_pop_substr_asserts::suf_ary_push_pop_substr_asserts; + fn main() { input! { s: String, t: String } - let n = s.chars().count(); let m = t.chars().count(); let mut both = t.chars().map(|x| x as usize).collect::>(); both.extend(s.chars().map(|x| x as usize).collect::>()); @@ -17,48 +19,7 @@ fn main() { let suf_ary = SufAry::new(&both, 255); let range = suf_ary.find_substr(0..m); - { - let mut splits = (0..6) - .map(|_| rand::random::() % (m + 1)) - .collect::>(); - splits.push(0); - splits.push(m); - splits.sort(); - let subarrays = (1..splits.len()) - .map(|i| splits[i - 1]..splits[i]) - .collect::>(); - let mut push_pop_range = 0..both.len(); - let mut push_pop_lcp_len = 0; - let mut range_subarray = subarrays.len() / 2..subarrays.len() / 2; - loop { - let mut found = false; - if range_subarray.start > 0 { - found = true; - range_subarray.start -= 1; - let curr_substr = &subarrays[range_subarray.start]; - push_pop_range = suf_ary.push_front_substr( - curr_substr.clone(), - push_pop_range, - push_pop_lcp_len, - ); - push_pop_lcp_len += curr_substr.len(); - } - - if range_subarray.end < subarrays.len() { - found = true; - let curr_substr = &subarrays[range_subarray.end]; - push_pop_range = - suf_ary.push_back_substr(curr_substr.clone(), push_pop_range, push_pop_lcp_len); - push_pop_lcp_len += curr_substr.len(); - range_subarray.end += 1; - } - - if !found { - break; - } - } - assert_eq!(range, push_pop_range); - } + suf_ary_push_pop_substr_asserts(both.len(), &suf_ary, &range, &(0..m)); let mut res = suf_ary.sa[range] .iter() diff --git a/examples/strings/suf_ary_push_pop_substr_asserts.rs b/examples/strings/suf_ary_push_pop_substr_asserts.rs new file mode 100644 index 00000000..0f36d703 --- /dev/null +++ b/examples/strings/suf_ary_push_pop_substr_asserts.rs @@ -0,0 +1,48 @@ +use programming_team_code_rust::strings::suf_ary::SufAry; +use std::ops::Range; +pub fn suf_ary_push_pop_substr_asserts( + tot_len: usize, + suf_ary: &SufAry, + range: &Range, + s_to_look_for_range: &Range, +) { + let mut splits = (0..6) + .map(|_| { + s_to_look_for_range.start + (rand::random::() % (s_to_look_for_range.len() + 1)) + }) + .collect::>(); + splits.push(s_to_look_for_range.start); + splits.push(s_to_look_for_range.end); + splits.sort(); + let subarrays = (1..splits.len()) + .map(|i| splits[i - 1]..splits[i]) + .collect::>(); + let mut push_pop_range = 0..tot_len; + let mut push_pop_lcp_len = 0; + let mut range_subarray = subarrays.len() / 2..subarrays.len() / 2; + loop { + let mut found = false; + if range_subarray.start > 0 { + found = true; + range_subarray.start -= 1; + let curr_substr = &subarrays[range_subarray.start]; + push_pop_range = + suf_ary.push_front_substr(curr_substr.clone(), push_pop_range, push_pop_lcp_len); + push_pop_lcp_len += curr_substr.len(); + } + + if range_subarray.end < subarrays.len() { + found = true; + let curr_substr = &subarrays[range_subarray.end]; + push_pop_range = + suf_ary.push_back_substr(curr_substr.clone(), push_pop_range, push_pop_lcp_len); + push_pop_lcp_len += curr_substr.len(); + range_subarray.end += 1; + } + + if !found { + break; + } + } + assert_eq!(*range, push_pop_range); +} From c288b9f60b0f0b734c8eaf20f9da3aabb7fa16da Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 20:06:01 -0500 Subject: [PATCH 16/23] now call function from other test --- examples/strings/suf_ary_find_substr_many_aizu.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/strings/suf_ary_find_substr_many_aizu.rs b/examples/strings/suf_ary_find_substr_many_aizu.rs index dd811ebc..64cbbb5b 100644 --- a/examples/strings/suf_ary_find_substr_many_aizu.rs +++ b/examples/strings/suf_ary_find_substr_many_aizu.rs @@ -4,6 +4,9 @@ use proconio::input; use programming_team_code_rust::data_structures::rmq::RMQ; use programming_team_code_rust::strings::suf_ary::SufAry; +mod suf_ary_push_pop_substr_asserts; +use suf_ary_push_pop_substr_asserts::suf_ary_push_pop_substr_asserts; + fn main() { input! { s: String, @@ -29,7 +32,11 @@ fn main() { let rmq = RMQ::new(&suf_ary.sa, std::cmp::min); for i in 0..num_queries_find_substr { - let idx = rmq.query(suf_ary.find_substr(length[i]..length[i + 1])); + let s_to_look_for_range = length[i]..length[i + 1]; + let range = suf_ary.find_substr(s_to_look_for_range.clone()); + suf_ary_push_pop_substr_asserts(s.len(), &suf_ary, &range, &s_to_look_for_range); + + let idx = rmq.query(range); println!( "{}", (idx + length[i + 1] - length[i] <= length[0]) as usize From 90fd93de80e7f064d387538b84ee9922c267d51c Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 20:10:12 -0500 Subject: [PATCH 17/23] now test works --- src/strings/suf_ary.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/strings/suf_ary.rs b/src/strings/suf_ary.rs index 0bc06823..b5f8c87e 100644 --- a/src/strings/suf_ary.rs +++ b/src/strings/suf_ary.rs @@ -44,13 +44,11 @@ use ac_library::string::{lcp_array_arbitrary, suffix_array_manual}; /// let suf_ary2 = SufAry::new(&a_comp, max_val); /// /// assert_eq!(suf_ary1.len_lcp(1, 3), 3); -/// assert!(std::panic::catch_unwind(|| suf_ary1.len_lcp(1, n)).is_err()); /// /// assert_eq!(suf_ary1.cmp_sufs(1, 3), Ordering::Greater); /// assert!(std::panic::catch_unwind(|| suf_ary1.cmp_sufs(n, 2)).is_err()); /// /// assert_eq!(suf_ary1.cmp_substrs(1..4, 3..6), Ordering::Equal); -/// assert!(std::panic::catch_unwind(|| suf_ary1.cmp_substrs(3..4, n..n)).is_err()); /// /// assert_eq!(suf_ary1.find_str(&"ana".chars().map(|c| c as usize).collect::>()), 1..3); /// assert_eq!(suf_ary1.find_str(&[]), 0..n); From da41ff40c97c5d66c748d1038c6722323490ad3d Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 20:33:19 -0500 Subject: [PATCH 18/23] finished test --- src/strings/suf_ary.rs | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/strings/suf_ary.rs b/src/strings/suf_ary.rs index b5f8c87e..31e88d23 100644 --- a/src/strings/suf_ary.rs +++ b/src/strings/suf_ary.rs @@ -33,7 +33,7 @@ use ac_library::string::{lcp_array_arbitrary, suffix_array_manual}; /// // || /// // 2 nana 5 /// -/// let suf_ary1 = SufAry::new(&s.chars().map(|c| c as usize).collect::>(), 255); +/// let suf_ary1 = SufAry::new(&s.chars().map(|c| c as usize).collect::>(), 255); /// let n = suf_ary1.sa.len(); /// assert_eq!(suf_ary1.sa, [5, 3, 1, 0, 4, 2]); /// assert_eq!(suf_ary1.sa_inv, [3, 2, 5, 1, 4, 0]); @@ -54,8 +54,20 @@ use ac_library::string::{lcp_array_arbitrary, suffix_array_manual}; /// assert_eq!(suf_ary1.find_str(&[]), 0..n); /// /// assert_eq!(suf_ary1.find_substr(1..4), 1..3); -/// assert_eq!(suf_ary1.find_substr(1..1), 0..n); +/// assert_eq!(suf_ary1.find_substr(2..2), 0..n); /// assert!(std::panic::catch_unwind(|| suf_ary1.find_substr(n..n)).is_err()); +/// +/// assert_eq!(suf_ary1.push_back_char('n' as usize, 0..3, 1), 1..3); +/// assert_eq!(suf_ary1.push_back_char('n' as usize, n..n, 0), n..n); +/// +/// assert_eq!(suf_ary1.push_front_char('a' as usize, 4..6, 2), 1..3); +/// assert_eq!(suf_ary1.push_front_char('a' as usize, n..n, 0), n..n); +/// +/// assert_eq!(suf_ary1.push_back_substr(4..6, 0..3, 1), 1..3); +/// assert_eq!(suf_ary1.push_back_substr(4..6, n..n, 0), n..n); +/// +/// assert_eq!(suf_ary1.push_front_substr(3..5, 0..3, 1), 1..3); +/// assert_eq!(suf_ary1.push_front_substr(3..5, n..n, 0), n..n); /// ``` pub struct SufAry { n: usize, @@ -230,11 +242,15 @@ impl SufAry { if !sa_range.is_empty() { assert!(lcp_len <= self.len_lcp(self.sa[sa_range.start], self.sa[sa_range.end - 1])); } - //TODO: maybe special case when sa_range is empty - self.push_back_substr( - self.sa[sa_range.start]..self.sa[sa_range.start] + lcp_len, - self.find_substr(s_substr.clone()), - s_substr.len(), - ) + if sa_range.is_empty() { + sa_range + } else { + let i = self.sa[sa_range.start]; + self.push_back_substr( + i..i + lcp_len, + self.find_substr(s_substr.clone()), + s_substr.len(), + ) + } } } From b886f6d86af90148c04483a27527de4c79fca3c9 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 20:41:18 -0500 Subject: [PATCH 19/23] hit last branch --- examples/strings/suf_ary_find_substr_many_aizu.rs | 2 +- examples/strings/suf_ary_push_pop_substr_asserts.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/strings/suf_ary_find_substr_many_aizu.rs b/examples/strings/suf_ary_find_substr_many_aizu.rs index 64cbbb5b..fca643a8 100644 --- a/examples/strings/suf_ary_find_substr_many_aizu.rs +++ b/examples/strings/suf_ary_find_substr_many_aizu.rs @@ -13,7 +13,7 @@ fn main() { q: usize } - let num_queries_find_substr = q.min(100); + let num_queries_find_substr = q.min(50); let mut s = s.chars().map(|x| x as usize).collect::>(); diff --git a/examples/strings/suf_ary_push_pop_substr_asserts.rs b/examples/strings/suf_ary_push_pop_substr_asserts.rs index 0f36d703..97c3b655 100644 --- a/examples/strings/suf_ary_push_pop_substr_asserts.rs +++ b/examples/strings/suf_ary_push_pop_substr_asserts.rs @@ -6,6 +6,10 @@ pub fn suf_ary_push_pop_substr_asserts( range: &Range, s_to_look_for_range: &Range, ) { + assert_eq!( + suf_ary.push_front_substr(0..tot_len, tot_len..tot_len, 0), + tot_len..tot_len + ); let mut splits = (0..6) .map(|_| { s_to_look_for_range.start + (rand::random::() % (s_to_look_for_range.len() + 1)) From 0da00b202e0a1981df938eef900936cafbcb878e Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 20:49:53 -0500 Subject: [PATCH 20/23] finish docs --- src/strings/suf_ary.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/strings/suf_ary.rs b/src/strings/suf_ary.rs index 31e88d23..a1a6fa16 100644 --- a/src/strings/suf_ary.rs +++ b/src/strings/suf_ary.rs @@ -186,6 +186,15 @@ impl SufAry { le..ri } + /// let t = s[sa[sa_range.start]..sa[sa_range.start] + lcp_len] + c + /// + /// Gets range r such that: + /// - for all i in sa\[r\] s\[i..i + t.len()\] == t + /// - r.len() is the number of matches of t in s + /// + /// # Complexity + /// - Time: O(log(|s|)) + /// - Space: O(1) pub fn push_back_char(&self, c: usize, sa_range: Range, lcp_len: usize) -> Range { if !sa_range.is_empty() { assert!(lcp_len <= self.len_lcp(self.sa[sa_range.start], self.sa[sa_range.end - 1])); @@ -197,6 +206,15 @@ impl SufAry { le..ri } + /// let t = c + s[sa[sa_range.start]..sa[sa_range.start] + lcp_len] + /// + /// Gets range r such that: + /// - for all i in sa\[r\] s\[i..i + t.len()\] == t + /// - r.len() is the number of matches of t in s + /// + /// # Complexity + /// - Time: O(log(|s|)) + /// - Space: O(1) pub fn push_front_char( &self, c: usize, @@ -214,6 +232,15 @@ impl SufAry { } } + /// let t = s[sa[sa_range.start]..sa[sa_range.start] + lcp_len] + s[s_substr] + /// + /// Gets range r such that: + /// - for all i in sa\[r\] s\[i..i + t.len()\] == t + /// - r.len() is the number of matches of t in s + /// + /// # Complexity + /// - Time: O(log(|s|)) + /// - Space: O(1) pub fn push_back_substr( &self, s_substr: Range, @@ -233,6 +260,15 @@ impl SufAry { le..ri } + /// let t = s[s_substr] + s[sa[sa_range.start]..sa[sa_range.start] + lcp_len] + /// + /// Gets range r such that: + /// - for all i in sa\[r\] s\[i..i + t.len()\] == t + /// - r.len() is the number of matches of t in s + /// + /// # Complexity + /// - Time: O(log(|s|)) + /// - Space: O(1) pub fn push_front_substr( &self, s_substr: Range, From 77bb85897d5b2a625307b93355e902003b6279ba Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 20:55:46 -0500 Subject: [PATCH 21/23] finish docs --- src/strings/suf_ary.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/strings/suf_ary.rs b/src/strings/suf_ary.rs index a1a6fa16..1d9a126d 100644 --- a/src/strings/suf_ary.rs +++ b/src/strings/suf_ary.rs @@ -186,7 +186,7 @@ impl SufAry { le..ri } - /// let t = s[sa[sa_range.start]..sa[sa_range.start] + lcp_len] + c + /// let t = s\[sa\[sa_range.start\]..sa\[sa_range.start\] + lcp_len\] + c /// /// Gets range r such that: /// - for all i in sa\[r\] s\[i..i + t.len()\] == t @@ -206,7 +206,7 @@ impl SufAry { le..ri } - /// let t = c + s[sa[sa_range.start]..sa[sa_range.start] + lcp_len] + /// let t = c + s\[sa\[sa_range.start\]..sa\[sa_range.start\] + lcp_len\] /// /// Gets range r such that: /// - for all i in sa\[r\] s\[i..i + t.len()\] == t @@ -232,7 +232,7 @@ impl SufAry { } } - /// let t = s[sa[sa_range.start]..sa[sa_range.start] + lcp_len] + s[s_substr] + /// let t = s\[sa\[sa_range.start\]..sa\[sa_range.start\] + lcp_len\] + s\[s_substr\] /// /// Gets range r such that: /// - for all i in sa\[r\] s\[i..i + t.len()\] == t @@ -260,7 +260,7 @@ impl SufAry { le..ri } - /// let t = s[s_substr] + s[sa[sa_range.start]..sa[sa_range.start] + lcp_len] + /// let t = s\[s_substr\] + s\[sa\[sa_range.start\]..sa\[sa_range.start\] + lcp_len\] /// /// Gets range r such that: /// - for all i in sa\[r\] s\[i..i + t.len()\] == t From d8f94662b5f70c5f01ae7bbce90f0a442f1bf23b Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 22:50:22 -0500 Subject: [PATCH 22/23] Update suf_ary_find_substr_many_aizu.rs --- examples/strings/suf_ary_find_substr_many_aizu.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/strings/suf_ary_find_substr_many_aizu.rs b/examples/strings/suf_ary_find_substr_many_aizu.rs index fca643a8..095ffa44 100644 --- a/examples/strings/suf_ary_find_substr_many_aizu.rs +++ b/examples/strings/suf_ary_find_substr_many_aizu.rs @@ -13,7 +13,7 @@ fn main() { q: usize } - let num_queries_find_substr = q.min(50); + let num_queries_find_substr = q.min(15); let mut s = s.chars().map(|x| x as usize).collect::>(); From 0348f171e32253bd866df4dacbaa661ed677374a Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 26 Jun 2024 23:11:44 -0500 Subject: [PATCH 23/23] Update suf_ary_find_substr_many_aizu.rs --- examples/strings/suf_ary_find_substr_many_aizu.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/strings/suf_ary_find_substr_many_aizu.rs b/examples/strings/suf_ary_find_substr_many_aizu.rs index 095ffa44..5ae34f33 100644 --- a/examples/strings/suf_ary_find_substr_many_aizu.rs +++ b/examples/strings/suf_ary_find_substr_many_aizu.rs @@ -13,7 +13,7 @@ fn main() { q: usize } - let num_queries_find_substr = q.min(15); + let num_queries_find_substr = q.min(3); let mut s = s.chars().map(|x| x as usize).collect::>();