private static Option <IEnumerable <Coin> > CalculateChange(ChangeCalculationState state) => state.IsChangePaidOut ? new Some <IEnumerable <Coin> >(state.CalculatedChange) : state.CoinBeingProcessed .Map(coin => { state.UseAsMuchAsPossible(coin); return(CalculateChange(state.ForNextCoin()) .TryReduce(() => Backtrack(state))); }) .Reduce(None.Value);
private static Option <IEnumerable <Coin> > Backtrack(ChangeCalculationState state) => state.CoinBeingProcessed .Map(coin => { if (!state.IsUsed(coin)) { return(None.Value); } state.Unuse(coin); return(CalculateChange(state.ForNextCoin()) .TryReduce(() => Backtrack(state))); }) .Reduce(None.Value);