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

net.jqwik.engine.support.Combinatorics Maven / Gradle / Ivy

The newest version!
package net.jqwik.engine.support;

import java.util.ArrayList;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;

import net.jqwik.api.*;
import net.jqwik.api.Tuple.*;
import net.jqwik.engine.support.combinatorics.*;

import org.jspecify.annotations.*;

import static java.util.Arrays.*;

public class Combinatorics {

	public static  Iterator> combine(List> listOfIterables) {
		if (listOfIterables.isEmpty()) {
			return emptyListSingleton();
		}
		return new CombinedIterator<>(listOfIterables);
	}

	@SuppressWarnings("unchecked")
	private static  Iterator> emptyListSingleton() {
		return asList((List) new ArrayList<>()).iterator();
	}

	@SuppressWarnings("unchecked")
	private static  Iterator> emptySetSingleton() {
		return asList((Set) new LinkedHashSet<>()).iterator();
	}

	public static  Iterator> listCombinations(Iterable elementIterable, int minSize, int maxSize) {
		List>> iterators = new ArrayList<>();
		for(int listSize = minSize; listSize <= maxSize; listSize++) {
			iterators.add(listIterator(elementIterable, listSize));
		}
		return concatIterators(iterators);
	}

	private static  Iterator> listIterator(Iterable elementIterable, int listSize) {
		List> listOfIterables = new ArrayList<>();
		for (int i = 0; i < listSize; i++) {
			listOfIterables.add(elementIterable);
		}
		return combine(listOfIterables);
	}

	public static  Iterator> setCombinations(Iterable elementIterable, int minSize, int maxSize) {
		List>> iterators = new ArrayList<>();
		for(int setSize = minSize; setSize <= maxSize; setSize++) {
			Iterator> setIterator = setIterator(elementIterable, setSize);
			iterators.add(setIterator);
		}
		return concatIterators(iterators);
	}

	private static  Iterator> setIterator(Iterable elementIterable, int setSize) {
		if (setSize == 0) {
			return emptySetSingleton();
		}
		return new SetIterator<>(elementIterable, setSize);
	}

	public static  Iterator> listPermutations(List values) {
		if (values.isEmpty()) {
			return emptyListSingleton();
		}
		return new PermutationIterator<>(values);
	}

	public static  Iterator concat(List> iterables) {
		List> iterators = iterables.stream().map(Iterable::iterator).collect(Collectors.toList());
		return new ConcatIterator<>(iterators);
	}

	private static  Iterator concatIterators(List> iterators) {
		return new ConcatIterator<>(iterators);
	}

	public static Stream> distinctPairs(int maxExclusive) {
		if (maxExclusive < 2) {
			return Stream.empty();
		}
		return StreamSupport.stream(new PairSpliterator(maxExclusive), false);
	}

	private static class PairSpliterator implements Spliterator> {
		private final int maxExclusive;

		private int i = 0;
		private int j = 1;

		public PairSpliterator(int maxExclusive) {
			this.maxExclusive = maxExclusive;
		}

		@Override
		public boolean tryAdvance(Consumer> action) {
			if (j >= maxExclusive) {
				return false;
			}
			action.accept(Tuple.of(i, j));
			j += 1;
			if (j >= maxExclusive) {
				i += 1;
				j = i + 1;
			}
			return true;
		}

		@Override
		public Spliterator> trySplit() {
			return null;
		}

		@Override
		public long estimateSize() {
			return (long) maxExclusive * (maxExclusive - 1) / 2;
		}

		@Override
		public int characteristics() {
			return Spliterator.DISTINCT | Spliterator.ORDERED | Spliterator.SIZED | Spliterator.NONNULL | Spliterator.IMMUTABLE;
		}
	}

}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy