Skip to content

Commit a32cddc

Browse files
committed
Updated to Rust 1.21
1 parent 5c60b31 commit a32cddc

File tree

7 files changed

+49
-46
lines changed

7 files changed

+49
-46
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ rust:
33
- stable
44
- beta
55
- nightly
6-
- 1.19.0 # Current version supported by Codeforces
6+
- 1.21.0 # Current version supported by Codeforces
77
matrix:
88
allow_failures:
99
- rust: nightly

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@ In addition, the Rust language has outstanding pedagogical attributes. Its compi
1616

1717
The original intent of this project was to build a reference for use in programming contests such as [Codeforces](http://codeforces.com) and the [Google Code Jam](https://code.google.com/codejam). As a result, it contains algorithms that are frequently useful to have in one's toolkit, with an emphasis on making the code concise and easy to modify under time pressure.
1818

19-
Most competition programmers use C++ for its fast execution time. However, it's notoriously unsafe, wasting a considerable share of the contestant's time and attention on accident prevention and debugging. Java is the next most popular choice, offering a little safety at some expense to coding and execution speed. To my delight, I found that Rust provides even more safety without the visual clutter, and it's *fast*. A proficient Rust programmer stands to gain a competitive advantage as well as a more pleasant experience!
19+
Most competition programmers rely on C++ for its fast execution time. However, it's notoriously unsafe, diverting a considerable share of the contestant's time and attention on mistake prevention and debugging. Java is the next most popular choice, offering a little safety at some expense to speed of coding and execution.
20+
21+
To my delight, I found that Rust provides even more safety without the visual clutter, and it's *fast*. A proficient Rust programmer stands to gain a competitive advantage as well as a more pleasant experience!
2022

2123
## Programming Language Advocacy
2224

23-
My other goal is to appeal to developers who feel, as I once did, trapped between the lesser of headaches among old mainstream languages (e.g., C++/Java), to raise awareness that *it doesn't have to be this way*. Rather than trying to persuade you with words, this repository aims to show by example and ease the learning curve. See [Jim Blandy's *Why Rust?*](http://www.oreilly.com/programming/free/files/why-rust.pdf) for a brief introduction, or just [dive in!](https://doc.rust-lang.org/book/second-edition/)
25+
My other goal is to appeal to developers who feel, as I once did, trapped between the lesser of headaches among old mainstream languages (e.g., C++/Java), to raise awareness that *it doesn't have to be this way*.
26+
27+
Rather than try to persuade you with words, this repository aims to show by example while easing the learning curve. See [Jim Blandy's *Why Rust?*](http://www.oreilly.com/programming/free/files/why-rust.pdf) for a brief introduction, or just [dive in!](https://doc.rust-lang.org/book/second-edition/)
2428

2529
## Contents
2630

src/arq_tree.rs

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,38 @@ pub trait ArqSpec {
132132
fn identity() -> Self::M;
133133
}
134134

135-
/// In this example, we want to support range sum queries and range constant
136-
/// assignments. Note that constant assignment f_c(a) = c is not a endomorphism
137-
/// on (i64, +) because f_c(a+b) = c != 2*c = f_c(a) + f_c(b). In intuitive
138-
/// terms, the problem is that the internal nodes of the tree should really be
139-
/// set to a multiple of c, corresponding to the subtree size. So let's augment
140-
/// the monoid type with size information, using the 2D vector (a_i,1) instead
141-
/// of a_i. Now check that f_c((a, s)) = (c*s, s) is indeed an endomorphism on
135+
/// Range Minimum Query, a classic application of associative range query.
136+
// Exercises: try augmenting this struct to find the index of a minimum element
137+
// in a range query, as well as the number of elements that match the minimum.
138+
// Then instead of assigning to a range, try to support the operation of
139+
// incrementing each element in a range by a given offset!
140+
pub struct AssignMin;
141+
142+
impl ArqSpec for AssignMin {
143+
type F = i64;
144+
type M = i64;
145+
fn compose(f: &Self::F, _: &Self::F) -> Self::F {
146+
*f
147+
}
148+
fn apply(f: &Self::F, _: &Self::M) -> Self::M {
149+
*f
150+
}
151+
fn op(a: &Self::M, b: &Self::M) -> Self::M {
152+
(*a).min(*b)
153+
}
154+
fn identity() -> Self::M {
155+
Self::M::max_value()
156+
}
157+
}
158+
159+
/// A slightly more advanced application, where we aim to support range sum
160+
/// queries and range constant assignments.
161+
/// Note that constant assignment f_c(a) = c is not a endomorphism on (i64, +)
162+
/// because f_c(a+b) = c != 2*c = f_c(a) + f_c(b). In intuitive terms, the
163+
/// problem is that the internal nodes of the tree should not simply be set to
164+
/// c, but rather, to c multiplied by the subtree size. So let's augment the
165+
/// monoid type with size information, using the 2D vector (a_i,1) instead of
166+
/// a_i. Now check that f_c((a, s)) = (c*s, s) is indeed an endomorphism on
142167
/// vector addition: f_c((a,s)+(b,t)) = f_c((a+b,s+t)) = (c*(s+t),s+t)
143168
/// = (c*s,s)+(c*t,t) = f_c((a,s)) + f_c((b,t)).
144169
///
@@ -164,30 +189,6 @@ impl ArqSpec for AssignSum {
164189
}
165190
}
166191

167-
/// Range Minimum Query, a classic form of associative range query.
168-
// Exercises: try augmenting this struct to find the index of a minimum element
169-
// in a range query, as well as the number of elements that match the minimum.
170-
// Then instead of assigning to a range, try to support the operation of
171-
// incrementing each element in a range by a given offset!
172-
pub struct AssignMin;
173-
174-
impl ArqSpec for AssignMin {
175-
type F = i64;
176-
type M = i64;
177-
fn compose(f: &Self::F, _: &Self::F) -> Self::F {
178-
*f
179-
}
180-
fn apply(f: &Self::F, _: &Self::M) -> Self::M {
181-
*f
182-
}
183-
fn op(a: &Self::M, b: &Self::M) -> Self::M {
184-
::std::cmp::min(*a, *b)
185-
}
186-
fn identity() -> Self::M {
187-
Self::M::max_value()
188-
}
189-
}
190-
191192
#[cfg(test)]
192193
mod test {
193194
use super::*;

src/graph/connectivity.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! Graph connectivity structures.
22
use graph::Graph;
3-
use std::cmp::min;
43

54
/// Represents the decomposition of a graph into any of its constituent parts:
65
///
@@ -78,7 +77,7 @@ impl<'a> ConnectivityGraph<'a> {
7877
self.scc(v, t, vis, low, v_stack);
7978
}
8079
if self.cc[v] == 0 {
81-
low[u] = min(low[u], low[v]);
80+
low[u] = low[u].min(low[v]);
8281
}
8382
}
8483
if vis[u] == low[u] {
@@ -112,7 +111,7 @@ impl<'a> ConnectivityGraph<'a> {
112111
/// order. Undefined behavior if the graph is not a DAG.
113112
pub fn topological_sort(&self) -> Vec<usize> {
114113
let mut vertices = (0..self.graph.num_v()).collect::<Vec<_>>();
115-
vertices.sort_by_key(|&u| self.num_cc - self.cc[u]);
114+
vertices.sort_unstable_by_key(|&u| self.num_cc - self.cc[u]);
116115
vertices
117116
}
118117

@@ -134,7 +133,7 @@ impl<'a> ConnectivityGraph<'a> {
134133
if vis[v] == 0 {
135134
e_stack.push(e);
136135
self.bcc(v, e, t, vis, low, v_stack, e_stack);
137-
low[u] = min(low[u], low[v]);
136+
low[u] = low[u].min(low[v]);
138137
if vis[u] <= low[v] {
139138
// u is a cut vertex unless it's a one-child root
140139
self.num_vcc += 1;
@@ -147,7 +146,7 @@ impl<'a> ConnectivityGraph<'a> {
147146
}
148147
}
149148
} else if vis[v] < vis[u] && e ^ par != 1 {
150-
low[u] = min(low[u], vis[v]);
149+
low[u] = low[u].min(vis[v]);
151150
e_stack.push(e);
152151
} else if v == u {
153152
// e is a self-loop

src/graph/flow.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Maximum flows, matchings, and minimum cuts.
22
use graph::{Graph, AdjListIterator};
3-
use std::cmp::min;
4-
const INF: i64 = 0x3f3f3f3f;
3+
const INF: i64 = 0x3f3f3f3f3f3f3f3f;
54

65
/// Representation of a network flow problem with (optional) costs.
76
pub struct FlowGraph {
@@ -91,7 +90,7 @@ impl FlowGraph {
9190
let mut df = 0;
9291

9392
while let Some(&(e, v)) = adj[u].peek() {
94-
let rem_cap = min(self.cap[e] - flow[e], f - df);
93+
let rem_cap = (self.cap[e] - flow[e]).min(f - df);
9594
if rem_cap > 0 && dist[v] == dist[u] + 1 {
9695
let cf = self.dinic_augment(v, t, rem_cap, dist, adj, flow);
9796
flow[e] += cf;
@@ -133,7 +132,7 @@ impl FlowGraph {
133132
if self.cap[e] > 0 {
134133
let u = self.graph.endp[e ^ 1];
135134
let v = self.graph.endp[e];
136-
pot[v] = min(pot[v], pot[u] + self.cost[e]);
135+
pot[v] = pot[v].min(pot[u] + self.cost[e]);
137136
}
138137
}
139138
}
@@ -181,7 +180,7 @@ impl FlowGraph {
181180
let (mut dc, mut df) = (0, INF);
182181
let mut u = t;
183182
while let Some(e) = par[u] {
184-
df = min(df, self.cap[e] - flow[e]);
183+
df = df.min(self.cap[e] - flow[e]);
185184
u = self.graph.endp[e ^ 1];
186185
}
187186
u = t;

src/graph/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl Graph {
128128
pub fn min_spanning_tree(&self, weights: &[i64]) -> Vec<usize> {
129129
assert_eq!(self.num_e(), 2 * weights.len());
130130
let mut edges = (0..weights.len()).collect::<Vec<_>>();
131-
edges.sort_by_key(|&e| weights[e]);
131+
edges.sort_unstable_by_key(|&e| weights[e]);
132132

133133
let mut components = DisjointSets::new(self.num_v());
134134
edges

src/string_proc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub fn palindromes(text: &[u8]) -> Vec<usize> {
6161
pal.push(1);
6262
while pal.len() < pal.capacity() {
6363
let i = pal.len() - 1;
64-
let max_len = ::std::cmp::min(i + 1, pal.capacity() - i);
64+
let max_len = (i + 1).min(pal.capacity() - i);
6565
while pal[i] < max_len && text[(i - pal[i] - 1) / 2] == text[(i + pal[i] + 1) / 2] {
6666
pal[i] += 2;
6767
}

0 commit comments

Comments
 (0)