Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion solutions/brain_fuck/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "brain_fuck"
version = "0.1.0"
authors = ["OGordoo <marcosafonso8@hotmail.com>"]
edition = "2021"
edition = "2024"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
89 changes: 47 additions & 42 deletions solutions/brain_fuck/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,56 +1,61 @@
pub fn brainfuck(pattern: &str) {
let mut ds = vec![0 as i8; 5000];
let mut dp: usize = 0;
const STACK_MEM: usize = 2048;

let pattern_arr = pattern.chars().collect::<Vec<char>>();

let mut i: i32 = 0;

if pattern_arr.len() == 0 {
pub fn brainfuck(code: &str) {
if code.is_empty() {
return;
}
while i as usize <= (&pattern_arr).len() - 1 {
match &pattern_arr[i as usize] {
'>' => dp += 1,
'<' => dp -= 1,
'+' => ds[dp] = ds[dp] + 1,
'-' => ds[dp] = ds[dp] - 1,
'.' => {
print!("{}", ds[dp] as u8 as char);

let mut mem = [0i8; STACK_MEM];
let mut mp = 0;
let code = code.as_bytes();
let jumps = build_jumps(code);
let mut ip = 0;

while ip < code.len() {
match code[ip] {
b'>' => mp = (mp + 1) % STACK_MEM,
b'<' => mp = (mp + STACK_MEM - 1) % STACK_MEM,
b'+' => mem[mp] = mem[mp].wrapping_add(1),
b'-' => mem[mp] = mem[mp].wrapping_sub(1),
b'.' => print!("{}", mem[mp] as u8 as char),
b'[' => {
if mem[mp] == 0 {
ip = jumps[ip]
}
}
'[' => {
if ds[dp] == 0 {
let mut nc = 1;
while nc > 0 {
i += 1;
if pattern_arr[i as usize] == '[' {
nc += 1;
} else if pattern_arr[i as usize] == ']' {
nc -= 1;
}
}
b']' => {
if mem[mp] != 0 {
ip = jumps[ip]
}
}
']' => {
if ds[dp] != 0 {
let mut nc = 1;
while nc > 0 {
i -= 1;
if pattern_arr[i as usize] == ']' {
nc += 1;
} else if pattern_arr[i as usize] == '[' {
nc -= 1;
}
}
_ => (),
}
ip += 1;
}
}

fn build_jumps(code: &[u8]) -> Vec<usize> {
let mut jumps = vec![0; code.len()];
let mut stack = Vec::new();

for (i, &b) in code.iter().enumerate() {
match b {
b'[' => stack.push(i),
b']' => {
if let Some(start) = stack.pop() {
jumps[start] = i;
jumps[i] = start;
}
}
_ => {}
_ => (),
}
i += 1;
}

jumps
}

fn main() {
let args: Vec<String> = std::env::args().collect();
brainfuck(&args[1]);
if let Some(arg) = std::env::args().nth(1) {
brainfuck(&arg);
}
}
2 changes: 1 addition & 1 deletion solutions/check_user_name/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "check_user_name"
version = "0.1.0"
edition = "2021"
edition = "2024"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
12 changes: 6 additions & 6 deletions solutions/check_user_name/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ pub struct User {
}

impl User {
pub fn new(user: String, access_level: AccessLevel) -> User {
User {
pub const fn new(user: String, access_level: AccessLevel) -> Self {
Self {
access_level,
name: user,
}
}

pub fn send_name(&self) -> Option<&str> {
match &self.access_level {
pub const fn send_name(&self) -> Option<&str> {
match self.access_level {
AccessLevel::Guest => None,
_ => Some(&self.name),
_ => Some(self.name.as_str()),
}
}
}

pub fn check_user_name(user: &User) -> (bool, &str) {
pub const fn check_user_name(user: &User) -> (bool, &str) {
match user.send_name() {
Some(name) => (true, name),
None => (false, "ERROR: User is guest"),
Expand Down
2 changes: 1 addition & 1 deletion solutions/drop_the_blog/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "drop_the_blog"
version = "0.1.0"
edition = "2021"
edition = "2024"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
24 changes: 13 additions & 11 deletions solutions/drop_the_blog/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,23 @@ pub struct Blog {
}

impl Blog {
pub fn new() -> Blog {
Blog::default()
#[inline]
pub fn new() -> Self {
Default::default()
}

pub fn new_article(&self, body: String) -> (usize, Article) {
pub fn new_article(&self, body: String) -> (usize, Article<'_>) {
let new_article = Article::new(self.new_id(), body, self);
self.states.borrow_mut().push(false);
(new_article.id, new_article)
}

#[inline]
pub fn new_id(&self) -> usize {
self.states.borrow().len()
self.states.borrow().len() // const when borrow is stabilised
}

#[inline]
pub fn is_dropped(&self, id: usize) -> bool {
self.states.borrow()[id]
}
Expand All @@ -30,7 +33,7 @@ impl Blog {
panic!("{} is already dropped", id)
}
self.states.borrow_mut()[id] = true;
self.drops.set(self.drops.get() + 1);
self.drops.update(|x| x + 1);
}
}

Expand All @@ -42,16 +45,15 @@ pub struct Article<'a> {
}

impl<'a> Article<'a> {
pub fn new(id: usize, body: String, parent: &'a Blog) -> Article {
Article { id, body, parent }
pub const fn new(id: usize, body: String, parent: &'a Blog) -> Self {
Self { id, body, parent }
}

pub fn discard(self) {
drop(self);
}
#[inline]
pub fn discard(self) {}
}

impl<'a> Drop for Article<'a> {
impl Drop for Article<'_> {
fn drop(&mut self) {
self.parent.add_drop(self.id);
}
Expand Down
2 changes: 1 addition & 1 deletion solutions/flat_tree/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "flat_tree"
version = "0.1.0"
authors = ["Augusto <aug.ornelas@gmail.com>"]
edition = "2021"
edition = "2024"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
25 changes: 2 additions & 23 deletions solutions/flat_tree/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,6 @@
// convert a binary search tree into a sorted array

use std::collections::BTreeSet;

#[allow(dead_code)]
#[inline]
pub fn flatten_tree<T: ToOwned<Owned = T>>(tree: &BTreeSet<T>) -> Vec<T> {
let mut flat = Vec::new();
for v in tree {
flat.push(v.to_owned());
}
flat
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn it_works() {
let mut tree = BTreeSet::new();
tree.insert(3);
tree.insert(0);
tree.insert(9);
tree.insert(10);
assert_eq!(flatten_tree(&tree), &[0, 3, 9, 10]);
}
tree.iter().map(T::to_owned).collect()
}
2 changes: 1 addition & 1 deletion solutions/insertion_sort/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "insertion_sort"
version = "0.1.0"
authors = ["Augusto <aug.ornelas@gmail.com>"]
edition = "2021"
edition = "2024"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
58 changes: 5 additions & 53 deletions solutions/insertion_sort/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,58 +1,10 @@
// How to avoid that students use sort without creating a program to
// restrict functions in the code??
// Just use a grep?
// Implement the insertion sort algorithm but implement it in a step
// by step so we can test that each step is corresponding with the algorithm
pub fn insertion_sort(slice: &mut [i32], steps: usize) {
for i in 1..=steps.min(slice.len().saturating_sub(1)) {
let mut j = i;

// Insertion sort algorithmAlgorithm

// To sort an array of size n in ascending order:

// 1: Iterate from arr[1] to arr[n] over the array.

// 2: Compare the current element (key) to its predecessor.

// 3: If the key element is smaller than its predecessor, compare it
// to the elements before. Move the greater elements one position up
// to make space for the swapped element.

pub fn insertion_sort<T: Ord + Clone>(ar: &mut [T], steps: usize) {
assert!(steps > 0);
for i in 1..steps + 1 {
let key = ar[i].to_owned();
let mut j: i32 = i as i32 - 1;
while j >= 0 && key < ar[j as usize] {
// move the value to the next position
ar[(j + 1) as usize] = ar[j as usize].to_owned();
while j > 0 && slice[j] < slice[j - 1] {
slice.swap(j, j - 1);
j -= 1;
}
ar[(j + 1) as usize] = key
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn it_works() {
let mut target = [5, 3, 7, 2, 1, 6, 8, 4];
let len = target.len();
insertion_sort(&mut target, len - 1);
assert_eq!(&[1, 2, 3, 4, 5, 6, 7, 8], &target);
}

#[test]
fn test_first_step() {
let mut target = [5, 3, 7, 2, 1, 6, 8, 4];
insertion_sort(&mut target, 1);
assert_eq!(&[3, 5, 7, 2, 1, 6, 8, 4], &target);
}

#[test]
fn test_second_step() {
let mut target = [5, 3, 7, 2, 1, 6, 8, 4];
insertion_sort(&mut target, 2);
assert_eq!(&[3, 5, 7, 2, 1, 6, 8, 4], &target);
}
}
2 changes: 1 addition & 1 deletion solutions/inv_pyramid/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "inv_pyramid"
version = "0.1.0"
authors = ["lee <lee-dasilva@hotmail.com>"]
edition = "2021"
edition = "2024"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
32 changes: 5 additions & 27 deletions solutions/inv_pyramid/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,7 @@
// In general it's better to use `usize` rather than `u32` for variables that represent
// addressable memory. Like the index or length of a vector, slice or string
#[inline]
pub fn inv_pyramid(st: String, max: usize) -> Vec<String> {
// Vec::with_capacity() creates a buffer with the size that
// we define. This makes the first operation be more costly because it
// allocates the memory at that moment but make the push calls more efficient
// because it avoids extra allocation
// It's good to use it if you know the final length of
// the vector
let mut vec = Vec::with_capacity(2 * max);
// In truth the length of the vector will always be ( 2*max - 1 ) at the
// end, but it doesn't make a lot of difference to allocate an
// extra element and that way I don't have to handle the case
// where max == 0 which cause a subtraction in overflow

// Pushes a string with `amount` number of spaces and the string
// `st` repeated `amount` number of times
let mut create_line = |amount| vec.push(format!("{:>1$}", st.repeat(amount), 2 * amount));

for amount in 1..max + 1 {
create_line(amount)
}

// the `rev` method reverses the range
for amount in (1..max).rev() {
create_line(amount)
}
return vec;
(1..=max)
.chain((1..max).rev())
.map(|i| format!("{:>1$}", st.repeat(i), 2 * i))
.collect()
}
2 changes: 1 addition & 1 deletion solutions/nextprime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "nextprime"
version = "0.1.0"
authors = ["OGordoo <marcosafonso8@hotmail.com>"]
edition = "2021"
edition = "2024"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
Loading
Loading