Finished projecteuler 084 with some proper rust code
This commit is contained in:
75
projecteuler/084/Cargo.lock
generated
Normal file
75
projecteuler/084/Cargo.lock
generated
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.139"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "main"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"rand",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
9
projecteuler/084/Cargo.toml
Normal file
9
projecteuler/084/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "main"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rand = "0.8.5"
|
||||||
283
projecteuler/084/src/main.rs
Normal file
283
projecteuler/084/src/main.rs
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
use rand::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum CommunityChest {
|
||||||
|
ToGo,
|
||||||
|
ToJail,
|
||||||
|
Empty,
|
||||||
|
}
|
||||||
|
struct CommunityChestDeck {
|
||||||
|
deck: Vec<CommunityChest>,
|
||||||
|
current_index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CommunityChestDeck {
|
||||||
|
fn next(&mut self) -> CommunityChest {
|
||||||
|
self.current_index = (self.current_index + 1) % self.deck.len();
|
||||||
|
self.deck[self.current_index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum Chance {
|
||||||
|
ToGo,
|
||||||
|
ToJail,
|
||||||
|
ToC1,
|
||||||
|
ToE3,
|
||||||
|
ToH2,
|
||||||
|
ToR1,
|
||||||
|
ToNextRailway,
|
||||||
|
ToNextUtility,
|
||||||
|
GoBack3,
|
||||||
|
Empty,
|
||||||
|
}
|
||||||
|
struct ChanceDeck {
|
||||||
|
deck: Vec<Chance>,
|
||||||
|
current_index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChanceDeck {
|
||||||
|
fn next(&mut self) -> Chance {
|
||||||
|
self.current_index = (self.current_index + 1) % self.deck.len();
|
||||||
|
self.deck[self.current_index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
enum TileType {
|
||||||
|
Go,
|
||||||
|
Jail,
|
||||||
|
GoToJail,
|
||||||
|
C1,
|
||||||
|
E3,
|
||||||
|
H2,
|
||||||
|
R1,
|
||||||
|
Railway,
|
||||||
|
Utility,
|
||||||
|
Empty,
|
||||||
|
CommunityChest,
|
||||||
|
Chance,
|
||||||
|
}
|
||||||
|
use TileType::*;
|
||||||
|
|
||||||
|
struct Board {
|
||||||
|
board: Vec<TileType>,
|
||||||
|
current_index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Board {
|
||||||
|
fn next(&mut self) -> TileType {
|
||||||
|
self.current_index = (self.current_index + 1) % self.board.len();
|
||||||
|
self.board[self.current_index]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prev(&mut self) -> TileType {
|
||||||
|
self.current_index = ((self.current_index as i32 - 1) % self.board.len() as i32) as usize;
|
||||||
|
self.board[self.current_index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DoubleDice {
|
||||||
|
sides: u32,
|
||||||
|
rng: ThreadRng,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DoubleDice {
|
||||||
|
// Need to know each specific throw because we need to keep track of the doubles
|
||||||
|
fn throw(&mut self) -> (u32, u32) {
|
||||||
|
let dice1 = self.rng.gen_range(1..=self.sides);
|
||||||
|
let dice2 = self.rng.gen_range(1..=self.sides);
|
||||||
|
|
||||||
|
(dice1, dice2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ThrowResult {
|
||||||
|
ToJail,
|
||||||
|
Moves(u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_dice(dice: &mut DoubleDice, past_throws: &mut [(u32, u32)]) -> ThrowResult {
|
||||||
|
let dice_throw = dice.throw();
|
||||||
|
if past_throws[0] == past_throws[1] && past_throws[1] == dice_throw {
|
||||||
|
past_throws[0] = (0, 0);
|
||||||
|
past_throws[1] = (0, 0);
|
||||||
|
ThrowResult::ToJail
|
||||||
|
} else {
|
||||||
|
past_throws[0] = past_throws[1];
|
||||||
|
past_throws[1] = dice_throw;
|
||||||
|
ThrowResult::Moves(dice_throw.0 + dice_throw.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, this is Patrick!");
|
||||||
|
let mut rng = thread_rng();
|
||||||
|
|
||||||
|
// First create card decks, board and dice
|
||||||
|
let mut community_chest_cards = vec![
|
||||||
|
CommunityChest::Empty,
|
||||||
|
CommunityChest::Empty,
|
||||||
|
CommunityChest::Empty,
|
||||||
|
CommunityChest::Empty,
|
||||||
|
CommunityChest::Empty,
|
||||||
|
CommunityChest::Empty,
|
||||||
|
CommunityChest::Empty,
|
||||||
|
CommunityChest::Empty,
|
||||||
|
CommunityChest::Empty,
|
||||||
|
CommunityChest::Empty,
|
||||||
|
CommunityChest::Empty,
|
||||||
|
CommunityChest::Empty,
|
||||||
|
CommunityChest::Empty,
|
||||||
|
CommunityChest::Empty,
|
||||||
|
CommunityChest::ToGo,
|
||||||
|
CommunityChest::ToJail,
|
||||||
|
];
|
||||||
|
community_chest_cards.shuffle(&mut rng);
|
||||||
|
|
||||||
|
let mut chance_cards = vec![
|
||||||
|
Chance::Empty,
|
||||||
|
Chance::Empty,
|
||||||
|
Chance::Empty,
|
||||||
|
Chance::Empty,
|
||||||
|
Chance::Empty,
|
||||||
|
Chance::Empty,
|
||||||
|
Chance::ToGo,
|
||||||
|
Chance::ToJail,
|
||||||
|
Chance::ToC1,
|
||||||
|
Chance::ToE3,
|
||||||
|
Chance::ToH2,
|
||||||
|
Chance::ToR1,
|
||||||
|
Chance::ToNextRailway,
|
||||||
|
Chance::ToNextRailway,
|
||||||
|
Chance::ToNextUtility,
|
||||||
|
Chance::GoBack3,
|
||||||
|
];
|
||||||
|
chance_cards.shuffle(&mut rng);
|
||||||
|
|
||||||
|
let board_tiles = vec![
|
||||||
|
Go,
|
||||||
|
Empty,
|
||||||
|
CommunityChest,
|
||||||
|
Empty,
|
||||||
|
Empty,
|
||||||
|
R1,
|
||||||
|
Empty,
|
||||||
|
Chance,
|
||||||
|
Empty,
|
||||||
|
Empty,
|
||||||
|
Jail,
|
||||||
|
C1,
|
||||||
|
Utility,
|
||||||
|
Empty,
|
||||||
|
Empty,
|
||||||
|
Railway,
|
||||||
|
Empty,
|
||||||
|
CommunityChest,
|
||||||
|
Empty,
|
||||||
|
Empty,
|
||||||
|
Empty,
|
||||||
|
Empty,
|
||||||
|
Chance,
|
||||||
|
Empty,
|
||||||
|
E3,
|
||||||
|
Railway,
|
||||||
|
Empty,
|
||||||
|
Empty,
|
||||||
|
Utility,
|
||||||
|
Empty,
|
||||||
|
GoToJail,
|
||||||
|
Empty,
|
||||||
|
Empty,
|
||||||
|
CommunityChest,
|
||||||
|
Empty,
|
||||||
|
Railway,
|
||||||
|
Chance,
|
||||||
|
Empty,
|
||||||
|
Empty,
|
||||||
|
H2,
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut cc_deck = CommunityChestDeck {
|
||||||
|
deck: community_chest_cards,
|
||||||
|
current_index: 0,
|
||||||
|
};
|
||||||
|
let mut chance_deck = ChanceDeck {
|
||||||
|
deck: chance_cards,
|
||||||
|
current_index: 0,
|
||||||
|
};
|
||||||
|
let mut board = Board {
|
||||||
|
board: board_tiles,
|
||||||
|
current_index: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut dice = DoubleDice { sides: 4, rng };
|
||||||
|
let mut square_popularity = vec![0; board.board.len()];
|
||||||
|
let mut dice_throws = [(0, 0), (0, 0)];
|
||||||
|
|
||||||
|
for _ in 0..2000000 {
|
||||||
|
match handle_dice(&mut dice, &mut dice_throws) {
|
||||||
|
ThrowResult::ToJail => {
|
||||||
|
board.current_index = 10;
|
||||||
|
}
|
||||||
|
ThrowResult::Moves(n) => {
|
||||||
|
let mut next_tile = Empty;
|
||||||
|
for _ in 0..n {
|
||||||
|
next_tile = board.next();
|
||||||
|
}
|
||||||
|
match next_tile {
|
||||||
|
GoToJail => {
|
||||||
|
board.current_index = 10;
|
||||||
|
}
|
||||||
|
CommunityChest => {
|
||||||
|
let card_drawn = cc_deck.next();
|
||||||
|
match card_drawn {
|
||||||
|
CommunityChest::ToGo => {
|
||||||
|
board.current_index = 0;
|
||||||
|
}
|
||||||
|
CommunityChest::ToJail => {
|
||||||
|
board.current_index = 10;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Chance => {
|
||||||
|
let card_drawn = chance_deck.next();
|
||||||
|
match card_drawn {
|
||||||
|
Chance::ToJail => {
|
||||||
|
board.current_index = 10;
|
||||||
|
}
|
||||||
|
Chance::ToGo => {
|
||||||
|
board.current_index = 0;
|
||||||
|
}
|
||||||
|
Chance::Empty => {}
|
||||||
|
Chance::GoBack3 => {
|
||||||
|
for _ in 0..3 {
|
||||||
|
_ = board.prev()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Chance::ToC1 => while board.next() != TileType::C1 {},
|
||||||
|
Chance::ToE3 => while board.next() != TileType::E3 {},
|
||||||
|
Chance::ToH2 => while board.next() != TileType::H2 {},
|
||||||
|
Chance::ToNextUtility => while board.next() != TileType::Utility {},
|
||||||
|
Chance::ToR1 => while board.next() != TileType::R1 {},
|
||||||
|
Chance::ToNextRailway => {
|
||||||
|
let mut next_tile = board.next();
|
||||||
|
while next_tile != TileType::R1 && next_tile != TileType::Railway {
|
||||||
|
next_tile = board.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
square_popularity[board.current_index] += 1;
|
||||||
|
}
|
||||||
|
let mut squares_sorted: Vec<(usize, u32)> = square_popularity.into_iter().enumerate().collect();
|
||||||
|
squares_sorted.sort_by(|(_, a), (_, b)| a.cmp(b));
|
||||||
|
|
||||||
|
println!("Square popularity: {:?}", squares_sorted);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user