Updated version with shorter code and (hopefully) better performance