mirror of
https://github.com/supleed2/cch23-8bit.git
synced 2024-12-22 14:05:48 +00:00
Day 15
This commit is contained in:
parent
320360ac9e
commit
e4a1d23e67
15
Cargo.lock
generated
15
Cargo.lock
generated
|
@ -431,9 +431,11 @@ dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"chrono",
|
"chrono",
|
||||||
"image",
|
"image",
|
||||||
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"sha256",
|
||||||
"shuttle-axum",
|
"shuttle-axum",
|
||||||
"shuttle-runtime",
|
"shuttle-runtime",
|
||||||
"shuttle-shared-db",
|
"shuttle-shared-db",
|
||||||
|
@ -2541,6 +2543,19 @@ dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha256"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7895c8ae88588ccead14ff438b939b0c569cd619116f14b4d13fdff7b8333386"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"bytes",
|
||||||
|
"hex",
|
||||||
|
"sha2",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sharded-slab"
|
name = "sharded-slab"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
|
|
|
@ -11,9 +11,11 @@ axum-extra = { version = "0.9.0", features = ["typed-header"] }
|
||||||
base64 = "0.21.5"
|
base64 = "0.21.5"
|
||||||
chrono = { version = "0.4.31", default-features = false, features = ["std"] }
|
chrono = { version = "0.4.31", default-features = false, features = ["std"] }
|
||||||
image = "0.24.7"
|
image = "0.24.7"
|
||||||
|
regex = "1.10.2"
|
||||||
reqwest = { version = "0.11.22", features = ["json"] }
|
reqwest = { version = "0.11.22", features = ["json"] }
|
||||||
serde = { version = "1.0.193", features = ["derive"] }
|
serde = { version = "1.0.193", features = ["derive"] }
|
||||||
serde_json = "1.0.108"
|
serde_json = "1.0.108"
|
||||||
|
sha256 = "1.4.0"
|
||||||
shuttle-axum = { version = "0.35.0", default-features = false, features = ["axum-0-7"] }
|
shuttle-axum = { version = "0.35.0", default-features = false, features = ["axum-0-7"] }
|
||||||
shuttle-runtime = "0.35.0"
|
shuttle-runtime = "0.35.0"
|
||||||
shuttle-shared-db = { version = "0.35.1", features = ["postgres"] }
|
shuttle-shared-db = { version = "0.35.1", features = ["postgres"] }
|
||||||
|
|
117
src/cal/day15.rs
Normal file
117
src/cal/day15.rs
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
use axum::{http::StatusCode, response::IntoResponse, routing::post, Json, Router};
|
||||||
|
|
||||||
|
pub(crate) fn router() -> Router {
|
||||||
|
Router::new()
|
||||||
|
.route("/15/nice", post(nice))
|
||||||
|
.route("/15/game", post(game))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize)]
|
||||||
|
struct Nice {
|
||||||
|
input: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn nice(Json(Nice { input }): Json<Nice>) -> impl IntoResponse {
|
||||||
|
let vowels = input
|
||||||
|
.chars()
|
||||||
|
.filter(|&c| c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'y')
|
||||||
|
.count();
|
||||||
|
let repeat = input
|
||||||
|
.as_bytes()
|
||||||
|
.windows(2)
|
||||||
|
.any(|c| c[0].is_ascii_alphabetic() && c[0] == c[1]);
|
||||||
|
let substrs = input.contains("ab")
|
||||||
|
|| input.contains("cd")
|
||||||
|
|| input.contains("pq")
|
||||||
|
|| input.contains("xy");
|
||||||
|
if vowels > 2 && repeat && !substrs {
|
||||||
|
(StatusCode::OK, "{\"result\":\"nice\"}".to_string())
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
|
"{\"result\":\"naughty\"}".to_string(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Serialize)]
|
||||||
|
struct Game {
|
||||||
|
result: String,
|
||||||
|
reason: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn game(Json(Nice { input }): Json<Nice>) -> (StatusCode, Json<Game>) {
|
||||||
|
let code;
|
||||||
|
let result;
|
||||||
|
let reason;
|
||||||
|
let r1 = input.len() >= 8;
|
||||||
|
let r2 = input.chars().any(|c| c.is_ascii_uppercase())
|
||||||
|
&& input.chars().any(|c| c.is_ascii_lowercase())
|
||||||
|
&& input.chars().any(|c| c.is_ascii_digit());
|
||||||
|
let r3 = input.chars().filter(char::is_ascii_digit).count() >= 5;
|
||||||
|
let r4 = regex::Regex::new(r"\d+")
|
||||||
|
.expect("Regex should be valid")
|
||||||
|
.captures_iter(&input)
|
||||||
|
.map(|c| c.extract::<0>().0)
|
||||||
|
.map(|s| s.parse::<i32>().expect("All matches are only digits"))
|
||||||
|
.sum::<i32>()
|
||||||
|
== 2023;
|
||||||
|
let r5 = regex::Regex::new(r".*j.*o.*y.*")
|
||||||
|
.expect("Regex should be valid")
|
||||||
|
.is_match(&input)
|
||||||
|
&& input.chars().filter(|&c| c == 'j').count() == 1
|
||||||
|
&& input.chars().filter(|&c| c == 'o').count() == 1
|
||||||
|
&& input.chars().filter(|&c| c == 'y').count() == 1;
|
||||||
|
let r6 = input.as_bytes().windows(3).any(|c| {
|
||||||
|
c[0] != c[1] && c[0] == c[2] && c[0].is_ascii_alphabetic() && c[1].is_ascii_alphabetic()
|
||||||
|
});
|
||||||
|
let r7 = input
|
||||||
|
.chars()
|
||||||
|
.any(|c| ('\u{2980}'..='\u{2BFF}').contains(&c));
|
||||||
|
let r8 = regex::Regex::new(r"[\p{Emoji}--\p{Ascii}]")
|
||||||
|
.expect("Regex should be valid")
|
||||||
|
.is_match(&input);
|
||||||
|
let r9 = sha256::digest(input.clone()).ends_with('a');
|
||||||
|
if !r1 {
|
||||||
|
code = StatusCode::BAD_REQUEST;
|
||||||
|
result = "naughty".to_string();
|
||||||
|
reason = "8 chars".to_string();
|
||||||
|
} else if !r2 {
|
||||||
|
code = StatusCode::BAD_REQUEST;
|
||||||
|
result = "naughty".to_string();
|
||||||
|
reason = "more types of chars".to_string();
|
||||||
|
} else if !r3 {
|
||||||
|
code = StatusCode::BAD_REQUEST;
|
||||||
|
result = "naughty".to_string();
|
||||||
|
reason = "55555".to_string();
|
||||||
|
} else if !r4 {
|
||||||
|
code = StatusCode::BAD_REQUEST;
|
||||||
|
result = "naughty".to_string();
|
||||||
|
reason = "math is hard".to_string();
|
||||||
|
} else if !r5 {
|
||||||
|
code = StatusCode::NOT_ACCEPTABLE;
|
||||||
|
result = "naughty".to_string();
|
||||||
|
reason = "not joyful enough".to_string();
|
||||||
|
} else if !r6 {
|
||||||
|
code = StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS;
|
||||||
|
result = "naughty".to_string();
|
||||||
|
reason = "illegal: no sandwich".to_string();
|
||||||
|
} else if !r7 {
|
||||||
|
code = StatusCode::RANGE_NOT_SATISFIABLE;
|
||||||
|
result = "naughty".to_string();
|
||||||
|
reason = "outranged".to_string();
|
||||||
|
} else if !r8 {
|
||||||
|
code = StatusCode::UPGRADE_REQUIRED;
|
||||||
|
result = "naughty".to_string();
|
||||||
|
reason = "😳".to_string();
|
||||||
|
} else if !r9 {
|
||||||
|
code = StatusCode::IM_A_TEAPOT;
|
||||||
|
result = "naughty".to_string();
|
||||||
|
reason = "not a coffee brewer".to_string();
|
||||||
|
} else {
|
||||||
|
code = StatusCode::OK;
|
||||||
|
result = "nice".to_string();
|
||||||
|
reason = "that's a nice password".to_string();
|
||||||
|
}
|
||||||
|
(code, Json(Game { result, reason }))
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ mod day11;
|
||||||
mod day12;
|
mod day12;
|
||||||
mod day13;
|
mod day13;
|
||||||
mod day14;
|
mod day14;
|
||||||
|
mod day15;
|
||||||
|
|
||||||
pub(crate) fn router(pool: sqlx::PgPool) -> axum::Router {
|
pub(crate) fn router(pool: sqlx::PgPool) -> axum::Router {
|
||||||
axum::Router::new()
|
axum::Router::new()
|
||||||
|
@ -21,4 +22,5 @@ pub(crate) fn router(pool: sqlx::PgPool) -> axum::Router {
|
||||||
.nest("/", day12::router())
|
.nest("/", day12::router())
|
||||||
.nest("/", day13::router(pool))
|
.nest("/", day13::router(pool))
|
||||||
.nest("/", day14::router())
|
.nest("/", day14::router())
|
||||||
|
.nest("/", day15::router())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue