diff --git a/euler.png b/euler.png
new file mode 100644
index 0000000..d19e14a
Binary files /dev/null and b/euler.png differ
diff --git a/readme.md b/readme.md
index aae5791..d2af165 100644
--- a/readme.md
+++ b/readme.md
@@ -1 +1,113 @@
-# readme coming soon
+
+
+
euler
+
+
+> My solutions to many of Project Euler's problems.
+
+All of the solutions here are written in rust. [main.rs](src/main.rs) is the home to my helper command line that can As per the rules of the challenge, I may only publish the solutions to the first 100 problems here, so I will stop after that but still continue the challenge.
+
+## Challenge Completion
+
+8 out of 100 public challenges completed.
+
+- [x] 1 - [Multiples of 3 or 5](src/bin/1.rs)
+- [x] 2 - [Even Fibonacci numbers](src/bin/2.rs)
+- [x] 3 - [Largest prime factor](src/bin/3.rs)
+- [x] 4 - [Largest palindrome product](src/bin/4.rs)
+- [x] 5 - [Smallest multiple](src/bin/5.rs)
+- [x] 6 - [Sum square difference](src/bin/6.rs)
+- [x] 7 - [10001st prime](src/bin/7.rs)
+- [x] 8 - [Largest product in a series](src/bin/8.rs)
+- [ ] 9 - Special Pythagorean triplet
+- [ ] 10 - Summation of primes
+- [ ] 11 - Largest product in a grid
+- [ ] 12 - Highly divisible triangular number
+- [ ] 13 - Large sum
+- [ ] 14 - Longest Collatz sequence
+- [ ] 15 - Lattice paths
+- [ ] 16 - Power digit sum
+- [ ] 17 - Number letter counts
+- [ ] 18 - Maximum path sum I
+- [ ] 19 - Counting Sundays
+- [ ] 20 - Factorial digit sum
+- [ ] 21 - Amicable numbers
+- [ ] 22 - Names scores
+- [ ] 23 - Non-abundant sums
+- [ ] 24 - Lexicographic permutations
+- [ ] 25 - 1000-digit Fibonacci number
+- [ ] 26 - Reciprocal cycles
+- [ ] 27 - Quadratic primes
+- [ ] 28 - Number spiral diagonals
+- [ ] 29 - Distinct powers
+- [ ] 30 - Digit fifth powers
+- [ ] 31 - Coin sums
+- [ ] 32 - Pandigital products
+- [ ] 33 - Digit cancelling fractions
+- [ ] 34 - Digit factorials
+- [ ] 35 - Circular primes
+- [ ] 36 - Double-base palindromes
+- [ ] 37 - Truncatable primes
+- [ ] 38 - Pandigital multiples
+- [ ] 39 - Integer right triangles
+- [ ] 40 - Champernowne's constant
+- [ ] 41 - Pandigital prime
+- [ ] 42 - Coded triangle numbers
+- [ ] 43 - Sub-string divisibility
+- [ ] 44 - Pentagon numbers
+- [ ] 45 - Triangular, pentagonal, and hexagonal
+- [ ] 46 - Goldbach's other conjecture
+- [ ] 47 - Distinct primes factors
+- [ ] 48 - Self powers
+- [ ] 49 - Prime permutations
+- [ ] 50 - Consecutive prime sum
+- [ ] 51 - Prime digit replacements
+- [ ] 52 - Permuted multiples
+- [ ] 53 - Combinatoric selections
+- [ ] 54 - Poker hands
+- [ ] 55 - Lychrel numbers
+- [ ] 56 - Powerful digit sum
+- [ ] 57 - Square root convergents
+- [ ] 58 - Spiral primes
+- [ ] 59 - XOR decryption
+- [ ] 60 - Prime pair sets
+- [ ] 61 - Cyclical figurate numbers
+- [ ] 62 - Cubic permutations
+- [ ] 63 - Powerful digit counts
+- [ ] 64 - Odd period square roots
+- [ ] 65 - Convergents of e
+- [ ] 66 - Diophantine equation
+- [ ] 67 - Maximum path sum II
+- [ ] 68 - Magic 5-gon ring
+- [ ] 69 - Totient maximum
+- [ ] 70 - Totient permutation
+- [ ] 71 - Ordered fractions
+- [ ] 72 - Counting fractions
+- [ ] 73 - Counting fractions in a range
+- [ ] 74 - Digit factorial chains
+- [ ] 75 - Singular integer right triangles
+- [ ] 76 - Counting summations
+- [ ] 77 - Prime summations
+- [ ] 78 - Coin partitions
+- [ ] 79 - Passcode derivation
+- [ ] 80 - Square root digital expansion
+- [ ] 81 - Path sum: two ways
+- [ ] 82 - Path sum: three ways
+- [ ] 83 - Path sum: four ways
+- [ ] 84 - Monopoly odds
+- [ ] 85 - Counting rectangles
+- [ ] 86 - Cuboid route
+- [ ] 87 - Prime power triples
+- [ ] 88 - Product-sum numbers
+- [ ] 89 - Roman numerals
+- [ ] 90 - Cube digit pairs
+- [ ] 91 - Right triangles with integer coordinates
+- [ ] 92 - Square digit chains
+- [ ] 93 - Arithmetic expressions
+- [ ] 94 - Almost equilateral triangles
+- [ ] 95 - Amicable chains
+- [ ] 96 - Su Doku
+- [ ] 97 - Large non-Mersenne prime
+- [ ] 98 - Anagramic squares
+- [ ] 99 - Largest exponential
+- [ ] 100 - Arranged probability
diff --git a/src/main.rs b/src/main.rs
index 1c13190..6203345 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,8 +1,9 @@
use clap::{Parser, Subcommand};
use owo_colors::OwoColorize;
-use std::{fs, path::Path, io::Write};
+use std::{fs::{self, File, OpenOptions}, path::Path, io::{Write, BufRead}};
use scraper::{Html, Selector};
use regex::Regex;
+use std::io::{BufReader};
#[derive(Parser)]
#[clap(about, author, version)]
@@ -19,7 +20,8 @@ enum Commands {
#[tokio::main]
async fn new() -> Result<(), Box> {
- let code_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("src").join("bin");
+ let base_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
+ let code_path = base_dir.join("src").join("bin");
let problem_number = requestty::prompt_one(
requestty::Question::int("problemNumber")
@@ -61,10 +63,10 @@ async fn new() -> Result<(), Box> {
// Fetch the problem information
let body = reqwest::get(format!("https://projecteuler.net/problem={problem_number}")).await?.text().await?;
- let document = Html::parse_document(Box::leak(body.into_boxed_str()));
+ let document = Html::parse_document(body.as_str());
let title_selector = Selector::parse("h2")?;
let content_selector = Selector::parse(".problem_content")?;
- let re = Regex::new(r"<[^>]*>").unwrap();
+ let html_tag_regex = Regex::new(r"<[^>]*>").unwrap();
let mut title = document
.select(&title_selector)
@@ -74,16 +76,14 @@ async fn new() -> Result<(), Box> {
.collect::>()
.join("");
- let mut problem = re
+ let mut problem = html_tag_regex
.replace_all(
- Box::leak(
- document
+ document
.select(&content_selector)
.next()
.unwrap()
.inner_html()
- .into_boxed_str()
- ),
+ .as_str(),
" "
)
.to_string()
@@ -110,11 +110,60 @@ fn main() {{
);
// Create the file
- let mut file = fs::File::create(code_path.join(format!("{problem_number}.rs"))).unwrap();
+ let mut file = File::create(code_path.join(format!("{problem_number}.rs"))).unwrap();
file.write(file_body.as_bytes()).unwrap();
drop(file);
- // todo: update readme
+ // Read the contents of the readme for editing
+ let readme_path = base_dir.join("readme.md");
+
+ let mut readme_file = OpenOptions::new()
+ .read(true)
+ .open(&readme_path)
+ .unwrap();
+
+ let mut readme_content = BufReader::new(&readme_file)
+ .lines()
+ .map(|s| s.unwrap())
+ .collect::>();
+
+
+ drop(readme_file);
+
+ // Mark the problem as done on the readme
+ let readme_regex = Regex::new(format!(" {problem_number} - (.*)").as_str()).unwrap();
+
+ for i in 0..readme_content.len() {
+ let line = readme_content[i].as_str();
+
+ if readme_regex.is_match(line) {
+ let matched = readme_regex.captures(line).unwrap();
+ readme_content[i] = format!("- [x] {problem_number} - [{}](src/bin/{problem_number}.rs)", &matched[1].trim());
+ }
+ }
+
+ // Update the summary statistics on the readme
+ let mut readme_string = readme_content.join("\n");
+
+ let completed_regex = Regex::new("([0-9]+)").unwrap();
+
+ let new_completed = completed_regex
+ .captures(readme_string.as_str())
+ .unwrap()[1]
+ .parse::()
+ .unwrap() + 1;
+
+ readme_string = completed_regex.replace(readme_string.as_str(), format!("{new_completed}")).to_string();
+
+ // Write the new content to the readme
+ readme_file = OpenOptions::new()
+ .write(true)
+ .open(&readme_path)
+ .unwrap();
+
+ readme_file.write(readme_string.as_bytes()).unwrap();
+
+ drop(readme_file);
// Announce completion!
println!("{}", "File successfully created! Good luck (:".green());