Skip to content

Instantly share code, notes, and snippets.

@Spuffynism
Spuffynism / hockey-pool-picker.md
Created September 23, 2023 17:24
A 99th percentile hockey pool builder using a constraint solver

A 99th percentile hockey pool builder using a constraint solver

Have a moment to talk about our lord and savior Moneyball (2011)?

A few months ago, I was playing with prolog which got me thinking about possible applications for constraint solvers. Prolog offers a straightforward syntax to express constraints. This led me to explore constraint solving techniques in the context of maximizing points from players for a hockey pool.

With a score of 2502, the strategy detailed here would rank us in position #74 out of 16,733 of La Presse's 2022-2023 hockey pool (no affiliation!), ranking around the 99.56th percentile. Not too bad!

Using a variant of the knapsack problem, we build a team that respects our salary cap, while maximizing the value that players bring. We use players' salary, their scored points, and game logs across seasons to backtest our strategy.

@Spuffynism
Spuffynism / 1-solving-a-dungeons-and-dragons-riddle-using-prolog.md
Last active December 29, 2023 23:15
Solving a Dungeons & Dragons riddle using prolog

Solving a Dungeons & Dragons riddle using prolog

Bringing back the magic of Christmas using the magic of prolog

As part of a holiday D&D one-shot session where Santa Claus's toy factory had been sabotaged, our dungeon master presented to us, a group of Christmas elves, a riddle to solve.

9 cards, labeled with the names of Santa's reindeer were presented to us. The instructions indicated that we had to find the order reindeer were in, according to this riddle:

Vixen should be behind Rudolph, Prancer and Dasher, whilst Vixen should be in front of Dancer and Comet. Dancer should be behind Donder, Blitzen and Rudolph. Comet should be behind Cupid, Prancer and Rudolph. Donder should be behind Comet, Vixen, Dasher, Prancer and Cupid. Cupid should be in front of Comet, Blitzen, Vixen, Dancer and Rudolph. Prancer should be in front of Blitzen, Donder and Cupid. Blitzen should be behind Cupid but in front of Dancer, Vixen and Donder. Rudolph should be behind Prancer but in front of Dasher, Dancer and Dond

@Spuffynism
Spuffynism / graph.js
Created May 28, 2020 23:52
Print a nice graph
const bars = [1, 2, 4, 1, 4, 7, 2, 12, 12, 5];
const heightOfGraph = Math.max(...bars);
let graph = '';
for (let i = heightOfGraph; i > 0; i--) {
graph += bars.reduce((row, bar) => row + (i - bar > 0 ? ' ' : '+'), '') + '\n';
}
console.log(graph);
@Spuffynism
Spuffynism / bad_idea.js
Created May 26, 2020 22:29
DON'T DO THIS
// Fun fact! Returning if conditional statements can be done in js as well as in rust by using IIFEs!
const fn = (x) => {
return (() => {if (x == 0) { return 'zero'; } else if (x < 0) { return 'negative' } else { return 'positive'; }})();
};
fn(1)
// positive
@Spuffynism
Spuffynism / fizzbuzz.js
Last active March 16, 2021 16:41
fizzbuzz codegolf
// Fizz if i % 3 == 0, Buzz if i % 5 == 0, FizzBuzz if both
for(i=0;++i<101;)console.log(i%3?i%5?i:'Buzz':('Fizz'+(i%5?'':'Buzz'))) // 71
for(i=0;++i<101;)console.log(i%15?i%5?i%3?i:'Fizz':'Buzz':'FizzBuzz') // 69
i=0;while(++i<101)a=i%3?'':'Fizz',a+=i%5?'':'Buzz',console.log(a||i) // 68
for(i=0;++i<101;)a=i%3?'':'Fizz',a+=i%5?'':'Buzz',console.log(a?a:i) // 68
for(i=0;++i<101;console.log(a||i))a=(i%3?'':'Fizz')+(i%5?'':'Buzz') // 67
for(i=0;++i<101;console.log(a||i))a=i%3?'':'Fizz',a+=i%5?'':'Buzz' // 66
for(i=0;++i<101;)console.log(i%15?i%5?i%3?i:a='Fizz':b='Buzz':a+b) // 66
for(i=0;++i<101;console.log(a+(i%5?'':'Buzz')||i))a=i%3?'':'Fizz' // 65
@Spuffynism
Spuffynism / sudoku-semi-validator.js
Created September 25, 2018 14:34
Sudoku semi validator
function validSolution(b){
return f=x=>x.map(v=>eval(v.join`+`)),[...f(b),...f(b[0].map((c,i)=>b.map(r=>r[i])))].every(v=>v==45)
}
`0 7→ 20, 1 7→ 13, 2 7→ 21, 3 7→ 0, 4 7→ 1, 5 7→ 2, 6 7→ 3, 7 7→ 4, 8 7→ 5,
9 7→ 6, 10 7→ 7, 11 7→ 8, 12 7→ 9, 13 7→ 10, 14 7→ 11, 15 7→ 12, 16 7→ 14,
17 7→ 15, 18 7→ 16, 19 7→ 17, 20 7→ 18, 21 7→ 19, 22 7→ 22,
23 7→ 23, 24 7→ 24, 25 7→ 25`.split(',')
.map(v =>
v.replace('7→','')
.trim()
.split(' '))
.map(v=>({[v[1]]:v[0]}))
.reduce((v, acc) => Object.assign(acc,v),{});
@Spuffynism
Spuffynism / caesar_cypher.js
Last active November 27, 2018 03:38
Caesar Cypher
e=(m,a,b)=>m.replace(/./g,c=>String.fromCharCode(((c.charCodeAt()-65)*a+b)%26+65))
d=(m,a,b)=>m.replace(/./g,c=>String.fromCharCode(a*(c.charCodeAt()-39-b)%26+65))
@Spuffynism
Spuffynism / explain-this.js
Created July 18, 2018 02:04
explain this
// Collection of weird JS snippets
// taking advantage of non-utf chars
thіs.x = 'a'
this.x // error
// taking advantage of regex syntax
/(\/)/gimuy.exec`\/`[-[~[]]]
@Spuffynism
Spuffynism / codegolfing-generators.js
Last active July 7, 2018 23:50
Codegolfing generators
// recursive infinite generator
p=function*a(x){yield x;yield*a(x+1)}(0)
o={*a(x){yield x;yield*this.a(x+1)}}.a(0)
// using iterators
q=(x=>({next:_=>({value:x++})}))(0)