fix/logic bug

This commit is contained in:
itsscb 2024-06-12 01:19:39 +02:00
parent 360efb1a6e
commit 236fed176d
9 changed files with 133 additions and 27 deletions

View File

@ -9,3 +9,10 @@ shuttle-axum = "0.45.0"
shuttle-runtime = "0.45.0" shuttle-runtime = "0.45.0"
tokio = "1.28.2" tokio = "1.28.2"
tower-http = { version = "0.5.2", features = ["fs"] } tower-http = { version = "0.5.2", features = ["fs"] }
[workspace]
members = [
".",
"frontend",
]

View File

@ -14,3 +14,4 @@ yewdux = "0.10.0"
serde = "1.0.198" serde = "1.0.198"
serde_json = "1.0.116" serde_json = "1.0.116"
regex = "1.10.4" regex = "1.10.4"

View File

@ -1,6 +1,6 @@
<!doctype html><html lang=en><meta charset=UTF-8><meta content="width=device-width,initial-scale=1" name=viewport><title>wordl</title><link href=/styles-5be5e26778525bb4.css integrity=sha384-BFc0SAke1_1dylfdy26EEHJElxQCLB-DE7o_4TXFLpItCL4On0ZXkSV61ifrEl87 rel=stylesheet><link href=public/manifest.json rel=manifest><link as=fetch crossorigin href=/wordl-frontend-c8a90ba45d8538e2fa10a93a59efc670c56042558df3bd7fc15e94fdd8e80ddca15caab6ae49a4cca1f0d15c672579f6_bg.wasm integrity=sha384-yKkLpF2FOOL6EKk6We_GcMVgQlWN871_wV6U_djoDdyhXKq2rkmkzKHw0VxnJXn2 rel=preload type=application/wasm><link crossorigin href=/wordl-frontend-c8a90ba45d8538e2fa10a93a59efc670c56042558df3bd7fc15e94fdd8e80ddca15caab6ae49a4cca1f0d15c672579f6.js integrity=sha384-11cb5IDDMqXRsD7jZGwK_btLm367n9RZF99RgVEfdaioOs8aq6KMkV2cbp4q0rZR rel=modulepreload></head><body class="bg-black text-white"><script type=module> <!doctype html><html lang=en><meta charset=UTF-8><meta content="width=device-width,initial-scale=1" name=viewport><title>wordl</title><link href=/styles-5be5e26778525bb4.css integrity=sha384-BFc0SAke1_1dylfdy26EEHJElxQCLB-DE7o_4TXFLpItCL4On0ZXkSV61ifrEl87 rel=stylesheet><link href=public/manifest.json rel=manifest><link as=fetch crossorigin href=/wordl-frontend-421403a0bf0fc1dd87e39290748fb0fd1d0011ad9d39c436612b9d175949ff30f7f20814f79234fe65bf2a8cf40890a2_bg.wasm integrity=sha384-QhQDoL8Pwd2H45KQdI-w_R0AEa2dOcQ2YSudF1lJ_zD38ggU95I0_mW_Koz0CJCi rel=preload type=application/wasm><link crossorigin href=/wordl-frontend-421403a0bf0fc1dd87e39290748fb0fd1d0011ad9d39c436612b9d175949ff30f7f20814f79234fe65bf2a8cf40890a2.js integrity=sha384-zFzbv1bQho_A-EsUClHqrakXgf-m71aVFaJe-WLfJ7mTNYsbbpvqd3cABILbxMoq rel=modulepreload></head><body class="bg-black text-white"><script type=module>
import init, * as bindings from '/wordl-frontend-c8a90ba45d8538e2fa10a93a59efc670c56042558df3bd7fc15e94fdd8e80ddca15caab6ae49a4cca1f0d15c672579f6.js'; import init, * as bindings from '/wordl-frontend-421403a0bf0fc1dd87e39290748fb0fd1d0011ad9d39c436612b9d175949ff30f7f20814f79234fe65bf2a8cf40890a2.js';
init('/wordl-frontend-c8a90ba45d8538e2fa10a93a59efc670c56042558df3bd7fc15e94fdd8e80ddca15caab6ae49a4cca1f0d15c672579f6_bg.wasm'); init('/wordl-frontend-421403a0bf0fc1dd87e39290748fb0fd1d0011ad9d39c436612b9d175949ff30f7f20814f79234fe65bf2a8cf40890a2_bg.wasm');
window.wasmBindings = bindings; window.wasmBindings = bindings;
</script></body></html> </script></body></html>

View File

@ -2,32 +2,135 @@ pub mod pages;
pub mod router; pub mod router;
pub mod storage; pub mod storage;
use std::collections::HashSet; use std::collections::HashMap;
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
enum CharStatus<T> { enum CharStatus<T> {
NotContained(T), NotContained(T),
Contained(T), Contained(T),
Match(T), Match(T),
Unknown,
} }
fn compare_strings(s1: &str, s2: &str) -> Vec<CharStatus<String>> { fn compare_strings(s1: &str, s2: &str) -> Vec<CharStatus<String>> {
if s1.len() != s2.len() { let mut result: Vec<CharStatus<String>> = Vec::with_capacity(s1.len());
panic!("Strings must have the same length"); result.resize_with(s1.len(), || CharStatus::Unknown);
let mut s1_char_count: HashMap<char, usize> = HashMap::new();
let mut s2_char_count: HashMap<char, usize> = HashMap::new();
for c in s1.chars() {
*s1_char_count.entry(c).or_insert(0) += 1;
} }
let mut result = Vec::with_capacity(s1.len()); for ((c1, c2), res) in s1.chars().zip(s2.chars()).zip(result.iter_mut()) {
let s1_chars: HashSet<char> = s1.chars().collect();
for (c1, c2) in s1.chars().zip(s2.chars()) {
if c1 == c2 { if c1 == c2 {
result.push(CharStatus::Match(c2.to_string())); *res = CharStatus::Match(c2.to_string());
} else if s1_chars.contains(&c2) { *s2_char_count.entry(c2).or_insert(0) += 1;
result.push(CharStatus::Contained(c2.to_string()));
} else { } else {
result.push(CharStatus::NotContained(c2.to_string())); *res = CharStatus::Unknown;
}
}
for (res, c2) in result.iter_mut().zip(s2.chars()) {
match res {
CharStatus::Unknown => {
let c1_count = s1_char_count.get(&c2).unwrap_or(&0);
let c2_count = s2_char_count.get(&c2).unwrap_or(&0);
if *c1_count > 0 && c1_count > c2_count {
*res = CharStatus::Contained(c2.to_string());
*s2_char_count.entry(c2).or_insert(0) += 1;
} else {
*res = CharStatus::NotContained(c2.to_string());
}
}
_ => {}
} }
} }
result result
} }
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_compare_strings() {
let source = "HALLO";
let want = vec![
CharStatus::NotContained("0".to_owned()),
CharStatus::NotContained("0".to_owned()),
CharStatus::NotContained("0".to_owned()),
CharStatus::NotContained("0".to_owned()),
CharStatus::NotContained("0".to_owned()),
];
let input = "00000";
let got = compare_strings(source, input);
assert_eq!(want, got);
let source = "HALLO";
let want = vec![
CharStatus::NotContained("L".to_owned()),
CharStatus::NotContained("L".to_owned()),
CharStatus::Match("L".to_owned()),
CharStatus::Match("L".to_owned()),
CharStatus::NotContained("L".to_owned()),
];
let input = "LLLLL";
let got = compare_strings(source, input);
assert_eq!(want, got);
let want = vec![
CharStatus::Match("H".to_owned()),
CharStatus::Match("A".to_owned()),
CharStatus::Match("L".to_owned()),
CharStatus::Match("L".to_owned()),
CharStatus::Match("O".to_owned()),
];
let input = "HALLO";
let got = compare_strings(source, input);
assert_eq!(want, got);
let want = vec![
CharStatus::Match("H".to_owned()),
CharStatus::NotContained("L".to_owned()),
CharStatus::Match("L".to_owned()),
CharStatus::Match("L".to_owned()),
CharStatus::Match("O".to_owned()),
];
let input = "HLLLO";
let got = compare_strings(source, input);
assert_eq!(want, got);
let want = vec![
CharStatus::Match("H".to_owned()),
CharStatus::Contained("L".to_owned()),
CharStatus::Match("L".to_owned()),
CharStatus::NotContained("I".to_owned()),
CharStatus::NotContained("L".to_owned()),
];
let input = "HLLIL";
let got = compare_strings(source, input);
assert_eq!(want, got);
let want = vec![
CharStatus::Contained("L".to_owned()),
CharStatus::NotContained("L".to_owned()),
CharStatus::Match("L".to_owned()),
CharStatus::Contained("A".to_owned()),
CharStatus::Match("O".to_owned()),
];
let input = "LLLAO";
let got = compare_strings(source, input);
assert_eq!(want, got);
}
}

View File

@ -1,7 +1,5 @@
use yew::prelude::*; use yew::prelude::*;
use yew::{classes, function_component, html, Callback, Html, NodeRef}; use yew::{classes, function_component, html, Callback, Html};
use crate::router::Route;
use crate::CharStatus; use crate::CharStatus;
@ -38,6 +36,9 @@ fn string_to_html(input: &Vec<CharStatus<String>>) -> Html {
classes.push("border-2"); classes.push("border-2");
s s
} }
_ => {
""
},
}; };
html!{ html!{
<li <li
@ -56,7 +57,7 @@ fn string_to_html(input: &Vec<CharStatus<String>>) -> Html {
#[function_component] #[function_component]
pub fn Home() -> Html { pub fn Home() -> Html {
let got_word = "HALLO"; let got_word = "HALLO";
let mut submitted_words = yew::use_state(|| vec![]); let submitted_words = yew::use_state(|| vec![]);
let input = yew::use_state(|| { let input = yew::use_state(|| {
vec![ vec![
"".to_owned(), "".to_owned(),
@ -70,7 +71,7 @@ pub fn Home() -> Html {
let on_submit = { let on_submit = {
let input = input.clone(); let input = input.clone();
let submitted_words = submitted_words.clone(); let submitted_words = submitted_words.clone();
Callback::from(move |event: MouseEvent| { Callback::from(move |_: MouseEvent| {
let mut new_items = (*submitted_words).clone(); let mut new_items = (*submitted_words).clone();
new_items.push(crate::compare_strings(&got_word, &input.join(""))); new_items.push(crate::compare_strings(&got_word, &input.join("")));
submitted_words.set(new_items); submitted_words.set(new_items);
@ -111,9 +112,6 @@ pub fn Home() -> Html {
}) })
}; };
// let mut submitted_words = vec![];
let res = crate::compare_strings(got_word, "HLLAI");
html! { html! {
<div <div
class={ class={

View File

@ -1,7 +1,4 @@
use yew::{classes, function_component, html, Html}; use yew::{function_component, html, Html};
use yew_router::prelude::Link;
use crate::router::Route;
#[function_component] #[function_component]
pub fn Settings() -> Html { pub fn Settings() -> Html {