Rust: codewars的prize draw算法
2017-09-24 16:55
671 查看
这道codewars的prize draw算法题,很有意思,能很好看看rust与众不同的用法。
一、prize draw
资料来源:https://www.codewars.com/kata/prize-draw/solutions/rust
1、26个字母字符按字母表的顺序分别有相应的值,比如A为1,B为2…..,一直到Z:26; 其中大小写不区分。
2、对一个由26个字母字符构成的字符串,字符串对应的值(value)由两部分决定:
(1)字母串的值(val)先由每个字母字符的值相加而得,再加上字符串本身的长度(length)得到字符串值。
(2)字母串最终值由字符串值(val)和赋给的权重(weight)相乘而得。
3、举例
names: COLIN,AMANDBA,AMANDAB,CAROL,PauL,JOSEPH
weights: [1, 4, 4, 5, 2, 1]
对于PauL:
val: = length of Paul + 16 + 1 + 21 + 12 = 4 + 50 -> 54 。
weight: 2;
value = 54 * 2 = 108.
4、对相关的字符对应的value进行降序排列;
5、如果两个字符的value相等,那么,则按字符串的字母顺序进行降序排序:
(1)’a’>’b’>’c’>’d’…….;
(2)如果第一个字母相同,就比第二个字母…..
即,若对于两个都是108的value的字符串进行降序排列的话,就应把第一个字母是’a’的排在是’b’的前面(值大)。
6、给定一个可用”,”切分的字符长串(st),以及对应切分后的字符串的相关weight,请返回按降序排列中第n位的字符。
函数格式:
rank(st: &str, we: Vec, n: usize) -> &str{//
}
其中参数:
st: 如”COLIN,AMANDBA,AMANDAB,CAROL,PauL,JOSEPH” //可以按”,”切分。
we: 如[1, 4, 4, 5, 2, 1]
n: 4
7、其它说明:
若st为空,则返回 “No participants”.
若 n> is 切分后字符串的数量,则返回 “Not enough participants”.
二、我的解法
三、其它精彩的解法
1、
2、
3、
4、
6、
一、prize draw
资料来源:https://www.codewars.com/kata/prize-draw/solutions/rust
1、26个字母字符按字母表的顺序分别有相应的值,比如A为1,B为2…..,一直到Z:26; 其中大小写不区分。
2、对一个由26个字母字符构成的字符串,字符串对应的值(value)由两部分决定:
(1)字母串的值(val)先由每个字母字符的值相加而得,再加上字符串本身的长度(length)得到字符串值。
(2)字母串最终值由字符串值(val)和赋给的权重(weight)相乘而得。
3、举例
names: COLIN,AMANDBA,AMANDAB,CAROL,PauL,JOSEPH
weights: [1, 4, 4, 5, 2, 1]
对于PauL:
val: = length of Paul + 16 + 1 + 21 + 12 = 4 + 50 -> 54 。
weight: 2;
value = 54 * 2 = 108.
4、对相关的字符对应的value进行降序排列;
5、如果两个字符的value相等,那么,则按字符串的字母顺序进行降序排序:
(1)’a’>’b’>’c’>’d’…….;
(2)如果第一个字母相同,就比第二个字母…..
即,若对于两个都是108的value的字符串进行降序排列的话,就应把第一个字母是’a’的排在是’b’的前面(值大)。
6、给定一个可用”,”切分的字符长串(st),以及对应切分后的字符串的相关weight,请返回按降序排列中第n位的字符。
函数格式:
rank(st: &str, we: Vec, n: usize) -> &str{//
}
其中参数:
st: 如”COLIN,AMANDBA,AMANDAB,CAROL,PauL,JOSEPH” //可以按”,”切分。
we: 如[1, 4, 4, 5, 2, 1]
n: 4
fn main() { let st = SystemTime::now(); let dd = rank("Addison,Jayden,Sofia,Michael,Andrew,Lily,Benjamin", vec![4, 2, 1, 4, 3, 1, 2], 4); //返回=>Benjamin println!("dd,rank:{}", dd); println!("_sort:{:?} ", sort_str(vec!["aaa", "bbb", "abc"])); let d1 = rank("Elijah,Chloe,Elizabeth,Matthew,Natalie,Jayden", vec![1, 3, 5, 5, 3, 6], 2); //返回=> "Matthew"); println!("d1=>{:?}", d1); let d2 = rank("Aubrey,Olivai,Abigail,Chloe,Andrew,Elizabeth", vec![3, 1, 4, 4, 3, 2], 4); //返回=>"Abigail"); println!("d2 :{}", d2); let d3 = rank("Lagon,Lily", vec![1, 5], 2); // 返回=>"Lagon"); println!("d3:{}", d3); }
7、其它说明:
若st为空,则返回 “No participants”.
若 n> is 切分后字符串的数量,则返回 “Not enough participants”.
二、我的解法
use std::collections::HashMap; fn rank(st: &str, we: Vec<i32>, n: usize) -> &str { if n > st.clone().len() { return "No participants"; } let strs: Vec<&str> = st.split(',').collect(); if n > strs.clone().len() { return "Not enough participants"; } let scores: Vec<i32> = strs.clone().iter().map(|x| total(x)).collect(); let scores: Vec<i32> = scores.into_iter() .zip(we.clone().into_iter()) .collect::<Vec<_>>() .iter() .map(|x| x.0 * x.1) .collect(); let mut copy_scores = scores.clone(); copy_scores.sort_by(|a, b| b.cmp(a)); let name_scores: HashMap<&str, i32> = strs.clone().into_iter().zip(scores.clone().into_iter()).collect(); let len = copy_scores.len(); let copy_strs = strs.clone(); let mut sort_names: Vec<&str> = Vec::new(); for i in 0..len { let score_i = ©_scores[i]; if i > 0 { if score_i == ©_scores[i - 1] { continue; } } let score_i_names: Vec<&str> = copy_strs.clone() .into_iter() .filter(|x| name_scores.get(x).unwrap() == score_i) .collect(); let score_sorted = sort_str(score_i_names); for sc in score_sorted { sort_names.push(sc); } } &sort_names[n - 1] } fn total(name: &str) -> i32 { let data: HashMap<char, i32> = "abcdefghijklmnopqrstuvwxyz".chars().enumerate().map(|(x, y)| (y, x as i32 + 1)).collect(); name.to_lowercase().chars().fold(0, |total, x| total + data.get(&x).unwrap()) + name.len() as i32 } fn sort_str<'a>(names: Vec<&'a str>) -> Vec<&'a str> { let n: usize = names.len(); let mut _names = names.clone(); for i in 0..n - 1 { for j in i + 1..n { let (na, _) = _sort_by(names.clone().get(i).unwrap(), names.clone().get(j).unwrap(), 0); if &na != names.clone().get(i).unwrap() { _names = _sort(_names, i, j); } } } _names } fn _sort<'a>(names: Vec<&'a str>, n: usize, m: usize) -> Vec<&'a str> { let mut _names = names; let nval: &'a str = _names.clone().get(n).unwrap(); let mval: &'a str = _names.clone().get(m).unwrap(); if let Some(elem) = _names.get_mut(n) { *elem = mval; } if let Some(elem) = _names.get_mut(m) { *elem = nval; } _names } fn _sort_by<'a>(name1: &'a str, name2: &'a str, n: usize) -> (&'a str, &'a str) { let n1 = name1.len(); let n2 = name2.len(); let min_n = match n1 < n2 { true => n1, _ => n2, }; if n > min_n - 1 { return (&name1, &name2); } else { if &name1.chars().nth(n) < &name2.chars().nth(n) { (&name1, &name2) } else if &name1.chars().nth(n) == &name2.chars().nth(n) { if n == min_n { return (&name1, &name2); } _sort_by(name1, name2, n + 1) } else { (&name2, &name1) } } }
三、其它精彩的解法
1、
fn letter_values(value: &str) -> i32 { let charactor_total: i32 = value .chars() .map(|x| x.to_digit(36).unwrap_or(0) as i32) .map(|x| x - 9) .sum(); charactor_total + (value.len() as i32) } fn rank_names(st: &str, we: Vec<i32>) -> Vec<(i32, &str)> { let names = st.split(','); let mut raffles = names .clone() .into_iter() .map(|x| String::from(x)) .zip(we) .map(|(left, right)| letter_values(&left) * (right)) .zip(names) .collect::<Vec<(i32, &str)>>(); raffles.sort_by(|&(_, a), &(_, b)| a.cmp(&b)); raffles.sort_by(|&(a, _), &(b, _)| b.cmp(&a)); raffles } fn rank(st: &str, we: Vec<i32>, n: usize) -> &str { let raffles = rank_names(&st, we); if st.len() == 0 { return "No participants"; } let (_, winning_name) = raffles.into_iter().nth(n - 1).unwrap_or((0, "Not enough participants")); &winning_name }
2、
const A_BYTE: u16 = 'a' as u16; fn rank(st: &str, we: Vec<i32>, n: usize) -> &str { if st.is_empty() { return "No participants"; } let participants = st.split(',').collect::<Vec<_>>(); if n > participants.len() { return "Not enough participants"; } let mut winning_numbers_vec = participants.into_iter().zip(we).map(winning_number).collect::<Vec<_>>(); let winning_numbers = winning_numbers_vec.as_mut_slice(); winning_numbers.sort(); let (_, name) = winning_numbers[n-1]; name } fn winning_number(pair: (&str,i32)) -> (i32,&str) { let (name, weight) = pair; let n = name.to_lowercase() //Case insensitive .into_bytes() //ASCII code .into_iter().map(|byte| byte as u16 - A_BYTE + 1) //Alphabet order .fold(name.len() as u16, |n, value| n + value); //Sum values (n as i32 * -weight, name) }
3、
fn rank(st: &str, we: Vec<i32>, n: usize) -> &str { if st.len() == 0 { return "No participants"; } let names = st .split(',') .collect::<Vec<&str>>() ; if n > names.len() { return "Not enough participants"; } let mut sorted = names .iter() .map(|name| name .to_lowercase() .bytes() .map(|byte| byte as usize - 96) .collect::<Vec<usize>>() ) .map(|vector| vector.len() + vector.iter().sum::<usize>()) .zip(we) .map(|(number, weight)| number * weight as usize) .zip(names.clone()) .collect::<Vec<(usize, &str)>>() ; sorted.sort_by_key(|&(_, n)| n.to_lowercase()); sorted.sort_by_key(|&(w, _)| -(w as isize)); sorted[n-1].1 }
4、
fn word_rank(w: &str) -> usize { w.len() + w.to_lowercase().chars().map(|c| c as usize - 96).sum::<usize>() } fn rank(st: &str, we: Vec<i32>, n: usize) -> &str { let ws: Vec<&str> = st.split(',').filter(|s| s.len() > 0).collect(); if ws.len() == 0 { return "No participants"; } if n > ws.len() { return "Not enough participants"; } let vs: Vec<_> = ws.iter().map(|w| word_rank(w)) .zip(we.iter()).map(|(a, &b)| a * (b as usize)).collect(); let mut rk: Vec<_> = (0..ws.len()).collect(); // rk.sort_by(|&i, &j| vs[j].cmp(&vs[i]).then(ws[i].cmp(ws[j]))); rk.sort_by(|&i, &j| { let r = vs[j].cmp(&vs[i]); if r == std::cmp::Ordering::Equal {ws[i].cmp(ws[j])} else {r} }); ws[rk[n-1]] }
6、
static RANKS: &'static str = "abcdefghijklmnopqrstuvwxyz"; fn rank(st: &str, we: Vec<i32>, n: usize) -> &str { if st.is_empty() { return "No participants"; } let names: Vec<&str> = st.split(",").collect(); if n > names.len() { return "Not enough participants"; } let mut name_ranks: Vec<(i32, &str)> = names.iter().zip(we).map(|(&name, weight)| { let winning_number = weight * name.to_lowercase().chars().fold(name.len(), |sum, x| sum + RANKS.chars().position(|y| y == x).unwrap() + 1) as i32; (-winning_number, name) }).collect(); name_ranks.sort(); name_ranks[n-1].1 }
相关文章推荐
- Rust: codewars 的Duplicate Encoder
- Rust: codewars的Bleatrix Trotter
- Rust : codewars的up AND down 算法
- Rust: codewars 的Count of positives / sum of negatives
- Rust : codewars的Product of consecutive Fib numbers
- Rust: codewars的Roman Numerals Encoder
- Rust: codewars的Sum by Factors
- Rust: codewars的DNA to RNA Conversion
- Rust: codewars的Highest and Lowest
- Rust: codewars的Simple Substitution Cipher Helper算法题、N种不简单的解法集
- Rust: codewars的Molecule to atoms
- Rust : codewars的Sum of Pairs
- Rust: codewars的primes-in-numbers
- If I rest,I rust。
- Rust runtime error: Illegal instruction: 4
- CodeWars——js
- Rust语法之原生数据类型(一)
- Rust基础笔记之浅谈References and Borrowing
- [CodeWars][JS]如何判断给定的数字是否整数
- Rust用组合实现java中的继承重写