Skip to content

Instantly share code, notes, and snippets.

View yoniLavi's full-sized avatar
:octocat:
Figuring things out

Yoni Lavi yoniLavi

:octocat:
Figuring things out
View GitHub Profile
@yoniLavi
yoniLavi / day3.py
Created January 25, 2023 17:02
AoC2022 day 3 part 2 functional approach
from functools import reduce
from operator import and_
lines = [
"vJrwpWtwJgWrhcsFMMfFFhFp",
"jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL",
"PmmdzqPrVvPwwTWBwg",
"wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn",
"ttgJtRGJQctTZtZT",
"CrZsJsPPZsGzwwsLwLmpwMDw",
@yoniLavi
yoniLavi / roman.js
Last active November 8, 2022 14:00
Convert number to Roman numeral
// Convert a number to a Roman numeral
// The approach is based on the fact that each power of ten follows
// the same principle, whereby we break down the number and build up
// the roman numeral characters
function convertToRoman(num) {
let roman = [];
[roman, num] = convertPowerOfTen(roman, num, 1000, "M");
[roman, num] = convertPowerOfTen(roman, num, 100, "C", "D");
[roman, num] = convertPowerOfTen(roman, num, 10, "X", "L");
[roman, num] = convertPowerOfTen(roman, num, 1, "I", "V");
@yoniLavi
yoniLavi / twelvehours.py
Created October 11, 2022 11:09
A cyclical comparator in Python
"""This gist was prompted by seeing a coding course claim that the elif clause in the following code is unreachable:
if x < 10:
print("X is less than 10")
elif x < 5:
print("X is less than 5")
else:
print("Unknown")
I immediately got nerd-sniped, knowing that Python is magic, and while we usually want to have the less-than relationship
be transitive, it's easy to create a class that violates it.
@yoniLavi
yoniLavi / anagram.py
Created May 29, 2022 21:20
Anagram checker
from string import ascii_lowercase
def generate_letter_indices(s):
for c in s.lower():
if c in ascii_lowercase:
yield ord(c) - ord('a')
def is_anagram(s1, s2):
@yoniLavi
yoniLavi / rpn.py
Created May 19, 2022 00:40
Evaluate polish notation expression
def eval_rpn(expression: str) -> int:
"""Evaluate a Reverse Polish Notation expression involving integers
>>> eval_rpn("12+3*")
9
"""
stack = []
for symbol in expression:
if "0" <= symbol <= "9":
stack.append(symbol)
@yoniLavi
yoniLavi / rock_paper_scissors_lizard_spock.py
Last active April 28, 2022 11:02
An extensible implementation of rock-paper-scissors-lizard-spock
ACTIONS = ["rock", "paper", "scissors", "spock", "lizard"]
OUTCOMES = ["Tie", "P1 wins", "P2 wins", "P1 wins", "P2 wins"]
ACTION_ENUM = {v: i for (i, v) in enumerate(ACTIONS)}
def play(action1, action2):
outcome_int = (ACTION_ENUM[action1] - ACTION_ENUM[action2]) % len(ACTIONS)
return OUTCOMES[outcome_int]
@yoniLavi
yoniLavi / setnum.py
Last active June 3, 2023 01:43
Basic example of defining a natural number using (frozen) sets
class SetNum(frozenset):
"""A set-theoretical definition of a natural number"""
def __repr__(self):
members_repr = ', '.join(map(repr, iter(self)))
return "{" + members_repr + "}"
def successor(self):
cls = type(self)
return cls(self | cls((self,))) # using a tuple to force nesting
from dataclasses import dataclass, field
from itertools import chain
class Node:
"""A tree node of arbitrary values"""
def __init__(self, value, children=None):
self.value = value
self.children = children or []
@yoniLavi
yoniLavi / password_generator.py
Created June 21, 2021 14:02
Example function to generate a random password
from random import choice, shuffle
from string import ascii_lowercase, ascii_uppercase, digits
def generate_password(length=16, groups=[ascii_lowercase, ascii_uppercase, digits]):
"""Generate a random strong password.
It will be of length `length`, with at least one character of each of the `groups`.
"""
group_indices = list(range(len(groups)))
@yoniLavi
yoniLavi / recursive_generator.py
Created April 28, 2021 23:15
Tree traversal using a generator
#!/usr/bin/env python3
tree = {
"name": '1', "children": [
{"name": '11', "children": [
{"name": '111', "children": [
{"name": '1111', "children": []},
]},
{"name": '112', "children": []},
]},