All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.alpharogroup.lottery.drawing.DrawMultiMapLotteryNumbersFactory Maven / Gradle / Ivy

/**
 * Commercial License
 *
 * Copyright (C) 2015 Asterios Raptis - All Rights Reserved
 *
 * Proprietary and confidential
 *
 * Unauthorized copying of this software and its files,
 * via any medium is strictly prohibited
 *
 * Written by Asterios Raptis
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package de.alpharogroup.lottery.drawing;

import de.alpharogroup.collections.list.ListFactory;
import de.alpharogroup.collections.map.MapExtensions;
import de.alpharogroup.collections.map.MapFactory;
import de.alpharogroup.collections.set.SetFactory;
import de.alpharogroup.comparators.ComparatorFactory;
import de.alpharogroup.random.DefaultSecureRandom;
import de.alpharogroup.random.number.RandomBooleanFactory;
import de.alpharogroup.random.number.RandomIntFactory;

import java.security.SecureRandom;
import java.util.*;
import java.util.stream.Collectors;

/**
 * The factory class {@link DrawMultiMapLotteryNumbersFactory} provides factory methods to draw
 * lottery numbers
 * with different algorithms and {@link SecureRandom} argument for custom randomize draws, like
 * for a special draw date we could initialize the {@link SecureRandom} with the draw date. It
 * has provides methods for merge several multi maps
 */
public final class DrawMultiMapLotteryNumbersFactory {

    private DrawMultiMapLotteryNumbersFactory()
    {
    }

    /**
     * Draw of lottery numbers from given drawCount and take the numbers that are drawn the most
     * times and return a new set.
     *
     * @param maxNumbers
     *            the maximum of numbers to draw
     * @param minVolume
     *            the min volume
     * @param maxVolume
     *            the max volume
     * @param drawCount
     *            the draw count defines how many times to draw numbers
     * @return the sets of the drawn numbers
     */
    public static Set drawFromMultiMap(int maxNumbers, int minVolume, int maxVolume,
        int drawCount)
    {
        return drawFromMultiMap(maxNumbers, minVolume, maxVolume, drawCount, DefaultSecureRandom.get());
    }

    /**
     * Draw of lottery numbers from given drawCount and take the numbers that are drawn the most
     * times and return a new set.
     *
     * @param maxNumbers
     *            the maximum of numbers to draw
     * @param minVolume
     *            the min volume
     * @param maxVolume
     *            the max volume
     * @param drawCount
     *            the draw count defines how many times to draw numbers
     * @param secureRandom
     *            the secure random object for random generation
     * @return the sets of the drawn numbers
     */
    public static Set drawFromMultiMap(int maxNumbers, int minVolume, int maxVolume,
        int drawCount, SecureRandom secureRandom)
    {
        return drawFromMultiMap(maxNumbers, minVolume, maxVolume, drawCount, true,
            false, secureRandom);
    }

    /**
     * Draw of lottery numbers from given drawCount and take the numbers that are drawn the most
     * times and return a new set.
     *
     * @param maxNumbers
     *            the maximum of numbers to draw
     * @param minVolume
     *            the min volume
     * @param maxVolume
     *            the max volume
     * @param drawCount
     *            the draw count defines how many times to draw numbers
     * @param mostDrawn
     *            the flag that indicates if the most drawn numbers should be taken if true,
     *            otherwise the reverse order will be taken
     * @return the sets of the drawn numbers
     */
    public static Set drawFromMultiMap(int maxNumbers, int minVolume, int maxVolume,
        int drawCount, boolean mostDrawn)
    {
        return drawFromMultiMap(maxNumbers, minVolume, maxVolume, drawCount, mostDrawn, DefaultSecureRandom.get());
    }

    /**
     * Draw of lottery numbers from given drawCount and take the numbers that are drawn the most
     * times and return a new set.
     *
     * @param maxNumbers
     *            the maximum of numbers to draw
     * @param minVolume
     *            the min volume
     * @param maxVolume
     *            the max volume
     * @param drawCount
     *            the draw count defines how many times to draw numbers
     * @param mostDrawn
     *            the flag that indicates if the most drawn numbers should be taken if true,
     *            otherwise the reverse order will be taken
     * @param secureRandom
     *            the secure random object for random generation
     * @return the sets of the drawn numbers
     */
    public static Set drawFromMultiMap(int maxNumbers, int minVolume, int maxVolume,
        int drawCount, boolean mostDrawn, SecureRandom secureRandom)
    {
        return drawFromMultiMap(maxNumbers, minVolume, maxVolume, drawCount, mostDrawn, false, secureRandom);
    }

    /**
     * Draw of lottery numbers from given drawCount and take the numbers that are drawn the most
     * times and return a new set.
     *
     * @param maxNumbers
     *            the maximum of numbers to draw
     * @param minVolume
     *            the min volume
     * @param maxVolume
     *            the max volume
     * @param drawCount
     *            the draw count defines how many times to draw numbers
     * @param mostDrawn
     *            the flag that indicates if the most drawn numbers should be taken if true,
     *            otherwise the reverse order will be taken
     * @param paranoid
     *            the flag paranoid indicates to create a custom comparator from the counter map and
     *            define a random defined order to draw if true, otherwise the flag mostDrawn will
     *            define the order to draw
     * @return the sets of the drawn numbers
     */
    public static Set drawFromMultiMap(int maxNumbers, int minVolume, int maxVolume,
        int drawCount, boolean mostDrawn, boolean paranoid)
    {
        return drawFromMultiMap(maxNumbers, minVolume, maxVolume, drawCount, mostDrawn, paranoid, DefaultSecureRandom.get());
    }

    /**
     * Draw of lottery numbers from given drawCount and take the numbers that are drawn the most
     * times and return a new set.
     *
     * @param maxNumbers
     *            the maximum of numbers to draw
     * @param minVolume
     *            the min volume
     * @param maxVolume
     *            the max volume
     * @param drawCount
     *            the draw count defines how many times to draw numbers
     * @param mostDrawn
     *            the flag that indicates if the most drawn numbers should be taken if true,
     *            otherwise the reverse order will be taken
     * @param paranoid
     *            the flag paranoid indicates to create a custom comparator from the counter map and
     *            define a random defined order to draw if true, otherwise the flag mostDrawn will
     *            define the order to draw
     * @param secureRandom
     *            the secure random object for random generation
     * @return the sets of the drawn numbers
     */
    public static Set drawFromMultiMap(int maxNumbers, int minVolume, int maxVolume,
        int drawCount, boolean mostDrawn, boolean paranoid, SecureRandom secureRandom)
    {
        Map numberCounterMap = MapFactory
            .newNumberCounterMap(minVolume, maxVolume);
        Comparator mostDrawnComparator = drawFromMultiMap(maxNumbers, minVolume, maxVolume,
            drawCount, mostDrawn, paranoid, numberCounterMap, secureRandom);
        return resolveLotteryNumbers(maxNumbers, mostDrawnComparator, numberCounterMap);
    }

    /**
     * Factory method for create a comparator for sort the lottery numbers
     *
     * @param maxNumbers
     *            the maximum of numbers to draw
     * @param minVolume
     *            the min volume
     * @param maxVolume
     *            the max volume
     * @param drawCount
     *            the draw count defines how many times to draw numbers
     * @param mostDrawn
     *            the flag that indicates if the most drawn numbers should be taken if true,
     *            otherwise the reverse order will be taken
     * @param paranoid
     *            the flag paranoid indicates to create a custom comparator from the counter map and
     *            define a random defined order to draw if true, otherwise the flag mostDrawn will
     *            define the order to draw
     * @param numberCounterMap
     *            the counter map for generate statistics of the drawn lottery numbers
     * @return the comparator for sort the lottery numbers
     */
    public static Comparator drawFromMultiMap(int maxNumbers, int minVolume, int maxVolume,
                                                       int drawCount, boolean mostDrawn, boolean paranoid, Map numberCounterMap)
    {
        return drawFromMultiMap(
                maxNumbers, minVolume, maxVolume, drawCount, mostDrawn, paranoid,
                numberCounterMap, DefaultSecureRandom.get());
    }

    /**
     * Factory method for create a comparator for sort the lottery numbers
     *
     * @param maxNumbers
     *            the maximum of numbers to draw
     * @param minVolume
     *            the min volume
     * @param maxVolume
     *            the max volume
     * @param drawCount
     *            the draw count defines how many times to draw numbers
     * @param mostDrawn
     *            the flag that indicates if the most drawn numbers should be taken if true,
     *            otherwise the reverse order will be taken
     * @param paranoid
     *            the flag paranoid indicates to create a custom comparator from the counter map and
     *            define a random defined order to draw if true, otherwise the flag mostDrawn will
     *            define the order to draw
     * @param numberCounterMap
     *            the counter map for generate statistics of the drawn lottery numbers
     * @param secureRandom
     *            the secure random object for random generation
     * @return the comparator for sort the lottery numbers
     */
    public static Comparator drawFromMultiMap(int maxNumbers, int minVolume, int maxVolume,
        int drawCount, boolean mostDrawn,
        boolean paranoid, Map numberCounterMap, SecureRandom secureRandom)
    {
        return newMostDrawnComparator(
            mergeDrawings(maxNumbers, minVolume, maxVolume, drawCount, numberCounterMap), paranoid,
            mostDrawn, secureRandom);
    }

    /**
     * Factory method for create a comparator for sort the lottery numbers
     *
     * @param maxNumbers
     *            the maximum of numbers to draw
     * @param minVolume
     *            the min volume
     * @param maxVolume
     *            the max volume
     * @param drawCount
     *            the draw count defines how many times to draw numbers
     * @param numberCounterMap
     *            the counter map for generate statistics of the drawn lottery numbers
     * @return the comparator for sort the lottery numbers
     */
    public static Comparator drawFromMultiMap(int maxNumbers, int minVolume, int maxVolume,
                                                       int drawCount, Map numberCounterMap)
    {
        return drawFromMultiMap(maxNumbers, minVolume, maxVolume, drawCount, numberCounterMap, DefaultSecureRandom.get());
    }

    /**
     * Factory method for create a comparator for sort the lottery numbers
     *
     * @param maxNumbers
     *            the maximum of numbers to draw
     * @param minVolume
     *            the min volume
     * @param maxVolume
     *            the max volume
     * @param drawCount
     *            the draw count defines how many times to draw numbers
     * @param numberCounterMap
     *            the counter map for generate statistics of the drawn lottery numbers
     * @param secureRandom
     *            the secure random object for random generation
     * @return the comparator for sort the lottery numbers
     */
    public static Comparator drawFromMultiMap(int maxNumbers, int minVolume, int maxVolume,
        int drawCount, Map numberCounterMap, SecureRandom secureRandom)
    {
        return newMostDrawnComparator(
            mergeDrawings(maxNumbers, minVolume, maxVolume, drawCount, numberCounterMap), false,
            true, secureRandom);
    }

    /**
     * Draw of paranoid lottery numbers from given drawCount and take the numbers that are drawn the
     * most times and return a new set.
     *
     * @param maxNumbers
     *            the maximum of numbers to draw
     * @param minVolume
     *            the min volume
     * @param maxVolume
     *            the max volume
     * @param drawCount
     *            the draw count defines how many times to draw numbers
     * @return the sets of the drawn numbers
     */
    public static Set drawParanoidFromMultiMap(int maxNumbers, int minVolume,
        int maxVolume, int drawCount)
    {
        return drawParanoidFromMultiMap(maxNumbers, minVolume, maxVolume, drawCount, DefaultSecureRandom.get());
    }

    /**
     * Draw of paranoid lottery numbers from given drawCount and take the numbers that are drawn the
     * most times and return a new set.
     *
     * @param maxNumbers
     *            the maximum of numbers to draw
     * @param minVolume
     *            the min volume
     * @param maxVolume
     *            the max volume
     * @param drawCount
     *            the draw count defines how many times to draw numbers
     * @param secureRandom
     *            the secure random object for random generation
     * @return the sets of the drawn numbers
     */
    public static Set drawParanoidFromMultiMap(int maxNumbers, int minVolume,
        int maxVolume, int drawCount, SecureRandom secureRandom)
    {
        return drawFromMultiMap(maxNumbers, minVolume, maxVolume, drawCount,
            RandomBooleanFactory.randomBoolean(), true, secureRandom);
    }

    /**
     * Factory method for create a comparator for sort the lottery numbers
     *
     * @param numberCounterMap
     *            the counter map for generate statistics of the drawn lottery numbers
     * @param paranoid
     *            the flag paranoid indicates to create a custom comparator from the counter map and
     *            define a random defined order to draw if true, otherwise the flag mostDrawn will
     *            define the order to draw
     * @param mostDrawn
     *            the flag that indicates if the most drawn numbers should be taken if true,
     *            otherwise the reverse order will be taken
     * @return the comparator for sort the lottery numbers
     */
    private static Comparator newMostDrawnComparator(
        Map numberCounterMap, boolean paranoid, boolean mostDrawn)
    {
        return newMostDrawnComparator(numberCounterMap, paranoid, mostDrawn, DefaultSecureRandom.get());
    }

    /**
     * Factory method for create a comparator for sort the lottery numbers
     *
     * @param numberCounterMap
     *            the counter map for generate statistics of the drawn lottery numbers
     * @param paranoid
     *            the flag paranoid indicates to create a custom comparator from the counter map and
     *            define a random defined order to draw if true, otherwise the flag mostDrawn will
     *            define the order to draw
     * @param mostDrawn
     *            the flag that indicates if the most drawn numbers should be taken if true,
     *            otherwise the reverse order will be taken
     * @return the comparator for sort the lottery numbers
     */
    private static Comparator newMostDrawnComparator(
        Map numberCounterMap, boolean paranoid, boolean mostDrawn, SecureRandom secureRandom)
    {
        Comparator mostDrawnComparator;
        if (paranoid)
        {
            List numberCounterValues = ListFactory
                .newArrayList(SetFactory.newTreeSet(numberCounterMap.values()));
            Collections.shuffle(numberCounterValues, secureRandom);
            mostDrawnComparator = ComparatorFactory.newComparator(numberCounterValues);
        }
        else
        {
            mostDrawnComparator = mostDrawn ? Comparator.reverseOrder() : Comparator.naturalOrder();
        }
        return mostDrawnComparator;
    }

    /**
     * Merges several drawings of lottery numbers from the given arguments
     *
     * @param maxNumbers
     *            the maximum of numbers to draw
     * @param minVolume
     *            the min volume
     * @param maxVolume
     *            the max volume
     * @param drawCount
     *            the draw count defines how many times to draw numbers
     * @param numberCounterMap
     *            the counter map for generate statistics of the drawn lottery numbers
     * @return the map with the merged lottery numbers
     */
    public static Map mergeDrawings(int maxNumbers, int minVolume, int maxVolume,
                                                      int drawCount, Map numberCounterMap)
    {
        for (int i = 0; i < drawCount; i++)
        {
            DrawLotteryNumbersFactory.draw(maxNumbers, minVolume, maxVolume)
                    .forEach(key -> numberCounterMap.merge(key, 1, Integer::sum));
        }
        return numberCounterMap;
    }

    /**
     * Resolves the lottery numbers from the given number counter map in the order from the given
     * comparator limited to maxNumbers
     *
     * @param maxNumbers
     *            the max numbers
     * @param numberCounterMap
     *            the number counter map
     * @return the sets of the lottery numbers
     */
    public static Set resolveLotteryNumbers(int maxNumbers, Map numberCounterMap)
    {
        return resolveLotteryNumbers(maxNumbers, newMostDrawnComparator(numberCounterMap,false, true), numberCounterMap);
    }

    /**
     * Resolves the lottery numbers from the given number counter map in the order from the given
     * comparator limited to maxNumbers
     *
     * @param maxNumbers
     *            the max numbers
     * @param mostDrawn
     *            the comparator that defines in which order to take the drawn numbers. For instance
     *            if you want to have the reverse order you can simply give the
     *            Comparator.reverseOrder() or you can define your custom order
     * @param numberCounterMap
     *            the number counter map
     * @return the sets of the lottery numbers
     */
    public static Set resolveLotteryNumbers(int maxNumbers, Comparator mostDrawn,
                                                     Map numberCounterMap)
    {
        List> sortByValue = MapExtensions
                .sortByValueAsList(numberCounterMap, mostDrawn);

        List newLotteryNumbers = sortByValue.stream().map(Map.Entry::getKey)
                .limit(maxNumbers).collect(Collectors.toList());
        return SetFactory.newTreeSet(newLotteryNumbers);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy