update Readme to Day07
This commit is contained in:
parent
e06c191e99
commit
06d2e664ad
97
Day07/js/solution.js
Normal file
97
Day07/js/solution.js
Normal file
@ -0,0 +1,97 @@
|
||||
const fs = require('fs');
|
||||
|
||||
function readHands(filePath) {
|
||||
try {
|
||||
const data = fs.readFileSync(filePath, 'utf-8');
|
||||
console.log(`Reading hands from ${filePath}...`);
|
||||
return data.trim().split('\n').map(line => line.split(' '));
|
||||
} catch (err) {
|
||||
console.error(`Error reading file ${filePath}: ${err}`);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
function replaceFaceCards(hand) {
|
||||
return hand.replace(/T/g, 'a')
|
||||
.replace(/J/g, '1')
|
||||
.replace(/Q/g, 'c')
|
||||
.replace(/K/g, 'd')
|
||||
.replace(/A/g, 'e');
|
||||
}
|
||||
|
||||
function calculateStrength(hand) {
|
||||
hand = replaceFaceCards(hand);
|
||||
const counts = hand.split('').reduce((acc, card) => {
|
||||
acc[card] = (acc[card] || 0) + 1;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
if ('1' in counts) {
|
||||
let maxCount = Math.max(...Object.values(counts));
|
||||
let maxCard = Object.keys(counts).find(card => counts[card] === maxCount && card !== '1');
|
||||
|
||||
if (maxCard) {
|
||||
counts[maxCard] += counts['1'];
|
||||
delete counts['1'];
|
||||
}
|
||||
}
|
||||
|
||||
const sortedCounts = Object.values(counts).sort((a, b) => b - a);
|
||||
|
||||
console.log(`Hand: ${hand}, Counts: ${sortedCounts}`);
|
||||
|
||||
if (sortedCounts.toString() === '5') return 10;
|
||||
if (sortedCounts.toString() === '1,4') return 9;
|
||||
if (sortedCounts.toString() === '2,3') return 8;
|
||||
if (sortedCounts.toString() === '1,1,3') return 7;
|
||||
if (sortedCounts.toString() === '1,2,2') return 6;
|
||||
if (sortedCounts.toString() === '1,1,1,2') return 5;
|
||||
if (sortedCounts.toString() === '1,1,1,1,1') return 4;
|
||||
|
||||
throw new Error(`Invalid hand: ${hand}, Counts: ${sortedCounts}`);
|
||||
}
|
||||
|
||||
function handKey(hand) {
|
||||
return calculateStrength(hand[0]);
|
||||
}
|
||||
|
||||
function calculateTotalWinnings(filePath) {
|
||||
try {
|
||||
const hands = readHands(filePath);
|
||||
console.log("Sorting hands based on strength...");
|
||||
hands.sort((a, b) => handKey(b) - handKey(a));
|
||||
|
||||
console.log("Calculating total winnings...");
|
||||
return hands.reduce((acc, [hand, bid], index) => {
|
||||
const winnings = (index + 1) * parseInt(bid, 10);
|
||||
console.log(`Hand: ${hand}, Rank: ${index + 1}, Bid: ${bid}, Winnings: ${winnings}`);
|
||||
return acc + winnings;
|
||||
}, 0);
|
||||
} catch (err) {
|
||||
console.error(`Error calculating winnings: ${err}`);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
function runTest(filePath, expected) {
|
||||
console.log(`Running test with ${filePath}...`);
|
||||
try {
|
||||
const totalWinnings = calculateTotalWinnings(filePath);
|
||||
console.assert(totalWinnings === expected, `Test failed, expected ${expected} but got ${totalWinnings}`);
|
||||
console.log(`Test passed: ${totalWinnings}`);
|
||||
} catch (err) {
|
||||
console.error(`Test failed: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
try {
|
||||
runTest("../test.txt", 5905);
|
||||
const result = calculateTotalWinnings("../input.txt");
|
||||
console.log(`Total result from input.txt: ${result}`);
|
||||
} catch (err) {
|
||||
console.error(`An error occurred: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
8
Day07/rust/Cargo.toml
Normal file
8
Day07/rust/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "rust"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
88
Day07/rust/src/main.rs
Normal file
88
Day07/rust/src/main.rs
Normal file
@ -0,0 +1,88 @@
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufRead};
|
||||
|
||||
fn read_hands(filename: &str) -> io::Result<Vec<(String, i32)>> {
|
||||
let file = File::open(filename)?;
|
||||
let lines = io::BufReader::new(file).lines();
|
||||
|
||||
let mut hands = Vec::new();
|
||||
for line in lines {
|
||||
if let Ok(line) = line {
|
||||
let parts: Vec<&str> = line.split_whitespace().collect();
|
||||
if parts.len() == 2 {
|
||||
let hand = parts[0].to_string();
|
||||
let bid: i32 = parts[1].parse().unwrap();
|
||||
hands.push((hand, bid));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(hands)
|
||||
}
|
||||
|
||||
fn replace_face_cards(hand: &str) -> String {
|
||||
let mut replaced = hand.to_string();
|
||||
replaced = replaced.replace("T", "a");
|
||||
replaced = replaced.replace("J", "1");
|
||||
replaced = replaced.replace("Q", "c");
|
||||
replaced = replaced.replace("K", "d");
|
||||
replaced = replaced.replace("A", "e");
|
||||
replaced
|
||||
}
|
||||
|
||||
fn calculate_strength(hand: &str) -> (i32, String) {
|
||||
let replaced_hand = replace_face_cards(hand);
|
||||
let mut counts = HashMap::new();
|
||||
for c in replaced_hand.chars() {
|
||||
*counts.entry(c).or_insert(0) += 1;
|
||||
}
|
||||
|
||||
let mut joker_count = 0;
|
||||
if counts.contains_key(&'1') {
|
||||
joker_count = counts.remove(&'1').unwrap();
|
||||
}
|
||||
|
||||
let mut best_category = 4; // Default to High card
|
||||
for (card, count) in &counts {
|
||||
let adjusted_count = if *card != '1' { count + joker_count } else { *count };
|
||||
best_category = best_category.max(match adjusted_count {
|
||||
5 => 10,
|
||||
4 => 9,
|
||||
3 if counts.values().any(|&v| v == 2) => 8,
|
||||
3 => 7,
|
||||
_ => best_category,
|
||||
});
|
||||
}
|
||||
|
||||
// Use original hand for tie-breaking
|
||||
let tie_breaker_hand = hand.chars().collect::<String>();
|
||||
println!("Hand: {}, Strength: {}, Tie-breaker hand: {}", hand, best_category, tie_breaker_hand);
|
||||
(best_category, tie_breaker_hand)
|
||||
}
|
||||
|
||||
fn calculate_total_winnings(hands: Vec<(String, i32)>) -> i32 {
|
||||
let mut sorted_hands = hands;
|
||||
// Sort based on strength and original hand for tie-breaking
|
||||
sorted_hands.sort_unstable_by(|a, b| {
|
||||
let (strength_a, tie_breaker_a) = calculate_strength(&a.0);
|
||||
let (strength_b, tie_breaker_b) = calculate_strength(&b.0);
|
||||
(strength_b, tie_breaker_b).cmp(&(strength_a, tie_breaker_a))
|
||||
});
|
||||
|
||||
sorted_hands.iter().enumerate().fold(0, |acc, (i, (hand, bid))| {
|
||||
let winnings = bid * (i as i32 + 1);
|
||||
println!("Hand: {}, Rank: {}, Bid: {}, Winnings: {}", hand, i + 1, bid, winnings);
|
||||
acc + winnings
|
||||
})
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let test_hands = read_hands("../test.txt").expect("Failed to read test file");
|
||||
let test_total = calculate_total_winnings(test_hands);
|
||||
assert_eq!(test_total, 5905, "Test failed: expected 5905, got {}", test_total);
|
||||
println!("Test passed: Total winnings = {}", test_total);
|
||||
|
||||
let hands = read_hands("../input.txt").expect("Failed to read input file");
|
||||
let total_winnings = calculate_total_winnings(hands);
|
||||
println!("Total winnings from input.txt: {}", total_winnings);
|
||||
}
|
@ -38,7 +38,7 @@ I aim to complete each day's puzzle on the same day, but as with any challenge,
|
||||
| 04 | ✅ | ✅ | [Day04 README](/Day04/README.md) |
|
||||
| 05 | ✅ | ✅ | [Day05 README](/Day05/README.md) |
|
||||
| 06 | ✅ | ✅ | [Day06 README](/Day06/README.md) |
|
||||
| 07 | ❓ | ❓ | [Day07 README](/Day07/README.md) |
|
||||
| 07 | ✅ | ✅ | [Day07 README](/Day07/README.md) |
|
||||
| 08 | ❓ | ❓ | [Day08 README](/Day08/README.md) |
|
||||
| 09 | ❓ | ❓ | [Day09 README](/Day09/README.md) |
|
||||
| 10 | ❓ | ❓ | [Day10 README](/Day10/README.md) |
|
||||
|
Loading…
Reference in New Issue
Block a user