This commit is contained in:
2016-12-07 09:46:45 +01:00
parent 5eee81e7b8
commit e6b66a4049
4 changed files with 2243 additions and 0 deletions

233
2016/07/src/main.rs Normal file
View File

@@ -0,0 +1,233 @@
use std::collections::{VecDeque, HashSet};
use std::io::{self, BufRead};
struct TLSBuffer {
vec: VecDeque<char>
}
impl TLSBuffer {
fn new() -> Self {
TLSBuffer {
vec: VecDeque::with_capacity(4)
}
}
fn push(&mut self, value: char) {
self.vec.push_back(value);
while self.vec.len() > 4 {
self.vec.pop_front();
}
}
fn clear(&mut self) {
self.vec.clear();
}
fn is_abba(&self) -> bool {
self.vec.len() == 4
&& self.vec[0] != self.vec[1]
&& self.vec[0] == self.vec[3]
&& self.vec[1] == self.vec[2]
}
}
struct SSLBuffer {
vec: VecDeque<char>
}
impl SSLBuffer {
fn new() -> Self {
SSLBuffer {
vec: VecDeque::with_capacity(3)
}
}
fn push(&mut self, value: char) {
self.vec.push_back(value);
while self.vec.len() > 3 {
self.vec.pop_front();
}
}
fn clear(&mut self) {
self.vec.clear();
}
fn is_aba(&self) -> bool {
self.vec.len() == 3
&& self.vec[0] != self.vec[1]
&& self.vec[0] == self.vec[2]
}
fn get_aba(&self) -> String {
format!("{}{}{}", self.vec[0], self.vec[1], self.vec[0])
}
fn get_bab(&self) -> String {
format!("{}{}{}", self.vec[1], self.vec[0], self.vec[1])
}
}
enum MachineState {
Default,
HypernetSequence
}
fn supports_tls(input: &str) -> bool {
let mut state = MachineState::Default;
let mut buffer = TLSBuffer::new();
let mut supports_tls = false;
for ch in input.chars() {
state = match (ch, state) {
('[', MachineState::Default) => {
buffer.clear();
MachineState::HypernetSequence
}
(ch, MachineState::Default) => {
buffer.push(ch);
if buffer.is_abba() {
supports_tls = true;
}
MachineState::Default
}
(']', MachineState::HypernetSequence) => {
buffer.clear();
MachineState::Default
}
(ch, MachineState::HypernetSequence) => {
buffer.push(ch);
if buffer.is_abba() {
return false;
}
MachineState::HypernetSequence
}
}
}
supports_tls
}
fn supports_ssl(input: &str) -> bool {
let mut state = MachineState::Default;
let mut buffer = SSLBuffer::new();
let mut aba = HashSet::new();
let mut bab = HashSet::new();
for ch in input.chars() {
state = match (ch, state) {
('[', MachineState::Default) => {
buffer.clear();
MachineState::HypernetSequence
}
(ch, MachineState::Default) => {
buffer.push(ch);
if buffer.is_aba() {
aba.insert(buffer.get_aba());
}
MachineState::Default
}
(']', MachineState::HypernetSequence) => {
buffer.clear();
MachineState::Default
}
(ch, MachineState::HypernetSequence) => {
buffer.push(ch);
if buffer.is_aba() {
bab.insert(buffer.get_bab());
}
MachineState::HypernetSequence
}
}
}
aba.intersection(&bab).count() > 0
}
fn main() {
let stdin = io::stdin();
let lines = stdin.lock().lines()
.filter_map(|line| line.ok())
.collect::<Vec<_>>();
let count_tls = lines.iter()
.filter(|line| supports_tls(&line))
.count();
let count_ssl = lines.iter()
.filter(|line| supports_ssl(&line))
.count();
println!("count_tls={}", count_tls);
println!("count_ssl={}", count_ssl);
}
#[cfg(test)]
mod tests {
use super::{supports_tls, supports_ssl};
#[test]
fn example_01() {
assert_eq!(true, supports_tls("abba[mnop]qrst"));
}
#[test]
fn example_02() {
assert_eq!(false, supports_tls("abcd[bddb]xyyx"));
}
#[test]
fn example_03() {
assert_eq!(false, supports_tls("aaaa[qwer]tyui"));
}
#[test]
fn example_04() {
assert_eq!(true, supports_tls("ioxxoj[asdfgh]zxcvbn"));
}
#[test]
fn example_05() {
assert_eq!(true, supports_ssl("aba[bab]xyz"));
}
#[test]
fn example_06() {
assert_eq!(false, supports_ssl("xyx[xyx]xyx"));
}
#[test]
fn example_07() {
assert_eq!(true, supports_ssl("aaa[kek]eke"));
}
#[test]
fn example_08() {
assert_eq!(true, supports_ssl("zazbz[bzb]cdb"));
}
}