Based on Assignment VI Stanford CS193P course