Skip to content
This repository was archived by the owner on Apr 26, 2026. It is now read-only.

Commit e9b0484

Browse files
authored
Merge pull request #1 from Gridness/mvp
Mvp
2 parents 6f0b1e1 + 03c06e5 commit e9b0484

5 files changed

Lines changed: 230 additions & 0 deletions

File tree

.github/workflows/rust.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Rust CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
- name: Install Rust
18+
uses: dtolnay/rust-toolchain@stable
19+
- name: Build
20+
run: cargo build --verbose
21+
- name: Run tests
22+
run: cargo test --verbose
23+
24+
lint:
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v4
28+
- name: Install Rust
29+
uses: dtolnay/rust-toolchain@stable
30+
with:
31+
components: clippy, rustfmt
32+
- name: Check formatting
33+
run: cargo fmt -- --check
34+
- name: Run clippy
35+
run: cargo clippy -- -D warnings
36+
37+
sast:
38+
runs-on: ubuntu-latest
39+
steps:
40+
- uses: actions/checkout@v4
41+
- name: Install Rust
42+
uses: dtolnay/rust-toolchain@stable
43+
- name: Install cargo-audit
44+
run: cargo install cargo-audit
45+
- name: Run cargo-audit
46+
run: cargo audit
47+
- name: Install cargo-deny
48+
run: cargo install cargo-deny
49+
- name: Run cargo-deny
50+
run: cargo deny check

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target

Cargo.lock

Lines changed: 92 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "rustroika"
3+
version = "1.0.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
colored = "3.0.0"

src/main.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
use colored::*;
2+
3+
fn main() {
4+
let args: Vec<String> = std::env::args().collect();
5+
6+
if args.len() != 4 {
7+
eprintln!(
8+
"{}",
9+
format!(
10+
"Usage: {} <trips/week> <monthly_cost> <ticket_price>",
11+
args[0]
12+
)
13+
.red()
14+
);
15+
std::process::exit(1);
16+
}
17+
18+
let trips_per_week: u32 = args[1].parse().expect("Invalid trips per week");
19+
let monthly_cost: u32 = args[2].parse().expect("Invalid monthly cost");
20+
let ticket_price: u32 = args[3].parse().expect("Invalid ticket price");
21+
22+
let total_trips = trips_per_week * 4;
23+
let full_price_count = (total_trips + 1) / 2;
24+
let discounted_count = total_trips / 2;
25+
26+
let individual_cost = full_price_count * ticket_price + discounted_count * (ticket_price / 2);
27+
28+
println!(
29+
"\n╭{}╴{}╴{}╴{}╴╮",
30+
"─".repeat(14),
31+
"─".repeat(10),
32+
"─".repeat(14),
33+
"─".repeat(17)
34+
);
35+
println!(
36+
"│ {:14} │ {:10} │ {:14} │ {:10} │",
37+
"Total trips".cyan().bold(),
38+
"Monthly".cyan().bold(),
39+
"Individual".cyan().bold(),
40+
"Ticket".cyan().bold()
41+
);
42+
println!(
43+
"│ {:14} │ {:>10} │ {:>14} │ {:>10} │",
44+
format!("{}", total_trips).yellow(),
45+
format!("{} RUB", monthly_cost).yellow(),
46+
format!("{} RUB", individual_cost).yellow(),
47+
format!("{} RUB", ticket_price).yellow()
48+
);
49+
println!(
50+
"╰{}╴{}╴{}╴{}╯",
51+
"─".repeat(14),
52+
"─".repeat(10),
53+
"─".repeat(14),
54+
"─".repeat(18)
55+
);
56+
57+
let message = match individual_cost.cmp(&monthly_cost) {
58+
std::cmp::Ordering::Less => format!(
59+
"🚌 Paying per trip is cheaper by {} RUB!",
60+
monthly_cost - individual_cost
61+
)
62+
.green()
63+
.bold(),
64+
std::cmp::Ordering::Greater => format!(
65+
"💰 Monthly pass saves you {} RUB!",
66+
individual_cost - monthly_cost
67+
)
68+
.bright_green()
69+
.bold(),
70+
std::cmp::Ordering::Equal => "⚖️ Both options cost the same".blue().bold(),
71+
};
72+
73+
println!("\n{}\n", message);
74+
75+
// Add explanation of discount logic
76+
println!("{}", "Note:".bold().underline());
77+
println!("• Subsequent trips within 90 minutes get 50% discount");
78+
println!("• Discounted prices are rounded down (e.g., 63 → 31)");
79+
println!("• Calculation assumes optimal discount usage");
80+
}

0 commit comments

Comments
 (0)