• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Vest / aoc-rust / 4005027531

pending completion
4005027531

Pull #19

github

GitHub
Merge 74f46dcbf into 0e0e3157b
Pull Request #19: Updated versions

2556 of 3992 branches covered (64.03%)

Branch coverage included in aggregate %.

1560 of 1560 new or added lines in 44 files covered. (100.0%)

5981 of 6247 relevant lines covered (95.74%)

624811.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.83
/adv2015/src/day13.rs
1
use permute::permutations_of;
4✔
2
use std::cmp::max;
3
use std::collections::{HashMap, HashSet};
4

5
pub fn get_answer(input: &str) -> i32 {
1✔
6
    calculate_everyone(input)
1✔
7
}
1✔
8

9
pub fn get_answer_with_me(input: &str) -> i32 {
1✔
10
    calculate_everyone_and_me(input)
1✔
11
}
1✔
12

13
struct PersonToPerson {
14
    who: String,
15
    next: String,
16
    attitude: i32,
17
}
18

19
fn parse_line(input: &str) -> PersonToPerson {
64✔
20
    let mut split = input.split_whitespace();
64✔
21
    let who = split.next().unwrap(); // name
64✔
22
    split.next(); // would
64✔
23
    let verb = split.next().unwrap(); // gain/lose
64✔
24
    let attitude =
25
        split.next().unwrap().parse::<i32>().unwrap() * if verb == "lose" { -1 } else { 1 }; // amount * verb
64✔
26
    split.next(); // happiness
64✔
27
    split.next(); // units
64✔
28
    split.next(); // by
64✔
29
    split.next(); // sitting
64✔
30
    split.next(); // next
64✔
31
    split.next(); // to
64✔
32
    let mut next = String::from(split.next().unwrap()); // name, with . at the end.
64✔
33
    next.pop();
64✔
34

35
    PersonToPerson {
64✔
36
        who: String::from(who),
64✔
37
        next,
64✔
38
        attitude,
39
    }
40
}
64✔
41

42
fn parse_input(input: &str) -> Vec<PersonToPerson> {
7✔
43
    let vec: Vec<PersonToPerson> = input.lines().map(|line| parse_line(line)).collect();
69✔
44

45
    vec
46
}
7✔
47

48
fn build_relationships(input: &Vec<PersonToPerson>) -> HashMap<(String, String), i32> {
5✔
49
    let mut hash_map: HashMap<(String, String), i32> = HashMap::with_capacity(10);
5✔
50

51
    for person in input {
43✔
52
        hash_map.insert((person.who.clone(), person.next.clone()), person.attitude);
38✔
53
    }
54

55
    hash_map
56
}
5✔
57

58
fn extract_names(input: &Vec<PersonToPerson>) -> HashSet<String> {
4✔
59
    let mut hash_set: HashSet<String> = HashSet::with_capacity(5);
4✔
60

61
    input.iter().for_each(|person| {
30✔
62
        hash_set.insert(person.who.clone());
26✔
63
    });
26✔
64

65
    hash_set
66
}
4✔
67

68
fn calculate_happiness(people: &Vec<String>, relationship: &HashMap<(String, String), i32>) -> i32 {
26✔
69
    let mut result = 0i32;
26✔
70
    let mut previous = String::from(people.last().unwrap());
26✔
71

72
    for current in people.iter() {
127✔
73
        result += relationship[&(previous.clone(), current.clone())];
101✔
74
        result += relationship[&(current.clone(), previous.clone())];
101✔
75
        previous = current.clone();
101✔
76
    }
77

78
    result
79
}
26✔
80

81
fn calculate_happiness_with_me(
2✔
82
    people: &Vec<String>,
83
    relationship: &HashMap<(String, String), i32>,
84
) -> i32 {
85
    let mut result = 0i32;
2✔
86
    let mut previous = String::from(people.last().unwrap());
2✔
87

88
    for current in people.iter() {
6✔
89
        if current.eq("Me") || previous.eq("Me") {
4!
90
            previous = current.clone();
4✔
91
            continue;
92
        }
93

94
        result += relationship[&(previous.clone(), current.clone())];
×
95
        result += relationship[&(current.clone(), previous.clone())];
×
96
        previous = current.clone();
×
97
    }
98

99
    result
100
}
2✔
101

102
fn calculate_everyone(input: &str) -> i32 {
2✔
103
    let people = parse_input(input);
2✔
104
    let relationship = build_relationships(&people);
2✔
105
    let table: Vec<String> = extract_names(&people)
2✔
106
        .iter()
107
        .map(|n| (*n).clone())
5✔
108
        .collect();
2✔
109

110
    let mut result = 0i32;
2✔
111

112
    for permutation in permutations_of(&table) {
27✔
113
        let guessed_table: Vec<String> = permutation.map(|n| (*n).clone()).collect();
122✔
114

115
        let current_happiness = calculate_happiness(&guessed_table, &relationship);
25✔
116
        result = max(result, current_happiness);
25✔
117
    }
25✔
118

119
    result
120
}
2✔
121

122
fn calculate_everyone_and_me(input: &str) -> i32 {
1✔
123
    let people = parse_input(input);
1✔
124
    let relationship = build_relationships(&people);
1✔
125
    let mut table: Vec<String> = extract_names(&people)
1✔
126
        .iter()
127
        .map(|n| (*n).clone())
1✔
128
        .collect();
1✔
129
    table.push("Me".to_string());
1✔
130

131
    let mut result = 0i32;
1✔
132

133
    for permutation in permutations_of(&table) {
3✔
134
        let guessed_table: Vec<String> = permutation.map(|n| (*n).clone()).collect();
6✔
135

136
        let current_happiness = calculate_happiness_with_me(&guessed_table, &relationship);
2✔
137
        result = max(result, current_happiness);
2✔
138
    }
2✔
139

140
    result
141
}
1✔
142

143
#[cfg(test)]
144
mod tests {
145
    use super::*;
146

147
    const INPUT: &'static str = r#"Alice would gain 54 happiness units by sitting next to Bob.
148
                                   Alice would lose 79 happiness units by sitting next to Carol.
149
                                   Alice would lose 2 happiness units by sitting next to David.
150
                                   Bob would gain 83 happiness units by sitting next to Alice.
151
                                   Bob would lose 7 happiness units by sitting next to Carol.
152
                                   Bob would lose 63 happiness units by sitting next to David.
153
                                   Carol would lose 62 happiness units by sitting next to Alice.
154
                                   Carol would gain 60 happiness units by sitting next to Bob.
155
                                   Carol would gain 55 happiness units by sitting next to David.
156
                                   David would gain 46 happiness units by sitting next to Alice.
157
                                   David would lose 7 happiness units by sitting next to Bob.
158
                                   David would gain 41 happiness units by sitting next to Carol."#;
159

160
    #[test]
161
    fn test_parse_line_1() {
2✔
162
        let result = parse_line("Alice would gain 54 happiness units by sitting next to Bob.");
1✔
163
        assert_eq!(result.who, "Alice");
1!
164
        assert_eq!(result.next, "Bob");
1!
165
        assert_eq!(result.attitude, 54);
1!
166
    }
2✔
167

168
    #[test]
169
    fn test_parse_line_2() {
2✔
170
        let result = parse_line("Alice would lose 79 happiness units by sitting next to Carol.");
1✔
171
        assert_eq!(result.who, "Alice");
1!
172
        assert_eq!(result.next, "Carol");
1!
173
        assert_eq!(result.attitude, -79);
1!
174
    }
2✔
175

176
    #[test]
177
    fn test_parse_input() {
2✔
178
        let result = parse_input(INPUT);
1✔
179
        let single_line = result.get(10).unwrap();
1✔
180

181
        assert_eq!(result.len(), 12);
1!
182
        assert_eq!(single_line.who, "David");
1!
183
        assert_eq!(single_line.next, "Bob");
1!
184
        assert_eq!(single_line.attitude, -7);
1!
185
    }
2✔
186

187
    #[test]
188
    fn test_build_relationships() {
2✔
189
        let result = parse_input(INPUT);
1✔
190
        let hash_map = build_relationships(&result);
1✔
191

192
        let key = (String::from("David"), String::from("Bob")); // David -> Bob
1✔
193

194
        assert_eq!(hash_map.len(), 12);
1!
195
        assert_eq!(hash_map[&key], -7);
1!
196
    }
2✔
197

198
    #[test]
199
    fn test_extract_names() {
2✔
200
        let result = parse_input(INPUT);
1✔
201
        let people = extract_names(&result);
1✔
202

203
        assert_eq!(people.len(), 4);
1!
204
        assert!(people.contains("Alice"));
1!
205
        assert!(people.contains("Bob"));
1!
206
        assert!(people.contains("Carol"));
1!
207
        assert!(people.contains("David"));
1!
208
    }
2✔
209

210
    #[test]
211
    fn test_calculate_happiness() {
2✔
212
        let people = parse_input(INPUT);
1✔
213
        let hash_map = build_relationships(&people);
1✔
214
        let table: Vec<String> = vec![
2✔
215
            "Alice".to_string(),
1✔
216
            "Bob".to_string(),
1✔
217
            "Carol".to_string(),
1✔
218
            "David".to_string(),
1✔
219
        ];
220

221
        let result = calculate_happiness(&table, &hash_map);
1✔
222
        assert_eq!(result, 330);
1!
223
    }
2✔
224

225
    #[test]
226
    fn test_calculate_everyone() {
2✔
227
        let result = calculate_everyone(INPUT);
1✔
228
        assert_eq!(result, 330);
1!
229
    }
2✔
230
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc