ICFP 2007 Contest: https://web.archive.org/web/20090301164728/https://save-endo.cs.uu.nl/
1use crate::base::Base; 2use crate::pattern::Pattern; 3use crate::pattern::PatternItem; 4use crate::rna::Rna; 5use crate::template::Template; 6use crate::template::TemplateItem; 7use std::mem; 8 9pub struct Parser<I> 10where 11 I: Iterator<Item = Base>, 12{ 13 iter: I, 14 peeked: Vec<Base>, 15 index: usize, 16} 17 18impl<I> Parser<I> 19where 20 I: Iterator<Item = Base>, 21{ 22 pub fn new(iter: I) -> Parser<I> { 23 Parser { 24 iter: iter, 25 peeked: Vec::new(), 26 index: 0, 27 } 28 } 29 30 pub fn index(&self) -> usize { 31 self.index 32 } 33 34 fn peek_to(&mut self, n: usize) { 35 while self.peeked.len() < n { 36 if let Some(b) = self.iter.next() { 37 self.peeked.push(b); 38 } else { 39 return; 40 } 41 } 42 } 43 44 pub fn next_is(&mut self, next: &[Base]) -> bool { 45 self.peek_to(next.len()); 46 if self.peeked.len() < next.len() { 47 return false; 48 } 49 return &self.peeked[..next.len()] == next; 50 } 51 52 pub fn advance(&mut self, n: usize) { 53 self.peek_to(n); 54 self.index += n; 55 self.peeked.drain(..n); 56 } 57 58 pub fn nat(&mut self) -> Option<usize> { 59 let mut ret = 0; 60 let mut bit = 1; 61 loop { 62 if self.next_is(&[Base::P]) { 63 self.advance(1); 64 return Some(ret); 65 } else if self.next_is(&[Base::I]) || self.next_is(&[Base::F]) { 66 self.advance(1); 67 } else if self.next_is(&[Base::C]) { 68 ret += bit; 69 self.advance(1); 70 } else { 71 return None; 72 } 73 74 bit *= 2; 75 } 76 } 77 78 pub fn consts(&mut self) -> Vec<Base> { 79 let mut ret = Vec::new(); 80 loop { 81 if self.next_is(&[Base::C]) { 82 self.advance(1); 83 ret.push(Base::I); 84 } else if self.next_is(&[Base::F]) { 85 self.advance(1); 86 ret.push(Base::C); 87 } else if self.next_is(&[Base::P]) { 88 self.advance(1); 89 ret.push(Base::F); 90 } else if self.next_is(&[Base::I, Base::C]) { 91 self.advance(2); 92 ret.push(Base::P); 93 } else { 94 return ret; 95 } 96 } 97 } 98 99 pub fn pattern(&mut self, rna: &mut Vec<Rna>) -> Option<Pattern> { 100 let mut ret = Vec::new(); 101 let mut level = 0; 102 loop { 103 if self.next_is(&[Base::C]) { 104 self.advance(1); 105 ret.push(PatternItem::Base(Base::I)); 106 } else if self.next_is(&[Base::F]) { 107 self.advance(1); 108 ret.push(PatternItem::Base(Base::C)); 109 } else if self.next_is(&[Base::P]) { 110 self.advance(1); 111 ret.push(PatternItem::Base(Base::F)); 112 } else if self.next_is(&[Base::I, Base::C]) { 113 self.advance(2); 114 ret.push(PatternItem::Base(Base::P)); 115 } else if self.next_is(&[Base::I, Base::P]) { 116 self.advance(2); 117 let n = self.nat()?; 118 ret.push(PatternItem::Skip(n)); 119 } else if self.next_is(&[Base::I, Base::F]) { 120 self.advance(3); 121 let s = self.consts(); 122 ret.push(PatternItem::Search(s)); 123 } else if self.next_is(&[Base::I, Base::I, Base::P]) { 124 self.advance(3); 125 level += 1; 126 ret.push(PatternItem::Open); 127 } else if self.next_is(&[Base::I, Base::I, Base::C]) 128 || self.next_is(&[Base::I, Base::I, Base::F]) 129 { 130 self.advance(3); 131 if level == 0 { 132 return Some(Pattern::new(ret)); 133 } 134 level -= 1; 135 ret.push(PatternItem::Close); 136 } else if self.next_is(&[Base::I, Base::I, Base::I]) { 137 self.advance(3); 138 self.peek_to(7); 139 let mut r = Vec::new(); 140 mem::swap(&mut r, &mut self.peeked); 141 rna.push(r.try_into().unwrap()); 142 self.index += 7; 143 } else { 144 return None; 145 } 146 } 147 } 148 149 pub fn template(&mut self, rna: &mut Vec<Rna>) -> Option<Template> { 150 let mut ret = Vec::new(); 151 loop { 152 if self.next_is(&[Base::C]) { 153 self.advance(1); 154 ret.push(TemplateItem::Base(Base::I)); 155 } else if self.next_is(&[Base::F]) { 156 self.advance(1); 157 ret.push(TemplateItem::Base(Base::C)); 158 } else if self.next_is(&[Base::P]) { 159 self.advance(1); 160 ret.push(TemplateItem::Base(Base::F)); 161 } else if self.next_is(&[Base::I, Base::C]) { 162 self.advance(2); 163 ret.push(TemplateItem::Base(Base::P)); 164 } else if self.next_is(&[Base::I, Base::P]) || self.next_is(&[Base::I, Base::F]) { 165 self.advance(2); 166 let l = self.nat()?; 167 let n = self.nat()?; 168 ret.push(TemplateItem::Ref(n, l)); 169 } else if self.next_is(&[Base::I, Base::I, Base::C]) 170 || self.next_is(&[Base::I, Base::I, Base::F]) 171 { 172 self.advance(3); 173 return Some(Template::new(ret)); 174 } else if self.next_is(&[Base::I, Base::I, Base::P]) { 175 self.advance(3); 176 let n = self.nat()?; 177 ret.push(TemplateItem::Len(n)); 178 } else if self.next_is(&[Base::I, Base::I, Base::I]) { 179 self.advance(3); 180 self.peek_to(7); 181 let mut r = Vec::new(); 182 mem::swap(&mut r, &mut self.peeked); 183 rna.push(r.try_into().unwrap()); 184 self.index += 7; 185 } else { 186 return None; 187 } 188 } 189 } 190} 191 192#[cfg(test)] 193mod tests { 194 use super::*; 195 196 fn dna_from_str(s: &str) -> Vec<Base> { 197 s.chars().filter_map(|c| Base::from_char(c)).collect() 198 } 199 200 #[test] 201 fn test_base() { 202 let dna = dna_from_str("ICFP").into_iter(); 203 let mut parser = Parser::new(dna); 204 assert!(parser.next_is(&[Base::I])); 205 assert!(parser.next_is(&[Base::I, Base::C])); 206 assert!(parser.next_is(&[Base::I, Base::C, Base::F])); 207 assert!(parser.next_is(&[Base::I, Base::C, Base::F, Base::P])); 208 } 209 210 #[test] 211 fn test_nat() { 212 let dna = dna_from_str("CP").into_iter(); 213 let mut parser = Parser::new(dna); 214 assert_eq!(parser.nat(), Some(1)); 215 assert_eq!(parser.index, 2); 216 217 let dna = dna_from_str("ICICP").into_iter(); 218 let mut parser = Parser::new(dna); 219 assert_eq!(parser.nat(), Some(10)); 220 assert_eq!(parser.index, 5); 221 222 let dna = dna_from_str("III").into_iter(); 223 let mut parser = Parser::new(dna); 224 assert_eq!(parser.nat(), None); 225 assert_eq!(parser.index, 3); 226 } 227 228 #[test] 229 fn test_consts() { 230 let dna = dna_from_str("CFPICIIC").into_iter(); 231 let mut parser = Parser::new(dna); 232 assert_eq!(parser.consts(), &[Base::I, Base::C, Base::F, Base::P]); 233 assert_eq!(parser.index, 5); 234 } 235 236 #[test] 237 fn test_pattern() { 238 let mut rna = Vec::new(); 239 240 let dna = dna_from_str("CIIC").into_iter(); 241 let mut parser = Parser::new(dna); 242 assert_eq!( 243 parser.pattern(&mut rna), 244 Some(Pattern::new(vec![PatternItem::Base(Base::I)])) 245 ); 246 assert_eq!(parser.index, 4); 247 248 let dna = dna_from_str("IIPIPICPIICICIIF").into_iter(); 249 let mut parser = Parser::new(dna); 250 assert_eq!( 251 parser.pattern(&mut rna), 252 Some(Pattern::new(vec![ 253 PatternItem::Open, 254 PatternItem::Skip(2), 255 PatternItem::Close, 256 PatternItem::Base(Base::P) 257 ])) 258 ); 259 assert_eq!(parser.index, 16); 260 261 let dna = dna_from_str("IIIPFCICFPIIC").into_iter(); 262 let mut parser = Parser::new(dna); 263 assert_eq!(parser.pattern(&mut rna), Some(Pattern::new(vec![]))); 264 assert_eq!(parser.index, 13); 265 assert_eq!( 266 rna, 267 vec![[ 268 Base::P, 269 Base::F, 270 Base::C, 271 Base::I, 272 Base::C, 273 Base::F, 274 Base::P 275 ]] 276 ); 277 } 278 279 #[test] 280 fn test_template() { 281 let mut rna = Vec::new(); 282 283 let dna = dna_from_str("CFPICIFCPICPIIPIICPIIC").into_iter(); 284 let mut parser = Parser::new(dna); 285 assert_eq!( 286 parser.template(&mut rna), 287 Some(Template::new(vec![ 288 TemplateItem::Base(Base::I), 289 TemplateItem::Base(Base::C), 290 TemplateItem::Base(Base::F), 291 TemplateItem::Base(Base::P), 292 TemplateItem::Ref(2, 1), 293 TemplateItem::Len(4) 294 ])) 295 ); 296 assert_eq!(parser.index, 22); 297 298 let dna = dna_from_str("IIIPFCICFPIIC").into_iter(); 299 let mut parser = Parser::new(dna); 300 assert_eq!(parser.template(&mut rna), Some(Template::new(vec![]))); 301 assert_eq!(parser.index, 13); 302 assert_eq!( 303 rna, 304 vec![[ 305 Base::P, 306 Base::F, 307 Base::C, 308 Base::I, 309 Base::C, 310 Base::F, 311 Base::P 312 ]] 313 ); 314 } 315}