Skip to content

Commit 7a56eec

Browse files
committed
Added Text Justification
1 parent 16ef803 commit 7a56eec

File tree

2 files changed

+146
-1
lines changed

2 files changed

+146
-1
lines changed

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub mod minimum_path_sum; // 64 ✓
111111

112112
pub mod plus_one; // 66
113113
pub mod add_binary; // 67 ✓
114-
114+
pub mod text_justification; // 68 ✓
115115
pub mod sqrt_x; // 69 ✓
116116
pub mod climbing_stairs; // 70
117117
pub mod simplify_path; // 71

src/text_justification.rs

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/// Given an array of strings `words` and a width `maxWidth`, format the text such that each line
2+
/// has exactly `maxWidth` characters and is fully (left and right) justified.
3+
///
4+
/// You should pack your words in a greedy approach; that is, pack as many words as you can in each
5+
/// line. Pad extra spaces `' '` when necessary so that each line has exactly `maxWidth`
6+
/// characters.
7+
///
8+
/// Extra spaces between words should be distributed as evenly as possible. If the number of spaces
9+
/// on a line does not divide evenly between words, the empty slots on the left will be assigned
10+
/// more spaces than the slots on the right.
11+
///
12+
/// For the last line of text, it should be left-justified, and no extra space is inserted between
13+
/// words.
14+
struct Solution;
15+
16+
impl Solution {
17+
18+
pub fn full_justify(words: Vec<String>, max_width: i32) -> Vec<String> {
19+
let max_width = max_width as usize;
20+
let n = words.len();
21+
22+
let mut line_len = 0;
23+
let mut start = 0;
24+
25+
let mut results = vec![];
26+
27+
for i in 0..n {
28+
let word = &words[i];
29+
let word_len = word.len();
30+
let attempt = if line_len == 0 {
31+
word_len
32+
} else {
33+
line_len + word_len + 1
34+
};
35+
if attempt == max_width {
36+
// Matches Perfectly
37+
// One Space Between Words
38+
let mut line = words[start].clone();
39+
for j in start+1..=i {
40+
line.push(' ');
41+
line.push_str(&words[j]);
42+
}
43+
results.push(line);
44+
start = i + 1;
45+
line_len = 0;
46+
} else if attempt < max_width {
47+
// Keep Going
48+
line_len = attempt;
49+
} else {
50+
// Overshot It
51+
let mut chars_len = 0;
52+
let mut count = 0;
53+
for j in start..i {
54+
chars_len += words[j].len();
55+
count += 1;
56+
}
57+
count -= 1;
58+
let mut diff = max_width - chars_len;
59+
let mut line = words[start].clone();
60+
for j in start+1..i {
61+
// Divide the spaces evenly between words and
62+
// push the spaces and the word.
63+
let spaces = (diff as f64 / count as f64).ceil() as usize;
64+
count -= 1;
65+
diff -= spaces;
66+
for _ in 0..spaces {
67+
line.push(' ');
68+
}
69+
line.push_str(&words[j]);
70+
}
71+
// If there's only one word in the line, there may
72+
// need to be spaces pushed at the end.
73+
for _ in 0..diff {
74+
line.push(' ');
75+
}
76+
results.push(line);
77+
start = i;
78+
line_len = word_len;
79+
}
80+
}
81+
82+
if start < n {
83+
let mut line = words[start].clone();
84+
line_len = words[start].len();
85+
for j in start+1..n {
86+
line.push(' ');
87+
line.push_str(&words[j]);
88+
line_len += 1 + &words[j].len();
89+
}
90+
if line_len < max_width {
91+
for _ in line_len..max_width {
92+
line.push(' ');
93+
}
94+
}
95+
results.push(line);
96+
}
97+
98+
results
99+
}
100+
}
101+
102+
#[cfg(test)]
103+
mod tests {
104+
use super::Solution;
105+
106+
#[test]
107+
fn example_1() {
108+
let words = vec![
109+
str!("This"),
110+
str!("is"),
111+
str!("an"),
112+
str!("example"),
113+
str!("of"),
114+
str!("text"),
115+
str!("justification.")
116+
];
117+
let max_width = 16;
118+
let results = Solution::full_justify(words, max_width);
119+
assert_eq!(results, vec![
120+
"This is an",
121+
"example of text",
122+
"justification. "
123+
]);
124+
}
125+
126+
#[test]
127+
fn example_2() {
128+
let words = vec![
129+
str!("What"),
130+
str!("must"),
131+
str!("be"),
132+
str!("acknowledgment"),
133+
str!("shall"),
134+
str!("be"),
135+
];
136+
let max_width = 16;
137+
let results = Solution::full_justify(words, max_width);
138+
assert_eq!(results, vec![
139+
"What must be",
140+
"acknowledgment ",
141+
"shall be "
142+
]);
143+
}
144+
145+
}

0 commit comments

Comments
 (0)