Skip to content

Instantly share code, notes, and snippets.

View teryror's full-sized avatar

Tristan Dannenberg teryror

View GitHub Profile
@teryror
teryror / _tv-tropes-scraper.rs
Last active April 5, 2024 08:12
Scrape links off TV Tropes to find common tropes in a set of shows
use scraper::{Html, Selector};
use std::collections::HashMap;
fn main() {
let source_sites: &[&[&str]] = &[
&[
"https://tvtropes.org/pmwiki/pmwiki.php/BreakingBad/TropesAToB",
"https://tvtropes.org/pmwiki/pmwiki.php/BreakingBad/TropesCToD",
"https://tvtropes.org/pmwiki/pmwiki.php/BreakingBad/TropesEToL",
@teryror
teryror / constexpr_alias_method.rs
Last active August 22, 2021 09:24
Const evaluatable Rust implementation of Vose's Alias Method
/// Const evaluatable Rust implementation of Vose's Alias Method, as described
/// by Keith Schwarz at https://www.keithschwarz.com/darts-dice-coins/
///
/// In brief, this is an O(n) precomputation, which allows sampling an arbitrary
/// finite probability distribution in O(1) time, by first simulating a fair
/// n-sided die, followed by a biased coin.
///
/// Because floating point arithmetic cannot be used in const functions, this is
/// built to operate on integer weights, rather than precomputed probabilities.
///
// Calculate the area of a generalized ellipse (abs(x/a)^n + abs(y/b)^n = 1).
// I'm considering this as the metric to minimize for a weird optimization
// problem, where this would be evaluated _a lot_, so I tried making this
// as fast & simple as possible.
pub fn area_of_superellipse(exponent: f64, semi_axes: (f64, f64)) -> f64 {
let n = exponent;
let (a, b) = semi_axes;
// This method was derived from the following formula:
@teryror
teryror / mtga_price_parity.rs
Created April 5, 2021 10:23
Finding the win rates required to achieve rare card price parity with the MTG Arena Store
fn binomial_coefficient(n: u32, k: u32) -> u128 {
let mut res = 1u128;
for i in 0..k {
res = (res * (n - i) as u128) / (i + 1) as u128;
}
res
}
fn neg_binom_pmf(k: u32, r: u32, p: f64) -> f64 {
assert!(r > 0);
@teryror
teryror / mtg_arena_win_rates.rs
Last active April 4, 2021 10:04
Finding the minimum win rates required to "go infinite" in MTG Arena
fn binomial_coefficient(n: u32, k: u32) -> u128 {
let mut res = 1u128;
for i in 0..k {
res = (res * (n - i) as u128) / (i + 1) as u128;
}
res
}
fn neg_binom_pmf(k: u32, r: u32, p: f64) -> f64 {
assert!(r > 0);
@teryror
teryror / bin.rs
Last active January 28, 2021 12:31
Revised land count analysis for Magic: The Gathering
use num_bigint::BigUint;
use num_traits::ToPrimitive;
// calculate the binomial coefficient `n choose k`
fn binomial_coefficient(n: u32, k: u32) -> u64 {
let mut result = BigUint::from(1u32);
for i in 0..k {
result = (result * (n - i)) / (i + 1);
}
result.to_u64().unwrap()

Redesigning coca's Storage Abstraction

This post was written primarily to organize my thoughts during the design process. I'll explain the thought process that led me to each point in the design space we visit, then point out any issues, which will lead into the next iteration. Along the way, I made a few errors, which I'll try to rectify in the (Side Notes).

Here we go!

Introduction: The Status Quo

@teryror
teryror / mulligans-and-mana-bases.md
Last active September 4, 2023 21:18
An updated and expanded guide on building mana bases in Magic: the Gathering

Mulligans and Mana Bases

For my previous post on how many colored sources you should put in your mana bases, I adapted Frank Karsten's simulation code to the London Mulligan rules change, and to make recommendations based on how many lands you want to play. In doing so, I made two errors: first, the tables for Commander decks do not take into account the free mulligan, or the turn one draw. Second, I changed the assumed mulligan strategy to be more aggressive; the effect of this change dominated over the effect of the London Mulligan, invalidating my comment on the matter.

@teryror
teryror / color-aware-mull-strat-comparison.rs
Last active September 30, 2020 09:32
Simulation code analyzing how mana bases affect mulligan decisions in Magic: the Gathering
use rand::prelude::*;
use std::collections::HashMap;
use std::fmt::Write;
#[derive(Copy, Clone, PartialEq, Eq)]
enum CardType {
NonLand,
Land,
GoodLand,
}
@teryror
teryror / mtg-on-curve.rs
Last active September 25, 2020 15:26
Rust port of Frank Karsten's simulation code for optimizing mana bases in Magic: the Gathering.
/*
Based on Frank Karsten's "How Many Colored Mana Sources" simulation code
(see his article [1], original source code found at [2]).
[1]: https://strategy.channelfireball.com/all-strategy/channelmagic/channelmagic-articles/how-many-colored-mana-sources-do-you-need-to-consistently-cast-your-spells-a-guilds-of-ravnica-update/
[2]: https://pastebin.com/9P5kwqt1
Updated to account for the London Mulligan rule change, and expanded to
account for more restrictive casting costs and different land counts.