trackler 2.2.1.179 → 2.2.1.180
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/yacht/description.md +14 -13
- data/tracks/ballerina/config.json +1 -0
- data/tracks/coffeescript/config.json +138 -41
- data/tracks/coffeescript/docs/ABOUT.md +3 -7
- data/tracks/coq/config.json +1 -0
- data/tracks/d/config.json +1 -0
- data/tracks/dart/config.json +1 -0
- data/tracks/elixir/config.json +17 -16
- data/tracks/elixir/docs/ABOUT.md +10 -2
- data/tracks/fortran/config.json +1 -0
- data/tracks/gnu-apl/config.json +1 -0
- data/tracks/go/config.json +13 -0
- data/tracks/go/exercises/list-ops/README.md +27 -0
- data/tracks/go/exercises/list-ops/example.go +99 -0
- data/tracks/go/exercises/list-ops/listops_test.go +291 -0
- data/tracks/groovy/config.json +1 -0
- data/tracks/haxe/config.json +1 -0
- data/tracks/perl5/exercises/leap/.meta/exercise-data.yaml +3 -5
- data/tracks/perl5/exercises/leap/.meta/solutions/Leap.pm +2 -4
- data/tracks/perl5/exercises/leap/Leap.pm +1 -1
- data/tracks/perl5/exercises/leap/leap.t +2 -2
- data/tracks/php/config.json +1 -0
- data/tracks/plsql/config.json +1 -0
- data/tracks/pony/config.json +1 -0
- data/tracks/purescript/config.json +1 -0
- data/tracks/reasonml/config/exercise_readme.go.tmpl +18 -2
- data/tracks/reasonml/exercises/anagram/README.md +15 -4
- data/tracks/reasonml/exercises/armstrong-numbers/README.md +3 -4
- data/tracks/reasonml/exercises/binary-search/README.md +14 -7
- data/tracks/reasonml/exercises/bob/README.md +14 -6
- data/tracks/reasonml/exercises/change/README.md +2 -4
- data/tracks/reasonml/exercises/hello-world/README.md +2 -3
- data/tracks/reasonml/exercises/isogram/README.md +4 -6
- data/tracks/reasonml/exercises/leap/README.md +14 -4
- data/tracks/reasonml/exercises/pangram/README.md +13 -3
- data/tracks/reasonml/exercises/phone-number/README.md +15 -7
- data/tracks/reasonml/exercises/raindrops/README.md +14 -7
- data/tracks/reasonml/exercises/rna-transcription/README.md +13 -3
- data/tracks/reasonml/exercises/roman-numerals/README.md +4 -8
- data/tracks/reasonml/exercises/run-length-encoding/README.md +14 -7
- data/tracks/reasonml/exercises/space-age/README.md +13 -3
- data/tracks/reasonml/exercises/word-count/README.md +18 -8
- data/tracks/rust/.travis.yml +1 -0
- data/tracks/rust/_test/check-exercises-for-authors.sh +10 -0
- data/tracks/rust/bin/format_exercises +2 -0
- data/tracks/rust/exercises/accumulate/Cargo.toml +0 -1
- data/tracks/rust/exercises/accumulate/example.rs +4 -1
- data/tracks/rust/exercises/acronym/example.rs +6 -5
- data/tracks/rust/exercises/acronym/tests/acronym.rs +1 -1
- data/tracks/rust/exercises/all-your-base/example.rs +8 -2
- data/tracks/rust/exercises/allergies/example.rs +28 -6
- data/tracks/rust/exercises/alphametics/example.rs +18 -10
- data/tracks/rust/exercises/anagram/example.rs +8 -4
- data/tracks/rust/exercises/atbash-cipher/example.rs +15 -15
- data/tracks/rust/exercises/beer-song/example.rs +18 -12
- data/tracks/rust/exercises/binary-search/Cargo.toml +0 -1
- data/tracks/rust/exercises/binary-search/example.rs +3 -4
- data/tracks/rust/exercises/bob/example.rs +11 -5
- data/tracks/rust/exercises/book-store/Cargo-example.toml +0 -1
- data/tracks/rust/exercises/book-store/Cargo.toml +0 -1
- data/tracks/rust/exercises/book-store/example.rs +15 -19
- data/tracks/rust/exercises/bowling/example.rs +3 -1
- data/tracks/rust/exercises/bracket-push/example.rs +7 -2
- data/tracks/rust/exercises/circular-buffer/example.rs +1 -1
- data/tracks/rust/exercises/clock/.meta/ALLOWED_TO_NOT_COMPILE +3 -0
- data/tracks/rust/exercises/clock/Cargo.toml +0 -1
- data/tracks/rust/exercises/clock/example.rs +5 -3
- data/tracks/rust/exercises/clock/src/lib.rs +14 -0
- data/tracks/rust/exercises/collatz-conjecture/example.rs +2 -2
- data/tracks/rust/exercises/crypto-square/Cargo-example.toml +0 -1
- data/tracks/rust/exercises/crypto-square/Cargo.toml +0 -1
- data/tracks/rust/exercises/custom-set/example.rs +17 -15
- data/tracks/rust/exercises/decimal/Cargo-example.toml +0 -1
- data/tracks/rust/exercises/decimal/Cargo.toml +0 -1
- data/tracks/rust/exercises/decimal/example.rs +5 -5
- data/tracks/rust/exercises/diamond/Cargo.toml +0 -1
- data/tracks/rust/exercises/difference-of-squares/example.rs +1 -1
- data/tracks/rust/exercises/dominoes/example.rs +20 -19
- data/tracks/rust/exercises/etl/example.rs +4 -3
- data/tracks/rust/exercises/forth/example.rs +29 -45
- data/tracks/rust/exercises/grade-school/example.rs +4 -2
- data/tracks/rust/exercises/hexadecimal/example.rs +2 -4
- data/tracks/rust/exercises/isbn-verifier/example.rs +5 -6
- data/tracks/rust/exercises/isbn-verifier/tests/isbn-verifier.rs +12 -0
- data/tracks/rust/exercises/isogram/example.rs +9 -3
- data/tracks/rust/exercises/largest-series-product/example.rs +2 -1
- data/tracks/rust/exercises/luhn-from/example.rs +3 -1
- data/tracks/rust/exercises/luhn/example.rs +5 -3
- data/tracks/rust/exercises/macros/Cargo.toml +0 -1
- data/tracks/rust/exercises/nth-prime/Cargo.toml +0 -1
- data/tracks/rust/exercises/nth-prime/example.rs +6 -6
- data/tracks/rust/exercises/nucleotide-codons/Cargo.toml +0 -1
- data/tracks/rust/exercises/nucleotide-codons/example.rs +23 -17
- data/tracks/rust/exercises/nucleotide-count/example.rs +15 -5
- data/tracks/rust/exercises/nucleotide-count/src/lib.rs +15 -0
- data/tracks/rust/exercises/nucleotide-count/tests/nucleotide-count.rs +3 -3
- data/tracks/rust/exercises/palindrome-products/Cargo.toml +0 -1
- data/tracks/rust/exercises/pangram/example.rs +6 -6
- data/tracks/rust/exercises/parallel-letter-frequency/example.rs +7 -4
- data/tracks/rust/exercises/pascals-triangle/example.rs +6 -2
- data/tracks/rust/exercises/perfect-numbers/example.rs +2 -2
- data/tracks/rust/exercises/phone-number/example.rs +11 -15
- data/tracks/rust/exercises/pig-latin/Cargo-example.toml +0 -1
- data/tracks/rust/exercises/pig-latin/Cargo.toml +0 -1
- data/tracks/rust/exercises/pig-latin/example.rs +6 -2
- data/tracks/rust/exercises/poker/Cargo-example.toml +0 -1
- data/tracks/rust/exercises/poker/Cargo.toml +0 -1
- data/tracks/rust/exercises/poker/example.rs +9 -8
- data/tracks/rust/exercises/prime-factors/Cargo.toml +0 -1
- data/tracks/rust/exercises/prime-factors/example.rs +1 -1
- data/tracks/rust/exercises/protein-translation/Cargo.toml +0 -1
- data/tracks/rust/exercises/protein-translation/example.rs +6 -5
- data/tracks/rust/exercises/proverb/Cargo.toml +0 -1
- data/tracks/rust/exercises/proverb/example.rs +0 -1
- data/tracks/rust/exercises/pythagorean-triplet/Cargo.toml +0 -1
- data/tracks/rust/exercises/pythagorean-triplet/example.rs +3 -3
- data/tracks/rust/exercises/queen-attack/example.rs +3 -3
- data/tracks/rust/exercises/react/example.rs +61 -29
- data/tracks/rust/exercises/reverse-string/Cargo.toml +0 -1
- data/tracks/rust/exercises/rna-transcription/example.rs +17 -9
- data/tracks/rust/exercises/robot-name/example.rs +4 -3
- data/tracks/rust/exercises/robot-simulator/example.rs +5 -2
- data/tracks/rust/exercises/roman-numerals/example.rs +15 -14
- data/tracks/rust/exercises/rotational-cipher/Cargo.toml +0 -1
- data/tracks/rust/exercises/rotational-cipher/example.rs +10 -14
- data/tracks/rust/exercises/rotational-cipher/src/lib.rs +7 -1
- data/tracks/rust/exercises/run-length-encoding/Cargo.toml +0 -1
- data/tracks/rust/exercises/run-length-encoding/example.rs +34 -29
- data/tracks/rust/exercises/saddle-points/example.rs +0 -1
- data/tracks/rust/exercises/say/Cargo.toml +0 -1
- data/tracks/rust/exercises/say/example.rs +34 -8
- data/tracks/rust/exercises/series/example.rs +6 -8
- data/tracks/rust/exercises/simple-linked-list/example.rs +0 -2
- data/tracks/rust/exercises/spiral-matrix/example.rs +0 -1
- data/tracks/rust/exercises/tournament/example.rs +33 -20
- data/tracks/rust/exercises/triangle/example.rs +1 -1
- data/tracks/rust/exercises/two-bucket/example.rs +2 -6
- data/tracks/rust/exercises/two-fer/example.rs +3 -3
- data/tracks/rust/exercises/variable-length-quantity/example.rs +2 -3
- data/tracks/rust/exercises/word-count/example.rs +4 -1
- data/tracks/rust/exercises/wordy/example.rs +10 -4
- metadata +7 -2
@@ -1,5 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
1
|
/// The possible nucleotides in DNA and RNA
|
4
2
|
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
|
5
3
|
pub enum Nucleotide {
|
@@ -7,7 +5,7 @@ pub enum Nucleotide {
|
|
7
5
|
Cytosine,
|
8
6
|
Guanine,
|
9
7
|
Thymine,
|
10
|
-
Uracil
|
8
|
+
Uracil,
|
11
9
|
}
|
12
10
|
|
13
11
|
impl Nucleotide {
|
@@ -19,7 +17,9 @@ impl Nucleotide {
|
|
19
17
|
'G' => Nucleotide::Guanine,
|
20
18
|
'T' => Nucleotide::Thymine,
|
21
19
|
'U' => Nucleotide::Uracil,
|
22
|
-
_ => {
|
20
|
+
_ => {
|
21
|
+
return None;
|
22
|
+
}
|
23
23
|
})
|
24
24
|
}
|
25
25
|
}
|
@@ -38,8 +38,12 @@ impl DNA {
|
|
38
38
|
let mut out = Vec::new();
|
39
39
|
for (idx, ch) in input.chars().enumerate() {
|
40
40
|
match Nucleotide::from_char(ch) {
|
41
|
-
Some(Nucleotide::Uracil) | None => {
|
42
|
-
|
41
|
+
Some(Nucleotide::Uracil) | None => {
|
42
|
+
return Err(idx);
|
43
|
+
}
|
44
|
+
Some(n) => {
|
45
|
+
out.push(n);
|
46
|
+
}
|
43
47
|
}
|
44
48
|
}
|
45
49
|
Ok(DNA(out))
|
@@ -52,7 +56,7 @@ impl DNA {
|
|
52
56
|
Nucleotide::Cytosine => Nucleotide::Guanine,
|
53
57
|
Nucleotide::Guanine => Nucleotide::Cytosine,
|
54
58
|
Nucleotide::Thymine => Nucleotide::Adenine,
|
55
|
-
Nucleotide::Uracil => unreachable!()
|
59
|
+
Nucleotide::Uracil => unreachable!(),
|
56
60
|
}
|
57
61
|
}
|
58
62
|
RNA(self.0)
|
@@ -70,8 +74,12 @@ impl RNA {
|
|
70
74
|
let mut out = Vec::new();
|
71
75
|
for (idx, ch) in input.chars().enumerate() {
|
72
76
|
match Nucleotide::from_char(ch) {
|
73
|
-
Some(Nucleotide::Thymine) | None => {
|
74
|
-
|
77
|
+
Some(Nucleotide::Thymine) | None => {
|
78
|
+
return Err(idx);
|
79
|
+
}
|
80
|
+
Some(n) => {
|
81
|
+
out.push(n);
|
82
|
+
}
|
75
83
|
}
|
76
84
|
}
|
77
85
|
Ok(RNA(out))
|
@@ -2,7 +2,7 @@ extern crate rand;
|
|
2
2
|
use rand::{thread_rng, Rng};
|
3
3
|
|
4
4
|
pub struct Robot {
|
5
|
-
name: String
|
5
|
+
name: String,
|
6
6
|
}
|
7
7
|
|
8
8
|
fn generate_name() -> String {
|
@@ -20,7 +20,9 @@ fn generate_name() -> String {
|
|
20
20
|
|
21
21
|
impl Robot {
|
22
22
|
pub fn new() -> Robot {
|
23
|
-
Robot {
|
23
|
+
Robot {
|
24
|
+
name: generate_name(),
|
25
|
+
}
|
24
26
|
}
|
25
27
|
|
26
28
|
pub fn name<'a>(&'a self) -> &'a str {
|
@@ -30,5 +32,4 @@ impl Robot {
|
|
30
32
|
pub fn reset_name(&mut self) {
|
31
33
|
self.name = generate_name();
|
32
34
|
}
|
33
|
-
|
34
35
|
}
|
@@ -78,8 +78,11 @@ impl Robot {
|
|
78
78
|
}
|
79
79
|
|
80
80
|
pub fn instructions(&self, instructions: &str) -> Self {
|
81
|
-
instructions
|
82
|
-
|
81
|
+
instructions
|
82
|
+
.chars()
|
83
|
+
.fold(self.clone(), |robot, instruction| {
|
84
|
+
robot.execute(instruction)
|
85
|
+
})
|
83
86
|
}
|
84
87
|
|
85
88
|
pub fn position(&self) -> (i32, i32) {
|
@@ -1,18 +1,20 @@
|
|
1
1
|
use std::fmt;
|
2
2
|
|
3
|
-
static ROMAN_MAP: [(usize, &'static str); 13] = [
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
3
|
+
static ROMAN_MAP: [(usize, &'static str); 13] = [
|
4
|
+
(1, "I"),
|
5
|
+
(4, "IV"),
|
6
|
+
(5, "V"),
|
7
|
+
(9, "IX"),
|
8
|
+
(10, "X"),
|
9
|
+
(40, "XL"),
|
10
|
+
(50, "L"),
|
11
|
+
(90, "XC"),
|
12
|
+
(100, "C"),
|
13
|
+
(400, "CD"),
|
14
|
+
(500, "D"),
|
15
|
+
(900, "CM"),
|
16
|
+
(1000, "M"),
|
17
|
+
];
|
16
18
|
|
17
19
|
pub struct Roman {
|
18
20
|
num: usize,
|
@@ -38,7 +40,6 @@ impl fmt::Display for Roman {
|
|
38
40
|
}
|
39
41
|
}
|
40
42
|
|
41
|
-
|
42
43
|
impl Roman {
|
43
44
|
fn new(num: usize) -> Roman {
|
44
45
|
Roman { num: num }
|
@@ -1,16 +1,12 @@
|
|
1
1
|
pub fn rotate(text: &str, shift_key: u8) -> String {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
c
|
13
|
-
}
|
14
|
-
}).collect::<String>()
|
15
|
-
|
2
|
+
text.chars()
|
3
|
+
.map(|c| {
|
4
|
+
let case = if c.is_uppercase() { 'A' } else { 'a' } as u8;
|
5
|
+
if c.is_alphabetic() {
|
6
|
+
(((c as u8 - case + shift_key) % 26) + case) as char
|
7
|
+
} else {
|
8
|
+
c
|
9
|
+
}
|
10
|
+
})
|
11
|
+
.collect::<String>()
|
16
12
|
}
|
@@ -3,30 +3,36 @@ use std::cmp;
|
|
3
3
|
pub fn encode(input: &str) -> String {
|
4
4
|
input
|
5
5
|
.chars()
|
6
|
-
.fold(
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
.fold(
|
7
|
+
(String::new(), ' ', 0, 1),
|
8
|
+
|(mut acc, last, last_n, pos), c| {
|
9
|
+
// acc = where answer is accumulated
|
10
|
+
// last = last character read
|
11
|
+
// last_n = accum count for last
|
12
|
+
if c == last {
|
13
|
+
if pos == input.len() {
|
14
|
+
// end of string
|
15
|
+
acc += (last_n + 1).to_string().as_str();
|
16
|
+
acc.push(c);
|
17
|
+
}
|
18
|
+
(acc, last, last_n + 1, pos + 1)
|
19
|
+
} else {
|
20
|
+
if last_n > 1 {
|
21
|
+
acc += last_n.to_string().as_str();
|
22
|
+
}
|
23
|
+
if last_n > 0 {
|
24
|
+
// ignore initial last (single whitespace)
|
25
|
+
acc.push(last);
|
26
|
+
}
|
27
|
+
if pos == input.len() {
|
28
|
+
// end of string
|
29
|
+
acc.push(c);
|
30
|
+
}
|
31
|
+
(acc, c, 1, pos + 1)
|
14
32
|
}
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
if last_n > 1 {
|
19
|
-
acc += last_n.to_string().as_str();
|
20
|
-
}
|
21
|
-
if last_n > 0 { // ignore initial last (single whitespace)
|
22
|
-
acc.push(last);
|
23
|
-
}
|
24
|
-
if pos == input.len() { // end of string
|
25
|
-
acc.push(c);
|
26
|
-
}
|
27
|
-
(acc, c, 1, pos + 1)
|
28
|
-
}
|
29
|
-
}).0
|
33
|
+
},
|
34
|
+
)
|
35
|
+
.0
|
30
36
|
}
|
31
37
|
|
32
38
|
pub fn decode(input: &str) -> String {
|
@@ -34,12 +40,11 @@ pub fn decode(input: &str) -> String {
|
|
34
40
|
.chars()
|
35
41
|
.fold((String::new(), 0), |(mut acc, last_n), c| {
|
36
42
|
if let Some(d) = c.to_digit(10) {
|
37
|
-
(acc, 10*last_n + d)
|
38
|
-
}
|
39
|
-
|
40
|
-
acc += c.to_string()
|
41
|
-
.repeat(cmp::max(last_n, 1) as usize).as_str();
|
43
|
+
(acc, 10 * last_n + d)
|
44
|
+
} else {
|
45
|
+
acc += c.to_string().repeat(cmp::max(last_n, 1) as usize).as_str();
|
42
46
|
(acc, 0)
|
43
47
|
}
|
44
|
-
})
|
48
|
+
})
|
49
|
+
.0
|
45
50
|
}
|
@@ -1,13 +1,39 @@
|
|
1
|
-
const SMALL: &'static [&'static str] = &[
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
const SMALL: &'static [&'static str] = &[
|
2
|
+
"zero",
|
3
|
+
"one",
|
4
|
+
"two",
|
5
|
+
"three",
|
6
|
+
"four",
|
7
|
+
"five",
|
8
|
+
"six",
|
9
|
+
"seven",
|
10
|
+
"eight",
|
11
|
+
"nine",
|
12
|
+
"ten",
|
13
|
+
"eleven",
|
14
|
+
"twelve",
|
15
|
+
"thirteen",
|
16
|
+
"fourteen",
|
17
|
+
"fifteen",
|
18
|
+
"sixteen",
|
19
|
+
"seventeen",
|
20
|
+
"eighteen",
|
21
|
+
"nineteen",
|
22
|
+
];
|
5
23
|
|
6
|
-
const TENS: &'static [&'static str] = &[
|
7
|
-
|
24
|
+
const TENS: &'static [&'static str] = &[
|
25
|
+
"ones", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety",
|
26
|
+
];
|
8
27
|
|
9
|
-
const SCALE: &'static [&'static str] = &[
|
10
|
-
|
28
|
+
const SCALE: &'static [&'static str] = &[
|
29
|
+
"",
|
30
|
+
"thousand",
|
31
|
+
"million",
|
32
|
+
"billion",
|
33
|
+
"trillion",
|
34
|
+
"quadrillion",
|
35
|
+
"quintillion",
|
36
|
+
];
|
11
37
|
|
12
38
|
pub fn encode(n: u64) -> String {
|
13
39
|
if n < 20 {
|
@@ -1,13 +1,11 @@
|
|
1
1
|
pub fn series(digits: &str, len: usize) -> Vec<String> {
|
2
2
|
match len {
|
3
3
|
0 => vec!["".to_string(); digits.len() + 1],
|
4
|
-
_ =>
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
.collect::<Vec<String>>()
|
11
|
-
}
|
4
|
+
_ => digits
|
5
|
+
.chars()
|
6
|
+
.collect::<Vec<char>>()
|
7
|
+
.windows(len)
|
8
|
+
.map(|window| window.into_iter().collect::<String>())
|
9
|
+
.collect::<Vec<String>>(),
|
12
10
|
}
|
13
11
|
}
|
@@ -8,7 +8,6 @@ struct Node<T> {
|
|
8
8
|
next: Option<Box<Node<T>>>,
|
9
9
|
}
|
10
10
|
|
11
|
-
|
12
11
|
impl<T> SimpleLinkedList<T> {
|
13
12
|
pub fn new() -> Self {
|
14
13
|
SimpleLinkedList { head: None, len: 0 }
|
@@ -55,7 +54,6 @@ impl<T: Clone> SimpleLinkedList<T> {
|
|
55
54
|
}
|
56
55
|
}
|
57
56
|
|
58
|
-
|
59
57
|
impl<'a, T: Clone> From<&'a [T]> for SimpleLinkedList<T> {
|
60
58
|
fn from(item: &[T]) -> Self {
|
61
59
|
let mut list = SimpleLinkedList::new();
|
@@ -4,7 +4,7 @@ use std::collections::HashMap;
|
|
4
4
|
enum GameResult {
|
5
5
|
Win,
|
6
6
|
Draw,
|
7
|
-
Loss
|
7
|
+
Loss,
|
8
8
|
}
|
9
9
|
|
10
10
|
struct TeamResult {
|
@@ -15,7 +15,11 @@ struct TeamResult {
|
|
15
15
|
|
16
16
|
impl TeamResult {
|
17
17
|
fn new() -> TeamResult {
|
18
|
-
TeamResult {
|
18
|
+
TeamResult {
|
19
|
+
wins: 0,
|
20
|
+
draws: 0,
|
21
|
+
losses: 0,
|
22
|
+
}
|
19
23
|
}
|
20
24
|
fn add_game_result(&mut self, result: GameResult) {
|
21
25
|
match result {
|
@@ -30,7 +34,9 @@ pub fn tally(input: &str) -> String {
|
|
30
34
|
let mut results: HashMap<String, TeamResult> = HashMap::new();
|
31
35
|
for line in input.to_string().lines() {
|
32
36
|
let parts: Vec<&str> = line.trim_right().split(';').collect();
|
33
|
-
if parts.len() != 3 {
|
37
|
+
if parts.len() != 3 {
|
38
|
+
continue;
|
39
|
+
}
|
34
40
|
let team1 = parts[0];
|
35
41
|
let team2 = parts[1];
|
36
42
|
let outcome = parts[2];
|
@@ -38,41 +44,48 @@ pub fn tally(input: &str) -> String {
|
|
38
44
|
"win" => {
|
39
45
|
add_game_result(&mut results, team1.to_string(), GameResult::Win);
|
40
46
|
add_game_result(&mut results, team2.to_string(), GameResult::Loss);
|
41
|
-
}
|
47
|
+
}
|
42
48
|
"draw" => {
|
43
49
|
add_game_result(&mut results, team1.to_string(), GameResult::Draw);
|
44
50
|
add_game_result(&mut results, team2.to_string(), GameResult::Draw);
|
45
|
-
}
|
51
|
+
}
|
46
52
|
"loss" => {
|
47
53
|
add_game_result(&mut results, team1.to_string(), GameResult::Loss);
|
48
54
|
add_game_result(&mut results, team2.to_string(), GameResult::Win);
|
49
|
-
}
|
50
|
-
_ => () // Ignore bad lines
|
55
|
+
}
|
56
|
+
_ => (), // Ignore bad lines
|
51
57
|
}
|
52
58
|
}
|
53
59
|
write_tally(&results)
|
54
60
|
}
|
55
61
|
|
56
62
|
fn write_tally(results: &HashMap<String, TeamResult>) -> String {
|
57
|
-
let mut v: Vec<_> = results
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
63
|
+
let mut v: Vec<_> = results
|
64
|
+
.iter()
|
65
|
+
.map(|(team, r)| {
|
66
|
+
let games = r.wins + r.draws + r.losses;
|
67
|
+
let points = r.wins * 3 + r.draws;
|
68
|
+
(team, games, r, points)
|
69
|
+
})
|
70
|
+
.collect();
|
62
71
|
// Sort by points descending, then name A-Z.
|
63
|
-
v.sort_by(|a, b|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
});
|
72
|
+
v.sort_by(|a, b| match a.3.cmp(&(b.3)).reverse() {
|
73
|
+
Equal => a.0.cmp(&(b.0)),
|
74
|
+
other => other,
|
75
|
+
});
|
68
76
|
let mut lines = vec![format!("{:30} | MP | W | D | L | P", "Team")];
|
69
77
|
lines.extend(v.iter().map(|&(ref team, games, r, points)| {
|
70
|
-
format!(
|
71
|
-
|
78
|
+
format!(
|
79
|
+
"{:30} | {:2} | {:2} | {:2} | {:2} | {:2}",
|
80
|
+
team, games, r.wins, r.draws, r.losses, points
|
81
|
+
)
|
72
82
|
}));
|
73
83
|
lines.join("\n")
|
74
84
|
}
|
75
85
|
|
76
86
|
fn add_game_result(results: &mut HashMap<String, TeamResult>, team: String, result: GameResult) {
|
77
|
-
results
|
87
|
+
results
|
88
|
+
.entry(team)
|
89
|
+
.or_insert(TeamResult::new())
|
90
|
+
.add_game_result(result);
|
78
91
|
}
|