This Codewars prize draw algorithm problem, very interesting, can be very good to see rust unusual usage.
First, Prize draw
Data Source: Https://www.codewars.com/kata/prize-draw/solutions/rust
The 1, 26 alphabetic characters have corresponding values in alphabetical order, such as a for 1,b 2 ..., all the time until z:26, where the case is case-insensitive.
2, for a 26-letter character string, the string corresponding to the value (value) is determined by two parts:
(1) The value of the alphabetic string (val) is first added by the value of each alphabetic character, plus the length of the string itself to get the string value.
(2) The end value of the alphabetic string is multiplied by the string value (val) and the assigned weight (weight).
3. Examples
Names:colin,amandba,amandab,carol,paul,joseph
Weights: [1, 4, 4, 5, 2, 1]
For Paul:
Val: = length of Paul + + 1 + + = 4 +-> 54.
Weight:2;
Value = 54 * 2 = 108.
4. The corresponding value of the relevant characters is sorted in descending order;
5, if the value of the two characters is equal, then the order is sorted alphabetically by string:
(1) ' A ' > ' B ' > ' C ' > ' d ' ...;
(2) If the first letter is the same, it is more than the second letter ...
That is, if a string of two 108 values is sorted in descending order, the first letter is ' a ' in front of ' B ' (the value is large).
6, given a usable "," split character long string (ST), and corresponding to the split string of related weight, please return in descending order of the nth digit character.
function format:
Rank (ST: &str, We:vec, n:usize)-> &str{//
}
Where parameters:
ST: such as "colin,amandba,amandab,carol,paul,joseph"//Can Press "," segmentation.
We: such as [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; Return to =>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); Return to => "Matthew");
println! ("d1=>{:?}", D1);
Let D2 = Rank ("Aubrey,olivai,abigail,chloe,andrew,elizabeth",
vec![ 3, 1, 4, 4, 3, 2],
4); Return to => "Abigail");
println! ("D2: {}", D2);
Let D3 = Rank ("lagon,lily", vec![ 1, 5], 2); Return to => "Lagon");
println! ("d3:{}", D3);
}
7, Other notes:
If St is empty, return "No participants".
Returns "Not enough participants" if the number of strings after n> is Shard.
Second, my solution
Use Std::collections::hashmap; fn Rank (ST: &str, We:vec<i32>, n:usize)-> &str {if n > St.clone (). Len () {return "No p
Articipants ";
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-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 (). Filte
R (|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-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)-> ' 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 (&A
Mp;name1, &name2); } _sort_by (name1, name2, n + 1)} else {(&name2, &name1)}}}
Third, the other wonderful solution
1,
fn Letter_values (value: &str)-> i32 {Let charactor_total:i32 = value. Chars (). Map (|x| x.to_
Digit. 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. F Old (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"; c2/>} 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.SPL It (', '). 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}