Rust
obsidian source → .md
downloadhttps://toml.io/en/ for rust implementation https://doc.rust-lang.org/book/title-page.html rust tutorial https://cheats.rs
(media not in this export — contact me for the full note)
Rust
Hello World:
// hello_world.rs
fn main() {
println!("Hello, World!"); // println! is a macro
}
If-Else Question Program:
// if_else_example.rs
use std::io; // Required for input/output operations
fn main() {
println!("Enter an integer:");
let mut input = String::new(); // Create a mutable string to store input
// Read a line from stdin
io::stdin().read_line(&mut input)
.expect("Failed to read line"); // Handle potential error
// Trim whitespace and parse the string to an integer
let number: i32 = match input.trim().parse() {
Ok(num) => num, // Successfully parsed
Err(_) => { // Failed to parse
println!("Invalid input. Please enter an integer.");
return; // Exit the program
}
};
// If-else if-else statement (no parentheses around conditions in Rust)
if number > 0 {
println!("The number {} is positive.", number);
} else if number == 0 {
println!("The number {} is zero.", number);
} else {
println!("The number {} is negative.", number);
}
}
How to run Rust:
Save the code as a .rs file. You need Rust installed (via rustup).
-
Compile:
rustc hello_world.rs -
Run:
./hello_worldFor the if-else example:
-
Compile:
rustc if_else_example.rs -
Run:
./if_else_example
Rust Implementations
Place the following snippets in a Rust file (for example, main.rs) and run with cargo run or rustc main.rs && ./main.
Tip: For clarity, each example is separated by a comment header.
→ Vec<u64> specifies the return type of the Rust function.
Return Type Meaning
In Rust function signatures, the → arrow separates parameters from the return type. Here, Vec<u64> means the function returns ownership of a growable vector containing unsigned 64-bit integers (u64).
Vec Details
- Vec<T> is Rust’s standard contiguous, dynamically-sized array that can grow or shrink at runtime.
- u64 is a primitive unsigned 64-bit integer (0 to 18,446,744,073,709,551,615), ideal for Fibonacci numbers up to large indices before overflow.
Number Logic Programs in Rust
- Prime Number Check
fn is_prime(n: i32) -> bool {
if n <= 1 {
return false;
}
for i in 2..=((n as f64).sqrt() as i32) {
if n % i == 0 {
return false;
}
}
true
}
fn demo_prime() {
let num = 29;
println!("{} is prime? {}", num, is_prime(num));
// Expected Output: "29 is prime? true"
}
- Fibonacci Series
fn fibonacci(n: usize) -> Vec<u64> {
let mut series = Vec::with_capacity(n);
let (mut a, mut b) = (0, 1);
for _ in 0..n {
series.push(a);
let temp = a + b;
a = b;
b = temp;
}
series
}
fn demo_fibonacci() {
println!("Fibonacci series: {:?}", fibonacci(10));
// Expected Output: "Fibonacci series: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]"
}
- Factorial
fn factorial(n: u64) -> u64 {
if n == 0 { 1 } else { n * factorial(n - 1) }
}
fn demo_factorial() {
let num = 5;
println!("Factorial of {}: {}", num, factorial(num));
// Expected Output: "Factorial of 5: 120"
}
- Armstrong Number
fn is_armstrong(num: u32) -> bool {
let digits: Vec<u32> = num
.to_string()
.chars()
.filter_map(|c| c.to_digit(10))
.collect();
let power = digits.len() as u32;
let sum: u32 = digits.iter().map(|&d| d.pow(power)).sum();
sum == num
}
fn demo_armstrong() {
let num = 153;
println!("{} is Armstrong? {}", num, is_armstrong(num));
// Expected Output: "153 is Armstrong? true"
}
- Palindrome Number
fn is_palindrome(num: i32) -> bool {
let s = num.to_string();
s == s.chars().rev().collect::<String>()
}
fn demo_palindrome() {
let num = 121;
println!("{} is palindrome? {}", num, is_palindrome(num));
// Expected Output: "121 is palindrome? true"
}
- GCD and LCM
fn gcd(a: i32, b: i32) -> i32 {
if b == 0 { a } else { gcd(b, a % b) }
}
fn lcm(a: i32, b: i32) -> i32 {
(a * b).abs() / gcd(a, b)
}
fn demo_gcd_lcm() {
println!("GCD of 54 and 24: {}", gcd(54, 24)); // Expected: 6
println!("LCM of 12 and 18: {}", lcm(12, 18)); // Expected: 36
}
- Reverse a Number & Sum of Digits
fn reverse_number(num: i32) -> i32 {
num.to_string()
.chars()
.rev()
.collect::<String>()
.parse::<i32>()
.unwrap_or(0)
}
fn sum_of_digits(num: i32) -> i32 {
num.to_string()
.chars()
.filter_map(|c| c.to_digit(10))
.map(|d| d as i32)
.sum()
}
fn demo_reverse_and_sum() {
let num = 12345;
println!("Reverse of {}: {}", num, reverse_number(num)); // Expected: 54321
println!("Sum of digits of {}: {}", 1234, sum_of_digits(1234)); // Expected: 10
}
Array Programs in Rust
- Linear Search
fn linear_search(arr: &[i32], target: i32) -> Option<usize> {
arr.iter().position(|&x| x == target)
}
fn demo_linear_search() {
let arr = [10, 20, 30, 40, 50];
let target = 30;
println!("Position of {}: {:?}", target, linear_search(&arr, target));
// Expected Output: "Position of 30: Some(2)"
}
- Binary Search
fn binary_search(arr: &[i32], target: i32) -> Option<usize> {
let (mut low, mut high) = (0, arr.len() as i32 - 1);
while low <= high {
let mid = (low + high) / 2;
if arr[mid as usize] == target {
return Some(mid as usize);
} else if arr[mid as usize] < target {
low = mid + 1;
} else {
high = mid - 1;
}
}
None
}
fn demo_binary_search() {
let arr = [10, 20, 30, 40, 50];
let target = 40;
println!("Position of {}: {:?}", target, binary_search(&arr, target));
// Expected Output: "Position of 40: Some(3)"
}
- Bubble Sort
fn bubble_sort(arr: &mut [i32]) {
let n = arr.len();
for i in 0..n {
for j in 0..(n - i - 1) {
if arr[j] > arr[j + 1] {
arr.swap(j, j + 1);
}
}
}
}
fn demo_bubble_sort() {
let mut arr = [64, 34, 25, 12, 22, 11, 90];
bubble_sort(&mut arr);
println!("Sorted array: {:?}", arr);
// Expected Output: "Sorted array: [11, 12, 22, 25, 34, 64, 90]"
}
- Selection Sort
fn selection_sort(arr: &mut [i32]) {
let n = arr.len();
for i in 0..n {
let mut min_idx = i;
for j in (i + 1)..n {
if arr[j] < arr[min_idx] {
min_idx = j;
}
}
arr.swap(i, min_idx);
}
}
fn demo_selection_sort() {
let mut arr = [64, 25, 12, 22, 11];
selection_sort(&mut arr);
println!("Selection sorted: {:?}", arr);
// Expected Output: "Selection sorted: [11, 12, 22, 25, 64]"
}
- Insertion Sort
fn insertion_sort(arr: &mut [i32]) {
let n = arr.len();
for i in 1..n {
let key = arr[i];
let mut j = i;
while j > 0 && arr[j - 1] > key {
arr[j] = arr[j - 1];
j -= 1;
}
arr[j] = key;
}
}
fn demo_insertion_sort() {
let mut arr = [12, 11, 13, 5, 6];
insertion_sort(&mut arr);
println!("Insertion sorted: {:?}", arr);
// Expected Output: "Insertion sorted: [5, 6, 11, 12, 13]"
}
- Second Largest Element
fn second_largest(arr: &[i32]) -> Option<i32> {
if arr.len() < 2 { return None; }
let mut first = i32::MIN;
let mut second = i32::MIN;
for &num in arr {
if num > first {
second = first;
first = num;
} else if num > second && num != first {
second = num;
}
}
if second == i32::MIN { None } else { Some(second) }
}
fn demo_second_largest() {
let arr = [12, 35, 1, 10, 34, 1];
println!("Second largest: {:?}", second_largest(&arr));
// Expected Output: "Second largest: Some(34)"
}
- Array Rotation
fn rotate_array(arr: &[i32], k: usize) -> Vec<i32> {
let len = arr.len();
let k = k % len;
[&arr[k..], &arr[..k]].concat()
}
fn demo_array_rotation() {
let arr = [1, 2, 3, 4, 5, 6, 7];
println!("Rotated array: {:?}", rotate_array(&arr, 3));
// Expected Output: "Rotated array: [4, 5, 6, 7, 1, 2, 3]"
}
- Remove Duplicates
use std::collections::LinkedHashSet;
fn remove_duplicates(arr: &[i32]) -> Vec<i32> {
let mut set = LinkedHashSet::new();
for &num in arr {
set.insert(num);
}
set.into_iter().collect()
}
fn demo_remove_duplicates() {
let arr = [1, 2, 2, 3, 4, 4, 5];
println!("Without duplicates: {:?}", remove_duplicates(&arr));
// Expected Output: "Without duplicates: [1, 2, 3, 4, 5]"
}
- Merge Two Arrays
fn merge_arrays(arr1: &[i32], arr2: &[i32]) -> Vec<i32> {
let mut merged = [arr1, arr2].concat();
merged.sort();
merged
}
fn demo_merge_arrays() {
let arr1 = [1, 3, 5, 7];
let arr2 = [2, 4, 6, 8];
println!("Merged array: {:?}", merge_arrays(&arr1, &arr2));
// Expected Output: "Merged array: [1, 2, 3, 4, 5, 6, 7, 8]"
}
- Matrix Addition & Multiplication
fn matrix_addition(a: &Vec<Vec<i32>>, b: &Vec<Vec<i32>>) -> Vec<Vec<i32>> {
a.iter().zip(b.iter())
.map(|(row_a, row_b)| row_a.iter().zip(row_b.iter()).map(|(x, y)| x + y).collect())
.collect()
}
fn matrix_multiplication(a: &Vec<Vec<i32>>, b: &Vec<Vec<i32>>) -> Vec<Vec<i32>> {
let m = a.len();
let n = b[0].len();
let mut result = vec![vec![0; n]; m];
for i in 0..m {
for j in 0..n {
for k in 0..b.len() {
result[i][j] += a[i][k] * b[k][j];
}
}
}
result
}
fn demo_matrices() {
let a = vec![vec![1, 2], vec![3, 4]];
let b = vec![vec![5, 6], vec![7, 8]];
println!("Matrix addition: {:?}", matrix_addition(&a, &b));
// Expected Output: "Matrix addition: [[6, 8], [10, 12]]"
let c = vec![vec![2, 0], vec![1, 2]];
println!("Matrix multiplication: {:?}", matrix_multiplication(&a, &c));
// Expected Output: "Matrix multiplication: [[4, 4], [10, 8]]"
}
- Transpose Matrix
fn transpose(matrix: &Vec<Vec<i32>>) -> Vec<Vec<i32>> {
let rows = matrix.len();
let cols = matrix[0].len();
let mut transposed = vec![vec![0; rows]; cols];
for i in 0..rows {
for j in 0..cols {
transposed[j][i] = matrix[i][j];
}
}
transposed
}
fn demo_transpose() {
let matrix = vec![vec![1, 2, 3], vec![4, 5, 6]];
println!("Transpose: {:?}", transpose(&matrix));
// Expected Output: "Transpose: [[1, 4], [2, 5], [3, 6]]"
}
- Frequency of Elements
use std::collections::HashMap;
fn frequency_count(arr: &[i32]) -> HashMap<i32, i32> {
let mut freq = HashMap::new();
for &num in arr {
*freq.entry(num).or_insert(0) += 1;
}
freq
}
fn demo_frequency() {
let arr = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4];
println!("Frequency: {:?}", frequency_count(&arr));
// Expected Output (order may vary): "Frequency: {1: 1, 2: 2, 3: 3, 4: 4}"
}
arr: &i32 and related syntax define precise type annotations for safe, borrowed access to array data in Rust functions.
Parameter Syntax Breakdown
- arr is the parameter name.
- : separates name from type (required for all parameters).
- & denotes a borrow/reference — non-owning pointer to data elsewhere.
- i32 is a slice type: unsized view over contiguous i32 (32-bit signed integer) elements.
- Combined &i32 = borrowed slice: runtime-length, read-only array reference (zero-cost abstraction).
Return Type Syntax
- -> mandates explicit return type (unlike implicit () unit).
- HashMap<K, V> is generic: angle brackets < > specify type parameters.
- i32, i32 = key-value types (both 32-bit signed ints for number → frequency mapping).
Loop Pattern Syntax
- for ... in ITERABLE iterates owned values.
- &num = ref pattern: & destructures borrowed &i32 into owned i32 copy (via Copy trait).
- num becomes i32 variable per iteration (no further borrow).
- Find Missing Number
fn find_missing_number(arr: &[i32], n: i32) -> i32 {
let total_sum = n * (n + 1) / 2;
let arr_sum: i32 = arr.iter().sum();
total_sum - arr_sum
}
fn demo_missing_number() {
let arr = [1, 2, 4, 5, 6]; // Missing 3 in 1..6
println!("Missing number: {}", find_missing_number(&arr, 6));
// Expected Output: "Missing number: 3"
}
Advanced Array Programs in Rust
- Two Sum Problem
use std::collections::HashMap;
fn two_sum(arr: &[i32], target: i32) -> Option<(usize, usize)> {
let mut seen = HashMap::new();
for (i, &num) in arr.iter().enumerate() {
if let Some(&j) = seen.get(&(target - num)) {
return Some((j, i));
}
seen.insert(num, i);
}
None
}
fn demo_two_sum() {
let arr = [2, 7, 11, 15];
println!("Two sum indices: {:?}", two_sum(&arr, 9));
// Expected Output: "Two sum indices: Some((0, 1))"
}
- Maximum Subarray Sum (Kadane's Algorithm)
fn max_subarray_sum(arr: &[i32]) -> i32 {
let mut max_sum = arr[0];
let mut current_sum = arr[0];
for &num in &arr[1..] {
current_sum = current_sum.max(num + current_sum);
max_sum = max_sum.max(current_sum);
}
max_sum
}
fn demo_max_subarray() {
let arr = [-2, 1, -3, 4, -1, 2, 1, -5, 4];
println!("Maximum subarray sum: {}", max_subarray_sum(&arr));
// Expected Output: "Maximum subarray sum: 6"
}
- Move Zeros to End
fn move_zeros(arr: &mut [i32]) {
let mut non_zero_idx = 0;
for i in 0..arr.len() {
if arr[i] != 0 {
arr.swap(i, non_zero_idx);
non_zero_idx += 1;
}
}
}
fn demo_move_zeros() {
let mut arr = [0, 1, 0, 3, 12];
move_zeros(&mut arr);
println!("After moving zeros: {:?}", arr);
// Expected Output: "After moving zeros: [1, 3, 12, 0, 0]"
}
- Find All Duplicates
fn find_all_duplicates(arr: &[i32]) -> Vec<i32> {
let mut seen = std::collections::HashSet::new();
let mut duplicates = Vec::new();
for &num in arr {
if !seen.insert(num) {
duplicates.push(num);
}
}
duplicates
}
fn demo_find_duplicates() {
let arr = [4, 3, 2, 7, 8, 2, 3, 1];
println!("All duplicates: {:?}", find_all_duplicates(&arr));
// Expected Output: "All duplicates: [2, 3]" (order may vary)
}
- Array Intersection
fn array_intersection(arr1: &[i32], arr2: &[i32]) -> Vec<i32> {
let set1: std::collections::HashSet<_> = arr1.iter().cloned().collect();
arr2.iter().filter(|&&x| set1.contains(&x)).cloned().collect()
}
fn demo_intersection() {
let arr1 = [1, 2, 2, 1];
let arr2 = [2, 2];
println!("Intersection: {:?}", array_intersection(&arr1, &arr2));
// Expected Output: "Intersection: [2]"
}