feat: adding in initial generator that takes regexes, words, and generates a list of answers
This commit is contained in:
parent
0f8af5e718
commit
f9556804d7
@ -1,3 +1,8 @@
|
|||||||
# regexle
|
# Regexle
|
||||||
|
|
||||||
|
Regex focused cross-word puzzle generator
|
||||||
|
|
||||||
|
## Data flow
|
||||||
|
![data-flow.png](docs/data-flow.png)
|
||||||
|
[(raw-excalidraw-file)](docs/data-flow.excalidraw)
|
||||||
|
|
||||||
Regex-only crossword generation and site
|
|
11
checker/Cargo.toml
Normal file
11
checker/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "regex-checker"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
csv = "1.3.0"
|
||||||
|
fancy-regex = "0.13.0"
|
||||||
|
rayon = "1.10.0"
|
||||||
|
serde = "1.0.209"
|
||||||
|
serde_derive = "1.0.209"
|
4053
checker/processed_answers.csv
Normal file
4053
checker/processed_answers.csv
Normal file
File diff suppressed because it is too large
Load Diff
4
checker/regex.csv
Normal file
4
checker/regex.csv
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
^(?!.*(.).*\1)[abcdefghijklmnopqrstuvwxyz]+$
|
||||||
|
^(?!.*(.).*\1)[hijklmn]+$
|
||||||
|
^(?!.*(.).*\1)[opqrst]+$
|
||||||
|
^(?!.*(.).*\1)[uvwxyz]+$
|
|
53
checker/src/main.rs
Normal file
53
checker/src/main.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::string::String;
|
||||||
|
use std::error::Error;
|
||||||
|
use fancy_regex::Regex;
|
||||||
|
use rayon::iter::{IntoParallelIterator, IntoParallelRefIterator};
|
||||||
|
use rayon::iter::ParallelIterator;
|
||||||
|
use crate::utils::{read_csv, read_lines, write_to_csv};
|
||||||
|
use crate::word::{Answer, Word};
|
||||||
|
|
||||||
|
mod word;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
|
|
||||||
|
fn map_to_answers(regex: String, words: &Vec<Word>) -> Vec<Answer> {
|
||||||
|
let re = Regex::new(&*regex).unwrap();
|
||||||
|
let answers: Vec<Answer> = words.par_iter()
|
||||||
|
.filter(|w| re.is_match(&*w.word).unwrap_or(false))
|
||||||
|
.map(|word| Answer {
|
||||||
|
count: word.count,
|
||||||
|
question: regex.clone(),
|
||||||
|
answer: word.word.clone(),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
answers
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_answers(regexes: Vec<String>, words: &Vec<Word>) -> Result<Vec<Answer>, Box<dyn Error>> {
|
||||||
|
let answers = regexes.par_iter()
|
||||||
|
.map(|regex| { map_to_answers(regex.to_string(), words) })
|
||||||
|
.filter(|vec| vec.len() > 0)
|
||||||
|
.flatten()
|
||||||
|
.collect();
|
||||||
|
Ok(answers)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
println!("Hello, world!");
|
||||||
|
|
||||||
|
|
||||||
|
let regex_chart = "./regex.csv";
|
||||||
|
let regexes = read_lines(regex_chart)?;
|
||||||
|
|
||||||
|
let word_freq_chart = "./word_freq.csv";
|
||||||
|
let mut words = read_csv(word_freq_chart)?;
|
||||||
|
words.truncate(10000);
|
||||||
|
let processed_words: Vec<Word> = words.into_par_iter().filter(|word| word.word.len() > 2).collect();
|
||||||
|
|
||||||
|
let answers = create_answers(regexes, &processed_words)?;
|
||||||
|
println!("Answers: {:?}", answers);
|
||||||
|
|
||||||
|
write_to_csv(answers, "processed_answers.csv")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
47
checker/src/utils.rs
Normal file
47
checker/src/utils.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use std::error::Error;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{self, BufRead};
|
||||||
|
use std::path::Path;
|
||||||
|
use csv::{QuoteStyle, ReaderBuilder, WriterBuilder};
|
||||||
|
use crate::word::{Answer, Word};
|
||||||
|
|
||||||
|
pub fn read_csv(file_path: &str) -> Result<Vec<Word>, Box<dyn Error>> {
|
||||||
|
let file = File::open(file_path)?;
|
||||||
|
let mut rdr = ReaderBuilder::new().has_headers(true).from_reader(file);
|
||||||
|
let mut records = Vec::new();
|
||||||
|
|
||||||
|
for result in rdr.deserialize() {
|
||||||
|
let record: Word = result?;
|
||||||
|
records.push(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(records)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn write_to_csv(records: Vec<Answer>, path: &str) -> Result<(), Box<dyn Error>> {
|
||||||
|
// Create a new CSV writer with the file path
|
||||||
|
let file = File::create(path)?;
|
||||||
|
let mut wtr = WriterBuilder::new()
|
||||||
|
.quote_style(QuoteStyle::Always)
|
||||||
|
.from_writer(file);
|
||||||
|
|
||||||
|
// Write the records with headers
|
||||||
|
for record in records {
|
||||||
|
wtr.serialize(record)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure all data is written to the file
|
||||||
|
wtr.flush()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_lines<P>(filename: P) -> io::Result<Vec<String>>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let file = File::open(filename)?;
|
||||||
|
let buf = io::BufReader::new(file);
|
||||||
|
|
||||||
|
buf.lines().collect()
|
||||||
|
}
|
14
checker/src/word.rs
Normal file
14
checker/src/word.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct Word {
|
||||||
|
pub(crate) word: String,
|
||||||
|
pub(crate) count: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Answer {
|
||||||
|
pub(crate) question: String,
|
||||||
|
pub(crate) answer: String,
|
||||||
|
pub(crate) count: i64,
|
||||||
|
}
|
333334
checker/word_freq.csv
Normal file
333334
checker/word_freq.csv
Normal file
File diff suppressed because it is too large
Load Diff
1194
docs/data-flow.excalidraw
Normal file
1194
docs/data-flow.excalidraw
Normal file
File diff suppressed because it is too large
Load Diff
BIN
docs/data-flow.png
Normal file
BIN
docs/data-flow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 183 KiB |
@ -1,82 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "excalidraw",
|
|
||||||
"version": 2,
|
|
||||||
"source": "https://excalidraw-jetbrains-plugin",
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"id": "oC8LgfrGVs7Ww4Lpe1PEj",
|
|
||||||
"type": "rectangle",
|
|
||||||
"x": 290,
|
|
||||||
"y": 125,
|
|
||||||
"width": 262,
|
|
||||||
"height": 167,
|
|
||||||
"angle": 0,
|
|
||||||
"strokeColor": "#1e1e1e",
|
|
||||||
"backgroundColor": "transparent",
|
|
||||||
"fillStyle": "solid",
|
|
||||||
"strokeWidth": 2,
|
|
||||||
"strokeStyle": "solid",
|
|
||||||
"roughness": 1,
|
|
||||||
"opacity": 100,
|
|
||||||
"groupIds": [],
|
|
||||||
"frameId": null,
|
|
||||||
"roundness": {
|
|
||||||
"type": 3
|
|
||||||
},
|
|
||||||
"seed": 31779651,
|
|
||||||
"version": 19,
|
|
||||||
"versionNonce": 206623949,
|
|
||||||
"isDeleted": false,
|
|
||||||
"boundElements": [
|
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"id": "-e5FUpE-nI0s-KaM54PWT"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"updated": 1725243919617,
|
|
||||||
"link": null,
|
|
||||||
"locked": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "-e5FUpE-nI0s-KaM54PWT",
|
|
||||||
"type": "text",
|
|
||||||
"x": 336.73009490966797,
|
|
||||||
"y": 196,
|
|
||||||
"width": 168.53981018066406,
|
|
||||||
"height": 25,
|
|
||||||
"angle": 0,
|
|
||||||
"strokeColor": "#1e1e1e",
|
|
||||||
"backgroundColor": "transparent",
|
|
||||||
"fillStyle": "solid",
|
|
||||||
"strokeWidth": 2,
|
|
||||||
"strokeStyle": "solid",
|
|
||||||
"roughness": 1,
|
|
||||||
"opacity": 100,
|
|
||||||
"groupIds": [],
|
|
||||||
"frameId": null,
|
|
||||||
"roundness": null,
|
|
||||||
"seed": 1603354339,
|
|
||||||
"version": 16,
|
|
||||||
"versionNonce": 1210522317,
|
|
||||||
"isDeleted": false,
|
|
||||||
"boundElements": null,
|
|
||||||
"updated": 1725243923457,
|
|
||||||
"link": null,
|
|
||||||
"locked": false,
|
|
||||||
"text": "Test Image Here",
|
|
||||||
"fontSize": 20,
|
|
||||||
"fontFamily": 1,
|
|
||||||
"textAlign": "center",
|
|
||||||
"verticalAlign": "middle",
|
|
||||||
"baseline": 18,
|
|
||||||
"containerId": "oC8LgfrGVs7Ww4Lpe1PEj",
|
|
||||||
"originalText": "Test Image Here",
|
|
||||||
"lineHeight": 1.25
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"appState": {
|
|
||||||
"gridSize": null,
|
|
||||||
"viewBackgroundColor": "#ffffff"
|
|
||||||
},
|
|
||||||
"files": {}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user