Skip to content

Instantly share code, notes, and snippets.

@anlumo
Created September 28, 2023 22:25
Show Gist options
  • Save anlumo/bf62a960ede9cd858abb7e770a121f35 to your computer and use it in GitHub Desktop.
Save anlumo/bf62a960ede9cd858abb7e770a121f35 to your computer and use it in GitHub Desktop.
Rust Vienna Dojo 2023-09-28
#![warn(clippy::pedantic)]
#![warn(clippy::all)]
/// # Panics
/// when negative value is passed
#[must_use]
pub fn add(numbers: &str) -> usize {
let (seperators, content) = if let Some(line) = numbers.strip_prefix("//") {
let (seperators_str, content_str) = line.split_once('\n').unwrap();
if seperators_str.starts_with('[') {
let seperators: Vec<_> = seperators_str.split([']', '[']).collect();
(seperators, content_str)
} else {
let seperators = seperators_str
.split("")
.filter(|separator| !separator.is_empty())
.collect::<Vec<_>>();
(seperators, content_str)
}
} else {
(Vec::from([",", "\n"]), numbers)
};
let mut negative_numbers = Vec::new();
let mut content = content.to_string();
for sep in seperators {
if !sep.is_empty() {
content = content.replace(sep, ",");
}
}
let res = content
.split_terminator(',')
.map(|content_item| {
if content_item.starts_with('-') {
negative_numbers.push(content_item);
0
} else {
content_item.parse::<usize>().unwrap()
}
})
.filter(|&n| n <= 1000)
.sum();
/*
let (res, negative_numbers): (Vec<_>, _) = content
.split_terminator(',')
.map(|content_item| content_item.parse::<isize>().unwrap())
.filter(|&n| n <= 1000)
.partition(|&i| i >= 0);
*/
if negative_numbers.is_empty() {
res
} else {
panic!("negatives not allowed {}", negative_numbers.join(" "));
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_empty_string() {
assert_eq!(add(""), 0);
}
#[test]
fn test_single_integers() {
for i in 0..100 {
assert_eq!(add(&i.to_string()), i);
}
}
#[test]
fn test_two_integers() {
for i in 0..100 {
for j in 0..100 {
assert_eq!(add(&format!("{i},{j}")), i + j);
}
}
}
#[test]
fn test_many_integers() {
assert_eq!(add("1,2,3,4"), 10);
}
#[test]
fn test_n_integers() {
for i in 1..100 {
let nums = (0..i).map(|x| x.to_string()).collect::<Vec<_>>().join(",");
assert_eq!(add(&nums), (0..i).sum());
}
}
#[test]
fn test_many_integers_with_newlines() {
assert_eq!(add("1\n2\n3,4"), 10);
}
#[test]
fn test_custom_seperators() {
assert_eq!(add("//x\n1x2"), 3);
}
#[test]
#[should_panic(expected = "negatives not allowed")]
fn test_negatives() {
let _ = add("-1");
}
#[test]
#[should_panic(expected = "negatives not allowed -1 -2")]
fn test_multiple_negatives() {
let _ = add("-1,-2");
}
#[test]
fn test_large_number() {
assert_eq!(add("1,1001"), 1);
}
#[test]
fn test_arbitrary_delimiter() {
assert_eq!(add("//[***]\n1***2***3"), 6);
}
#[test]
fn test_multiple_single_delimiters() {
assert_eq!(add("//[*][x]\n1*2x3"), 6);
}
#[test]
fn test_multiple_digit_delimiters() {
assert_eq!(add("//[1][234]\n6234518"), 19);
}
#[test]
fn test_equal_digit_delimiters() {
assert_eq!(add("//[33]\n1331"), 2);
}
#[test]
fn test_multiple_arbitrary_delimiters() {
assert_eq!(add("//[***][xyz]\n1***2xyz3"), 6);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment