Nora's solution to the challenge.

Don't look at this before you've completed the challenge!

This is not the only correct solution, just one example.
I have notated the solution with comments beginning with NORA
to help explain my reasoning and the purpose of each line.
This commit is contained in:
Leonora Tindall 2021-11-11 12:52:47 -06:00
parent 278043b16a
commit 1cbd2e725a
Signed by: nora
GPG Key ID: 7A8B52EC67E09AAF
1 changed files with 43 additions and 2 deletions

View File

@ -11,6 +11,8 @@ use std::io::Write;
pub struct Parser {
token: &'static [u8],
suffix: &'static [u8],
/// NORA: Records the position in the token across calls to `process`.
pos: usize,
}
impl Parser {
@ -19,7 +21,11 @@ impl Parser {
//
// NOTE: This function signature should stay the same.
pub fn new(token: &'static [u8], suffix: &'static [u8]) -> Self {
Self { token, suffix }
Self {
token,
suffix,
pos: 0,
}
}
/// Write the bytes given in `input` to `output`, plus the bytes in `suffix`
@ -56,7 +62,42 @@ impl Parser {
//
// NOTE: This function signature should stay the same.
pub fn process(&mut self, input: &[u8], output: &mut dyn Write) -> Result<(), std::io::Error> {
output.write_all(input)
// NORA: Create a buffer to work in for just this call.
// We'll write the whole buffer at the end, unconditionally;
// the only question is what's in it.
let mut buffer = Vec::with_capacity(input.len() + self.suffix.len());
// NORA: Look at each byte in the input.
for byte in input {
// NORA: Unconditionally, write that byte into our buffer.
// No requirement calls for losing any bytes.
buffer.push(*byte);
// NORA: Compare the current byte in the input to the current byte
// in the token.
if *byte == self.token[self.pos] {
// NORA: If this byte is a match, progress to the next token byte.
self.pos += 1;
// NORA: If we've reached the end of the token,
// that's a successful match.
if self.pos == self.token.len() {
// NORA: Write the whole suffix into the output buffer.
for suffix_byte in self.suffix {
buffer.push(*suffix_byte);
}
// NORA: And reset to zero, so we can look for a new match.
self.pos = 0;
}
} else {
// NORA: If the current input byte isn't a match for the current
// token byte, we have failed to match the token;
// reset to the beginning.
// This prevents e.g. "oat meal" from matching "oatmeal".
self.pos = 0;
}
}
output.write_all(&buffer)
}
}