refactored factorial