this is dumb

This commit is contained in:
Pagwin 2025-11-09 22:05:23 -05:00
commit ede227f887
No known key found for this signature in database
GPG key ID: 81137023740CA260
6 changed files with 15436 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

7
Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "wordle-crush"
version = "0.1.0"

6
Cargo.toml Normal file
View file

@ -0,0 +1,6 @@
[package]
name = "wordle-crush"
version = "0.1.0"
edition = "2024"
[dependencies]

2315
src/all-actual.txt Normal file

File diff suppressed because it is too large Load diff

12972
src/all-possible.txt Normal file

File diff suppressed because it is too large Load diff

135
src/main.rs Normal file
View file

@ -0,0 +1,135 @@
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
enum Guess {
Correct,
InWord,
NotInWord,
}
fn main() {
let possible_words_read_only = &*Box::leak(
include_str!("all-possible.txt")
.split('\n')
.filter(|w| w.len() == 5)
.collect::<Box<[&'static str]>>(),
);
let mut possible_words = possible_words_read_only
.iter()
.cloned()
.collect::<Vec<&'static str>>();
let actual_words_read_only = &*Box::leak(
include_str!("all-actual.txt")
.split('\n')
.filter(|w| w.len() == 5)
.collect::<Box<[&'static str]>>(),
);
let mut actual_words = actual_words_read_only
.iter()
.cloned()
.collect::<Vec<&'static str>>();
let patterns = {
let mut tmp = std::io::stdin()
.lines()
.filter_map(|line| {
let tmp = line
.unwrap()
.to_uppercase()
.chars()
.map(|c| match c {
'G' => Some(Guess::Correct),
'Y' => Some(Guess::InWord),
'_' => Some(Guess::NotInWord),
_ => None,
})
.collect::<Vec<Option<Guess>>>();
if tmp.iter().any(Option::is_none) {
None
} else {
// bruh
Some([
tmp[0].as_ref().unwrap().clone(),
tmp[1].as_ref().unwrap().clone(),
tmp[2].as_ref().unwrap().clone(),
tmp[3].as_ref().unwrap().clone(),
tmp[4].as_ref().unwrap().clone(),
])
}
})
.collect::<Vec<[Guess; 5]>>();
tmp.sort_unstable();
let mut dedupped: Vec<([Guess; 5], usize)> = Vec::new();
for elem in tmp {
if dedupped.is_empty() {
dedupped.push((elem, 1));
continue;
}
let d_len = dedupped.len();
if dedupped[d_len - 1].0 == elem {
dedupped[d_len - 1].1 += 1;
} else {
dedupped.push((elem, 1));
}
}
dedupped.into_boxed_slice()
};
std::thread::scope(|scope| {
let box_ref = patterns.as_ref();
scope.spawn(|| {
for (pattern, pattern_count) in box_ref.iter() {
filter_pass(
&mut actual_words,
possible_words_read_only,
pattern,
*pattern_count,
);
}
});
scope.spawn(|| {
for (pattern, pattern_count) in box_ref.iter() {
filter_pass(
&mut possible_words,
possible_words_read_only,
pattern,
*pattern_count,
);
}
});
});
println!("likely words: {}", actual_words.join("\n"));
println!("possible words: {}", possible_words.join("\n"));
}
fn filter_pass(
current_words: &mut Vec<&'static str>,
word_list: &'static [&'static str],
pattern: &[Guess; 5],
pattern_count: usize,
) {
*current_words = current_words
.into_iter()
.filter(|word| {
word_list
.iter()
.filter(|pattern_match| *pattern == word_match(word, pattern_match))
.count()
>= pattern_count
})
// this is dumb
.map(|w| *w)
.collect()
}
fn word_match(word: &str, other_word: &str) -> [Guess; 5] {
let other_word_chars = other_word.chars().collect::<Box<[char]>>();
let mut ret: [Option<Guess>; 5] = [None; 5];
for (i, c) in word.chars().enumerate() {
if other_word_chars[i] == c {
ret[i] = Some(Guess::Correct);
} else if other_word_chars.contains(&c) {
ret[i] = Some(Guess::InWord);
} else {
ret[i] = Some(Guess::NotInWord);
}
}
ret.map(Option::unwrap)
}