Skip to content

Instantly share code, notes, and snippets.

@hellow554
Created December 4, 2019 18:47
Show Gist options
  • Save hellow554/23f7e81ec3ad319a34c9382a2686446f to your computer and use it in GitHub Desktop.
Save hellow554/23f7e81ec3ad319a34c9382a2686446f to your computer and use it in GitHub Desktop.
use std::mem;
use std::ops::Range;
const INPUT: &str = "307237-769058";
struct ExtractConsecutive<'a> {
string: &'a str,
}
impl<'a> Iterator for ExtractConsecutive<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<&'a str> {
let first = self.string.chars().next()?;
for (i, c) in self.string.char_indices() {
if c != first {
let (head, tail) = self.string.split_at(i);
self.string = tail;
return Some(head);
}
}
Some(mem::replace(&mut self.string, ""))
}
}
fn is_increasing(x: &str) -> bool {
x.as_bytes().windows(2).all(|c| c[0] <= c[1])
}
fn is_valid(num: u32, predicate: impl Fn(&str) -> bool) -> bool {
let num_str = num.to_string();
let mut ec = ExtractConsecutive { string: &num_str };
ec.any(predicate) && is_increasing(&num_str)
}
fn solve_a(range: Range<u32>) -> usize {
range.filter(|n| is_valid(*n, |x| x.len() > 1)).count()
}
fn solve_b(range: Range<u32>) -> usize {
range.filter(|n| is_valid(*n, |x| x.len() == 2)).count()
}
fn parse(s: &str) -> Range<u32> {
let mut splitter = s.split('-');
let start = splitter.next().unwrap();
let end = splitter.next().unwrap();
assert!(splitter.next().is_none());
start.parse().unwrap()..end.parse().unwrap()
}
fn main() {
let range = parse(INPUT);
println!("A: {}", solve_a(range.clone()));
println!("B: {}", solve_b(range));
}
#[test]
fn test_extract() {
let ec = ExtractConsecutive { string: "1122334444" };
assert_eq!(ec.collect::<Vec<_>>(), vec!["11", "22", "33", "4444"]);
let ec = ExtractConsecutive { string: "1" };
assert_eq!(ec.collect::<Vec<_>>(), vec!["1"])
}
#[test]
fn test_validity_a() {
let num = 111111;
assert_eq!(solve_a(num..1 + num), 1);
let num = 123455;
assert_eq!(solve_a(num..1 + num), 1);
let num = 223450;
assert_eq!(solve_a(num..1 + num), 0);
let num = 123789;
assert_eq!(solve_a(num..1 + num), 0);
}
#[test]
fn test_validity_b() {
let num = 112233;
assert_eq!(solve_b(num..1 + num), 1);
let num = 111122;
assert_eq!(solve_b(num..1 + num), 1);
let num = 123444;
assert_eq!(solve_b(num..1 + num), 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment