Skip to content

Instantly share code, notes, and snippets.

@skeleten
Last active August 29, 2015 14:24
Show Gist options
  • Save skeleten/cc989a2e54a11abc422a to your computer and use it in GitHub Desktop.
Save skeleten/cc989a2e54a11abc422a to your computer and use it in GitHub Desktop.
CONSUBSTANTIATION
WRONGHEADED
UNINTELLIGIBILITY
SUPERGLUE
#![feature(str_char)]
const CHARS: &'static str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
fn main() {
let mut stdin = std::io::stdin();
'main: loop {
let mut input = String::new();
match stdin.read_line(&mut input) {
Ok(s) => {
if s == 0 || input.is_empty() {
println!("empty input..");
break 'main;
} else {
input = input
.to_uppercase()
.trim_matches(' ').to_string()
.trim_matches('\n').to_string()
.trim_matches('\r').to_string();
match balance_word(&input) {
Ok(i) => {
print_result(&input, i);
},
Err(_) => {
println!("{} DOES NOT BALANCE", input);
}
}
}
},
Err(_) => {
break 'main;
},
}
}
}
fn print_result(word: &String, index: usize) {
let lside = word[0..index].to_string();
let middle = word.char_at(index);
let rside = word[index+1..word.len()].to_string();
let val = value_left_of(word, index);
println!("{} {} {} - {}", lside, middle, rside, val);
}
fn balance_word(word: &String) -> Result<usize, ()> {
if word.len() < 3 {
Err(())
} else {
let mut tried = vec_of_value(word.len(), false);
let mut index: usize = word.len() / 2;
while index < word.len() && !tried[index] {
tried[index] = true;
let lvalue = value_left_of(word, index);
let rvalue = value_right_of(word, index);
if lvalue > rvalue {
index -= 1;
} else if rvalue > lvalue {
index += 1;
} else {
return Ok(index);
}
};
if value_left_of(word, index) == value_right_of(word, index) {
Ok(index)
} else {
Err(())
}
}
}
fn vec_of_value<T: Clone>(size: usize, default: T) -> Vec<T> {
let mut vec = Vec::with_capacity(size);
for _ in 0..size {
vec.push(default.clone());
}
vec
}
fn value_left_of(word: &String, index: usize) -> usize {
(0..index)
.map(|i| value_of_char(word.char_at(i)) * diff(i, index))
.fold(0, |a, b| a + b)
}
fn value_right_of(word: &String, index: usize) -> usize {
(index..word.len())
.map(|i| value_of_char(word.char_at(i)) * diff(i, index))
.fold(0, |a, b| a + b)
}
fn value_of_char(c: char) -> usize {
CHARS.chars().position(|p| p == c).unwrap() + 1
}
fn diff(a: usize, b: usize) -> usize {
max(a, b) - min(a, b)
}
fn max(a: usize, b: usize) -> usize {
if a > b {
a
} else {
b
}
}
fn min(a: usize, b: usize) -> usize {
if a > b {
b
} else {
a
}
}
////////////////////////////////////////////////////////////////////////////////
// TESTS //
////////////////////////////////////////////////////////////////////////////////
#[test]
fn test_value_of_char() {
assert_eq!(value_of_char('A'), 1);
assert_eq!(value_of_char('B'), 2);
assert_eq!(value_of_char('Z'), 26);
}
#[test]
fn test_min() {
assert_eq!(min(0, 1), 0);
assert_eq!(min(9, 4), 4);
assert_eq!(min(3, 3), 3);
}
#[test]
fn test_max() {
assert_eq!(max(0, 1), 1);
assert_eq!(max(9, 4), 9);
assert_eq!(max(3, 3), 3);
}
#[test]
fn test_diff() {
assert_eq!(diff(3, 2), 1);
assert_eq!(diff(3, 9), 6);
assert_eq!(diff(5, 5), 0);
}
#[test]
fn test_value_left_of() {
let test_string = "ABCDE".to_string();
assert_eq!(value_left_of(&test_string, 0), 0);
assert_eq!(value_left_of(&test_string, 1), 1);
assert_eq!(value_left_of(&test_string, 2), 4);
assert_eq!(value_left_of(&test_string, 3), 10);
assert_eq!(value_left_of(&test_string, 4), 20);
assert_eq!(value_left_of(&test_string, 5), 35);
}
#[test]
fn test_value_right_of() {
let test_string = "ABCDE".to_string();
assert_eq!(value_right_of(&test_string, 0), 40);
assert_eq!(value_right_of(&test_string, 1), 26);
assert_eq!(value_right_of(&test_string, 2), 14);
assert_eq!(value_right_of(&test_string, 3), 5);
assert_eq!(value_right_of(&test_string, 4), 0);
}
#[test]
fn test_is_balanced() {
let string = "AABAA".to_string();
assert_eq!(is_balanced_at(&string, 2), true);
let string = "ABC".to_string();
assert_eq!(is_balanced_at(&string, 1), false)
}
#[test]
fn test_vec_of_value() {
let vec = vec_of_value(1, false);
for i in 0..1 {
assert_eq!(vec[i], false);
}
let vec = vec_of_value(2, 0);
for i in 0..2 {
assert_eq!(vec[i], 0);
}
}
#[test]
fn test_balance_word() {
let word = "AABAA".to_string();
assert_eq!(balance_word(&word), Ok(2));
let word = "AABC".to_string();
assert_eq!(balance_word(&word), Ok(2));
}
CONSUBST A NTIATION - 456
WRO N GHEADED - 120
UNINTELL I GIBILITY - 521
SUPERGLUE DOES NOT BALANCE
empty input..
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment