Esempio n. 1
0
    public Pocket[] AutoSelectPockets(SmartLabel recipient)
    {
        var knownPockets                = NonPrivatePockets.Where(x => x.Labels != CoinPocketHelper.UnlabelledFundsText).ToArray();
        var unknownPockets              = NonPrivatePockets.Except(knownPockets).ToArray();
        var privateAndUnknownPockets    = _allPockets.Except(knownPockets).ToArray();
        var privateAndKnownPockets      = _allPockets.Except(unknownPockets).ToArray();
        var knownByRecipientPockets     = knownPockets.Where(pocket => pocket.Labels.Any(label => recipient.Contains(label, StringComparer.OrdinalIgnoreCase))).ToArray();
        var onlyKnownByRecipientPockets =
            knownByRecipientPockets
            .Where(pocket =>
                   pocket.Labels.Count() == recipient.Count() &&
                   pocket.Labels.All(label => recipient.Contains(label, StringComparer.OrdinalIgnoreCase)))
            .ToArray();

        if (onlyKnownByRecipientPockets.Sum(x => x.Amount) >= _targetAmount)
        {
            return(onlyKnownByRecipientPockets);
        }

        if (_privatePocket.Amount >= _targetAmount)
        {
            return(new[] { _privatePocket });
        }

        if (TryGetBestKnownByRecipientPockets(knownByRecipientPockets, _targetAmount, recipient, out var pockets))
        {
            return(pockets);
        }

        if (knownPockets.Sum(x => x.Amount) >= _targetAmount)
        {
            return(knownPockets);
        }

        if (unknownPockets.Sum(x => x.Amount) >= _targetAmount)
        {
            return(unknownPockets);
        }

        if (NonPrivatePockets.Sum(x => x.Amount) >= _targetAmount)
        {
            return(NonPrivatePockets);
        }

        if (privateAndKnownPockets.Sum(x => x.Amount) >= _targetAmount)
        {
            return(privateAndKnownPockets);
        }

        if (privateAndUnknownPockets.Sum(x => x.Amount) >= _targetAmount)
        {
            return(privateAndUnknownPockets);
        }

        return(_allPockets.ToArray());
    }
Esempio n. 2
0
    private bool TryGetBestKnownByRecipientPockets(Pocket[] knownByRecipientPockets, Money targetAmount, SmartLabel recipient, [NotNullWhen(true)] out Pocket[]?pockets)
    {
        pockets = null;

        if (knownByRecipientPockets.Sum(x => x.Amount) < _targetAmount)
        {
            return(false);
        }

        var privacyRankedPockets =
            knownByRecipientPockets
            .Select(pocket =>
        {
            var containedRecipientLabelsCount = pocket.Labels.Count(label => recipient.Contains(label, StringComparer.OrdinalIgnoreCase));
            var totalPocketLabelsCount        = pocket.Labels.Count();
            var totalRecipientLabelsCount     = recipient.Count();
            var index = ((double)containedRecipientLabelsCount / totalPocketLabelsCount) + ((double)containedRecipientLabelsCount / totalRecipientLabelsCount);

            return(acceptabilityIndex: index, pocket);
        })
            .OrderByDescending(tup => tup.acceptabilityIndex)
            .ThenBy(tup => tup.pocket.Labels.Count())
            .ThenByDescending(tup => tup.pocket.Amount)
            .Select(tup => tup.pocket)
            .ToArray();

        var bestPockets = new List <Pocket>();

        foreach (var p in privacyRankedPockets)
        {
            bestPockets.Add(p);

            if (bestPockets.Sum(x => x.Amount) >= targetAmount)
            {
                break;
            }
        }

        foreach (var p in bestPockets.OrderBy(x => x.Amount).ThenByDescending(x => x.Labels.Count()).ToImmutableArray())
        {
            if (bestPockets.Sum(x => x.Amount) - p.Amount >= targetAmount)
            {
                bestPockets.Remove(p);
            }
            else
            {
                break;
            }
        }

        pockets = bestPockets.ToArray();
        return(true);
    }