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

dev.marksman.composablerandom.frequency.FrequencyMap2 Maven / Gradle / Ivy

package dev.marksman.composablerandom.frequency;

import com.jnape.palatable.lambda.functions.Fn1;
import dev.marksman.composablerandom.Generator;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;

import static dev.marksman.composablerandom.Generator.generateLongExclusive;
import static dev.marksman.composablerandom.frequency.FrequencyMap1.checkMultiplier;
import static dev.marksman.composablerandom.frequency.FrequencyMap3.frequencyMap3;
import static dev.marksman.composablerandom.frequency.FrequencyMapN.addLabel;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
class FrequencyMap2 implements FrequencyMap {
    private final int weightA;
    private final Generator generatorA;
    private final int weightB;
    private final Generator generatorB;

    @Override
    public Generator toGenerator() {
        long total = weightA + weightB;

        return addLabel(generateLongExclusive(total)
                .flatMap(n -> n < weightA
                        ? generatorA
                        : generatorB));
    }

    @Override
    public FrequencyMap add(int weight, Generator generator) {
        if (weight < 1) return this;
        else {
            @SuppressWarnings("unchecked")
            Generator generatorC = (Generator) generator;
            return frequencyMap3(weightA, generatorA, weightB, generatorB, weight, generatorC);
        }
    }

    @Override
    public FrequencyMap combine(FrequencyMap other) {
        return other.add(weightA, generatorA).add(weightB, generatorB);
    }

    @Override
    public FrequencyMap multiply(int positiveFactor) {
        checkMultiplier(positiveFactor);
        if (positiveFactor == 1) return this;
        else return frequencyMap2(positiveFactor * weightA, generatorA,
                positiveFactor * weightB, generatorB);
    }

    @Override
    public  FrequencyMap fmap(Fn1 fn) {
        return frequencyMap2(weightA, generatorA.fmap(fn),
                weightB, generatorB.fmap(fn));
    }

    static  FrequencyMap2 frequencyMap2(int weightA, Generator generatorA,
                                              int weightB, Generator generatorB) {
        return new FrequencyMap2<>(weightA, generatorA, weightB, generatorB);
    }
}