Getting delta of array values from constantly updating array - arrays

Having a problem getting something which should be rather simple to work.
I am constantly updating an array with new values and as I do so I need to get the delta or difference between the lowest and highest values. The length of the array should remain constant at 10.
The problem is that only the 1st and last values of my delta array seem to change. What am I missing?
Although in AS3, should be almost identical in Java or Javascript
private var _deltaArray:Array= new Array();
private function update(myVal:int):void{
if (_deltaArray.length < 10) {
_deltaArray.push(myVal);
}
if (_deltaArray.length >= 10) {
_deltaArray.push(myVal);
var delta:int =getDelta(_deltaArray);
_deltaArray.shift();
}
}//end func
private function getDelta(a:Array):int {
var total:Number=0;
var L:int=a.length
if (L > 1) {
a.sort(Array.NUMERIC);
var delta:int=int(a[0]) - int(a[L - 1]);
trace('getDelta delta= ' + delta);
}
return delta;
}//end func

This is just a suggestion, but why not keep a running count of your delta? I can only code this in pseudo-code, but:
private double max = Double.MIN;
private double min = Double.MAX;
private void update(integer value) {
array.push(value);
max = value > max ? value : max;
min = value < min ? value : min;
if (array.length > 10) {
array.shift();
}
}
private int delta() { return max - min; }

Found the answer.
I needed to clone my array BEFORE sorting it to retrieve delta value

Related

increase multiplier based on array index

My iq isnt high enough to comeup with a formula for this. Say i have array of 200 elements. i have a set multiplier with which im multiplying each array element in a for loop.
public float[] myArray = new float[200];
public float multiplier = 150;
public float multiplierFactor = 2;
public void enhance()
{
for(int i = 0; i < myArray.Length; i++)
{
if(i > myArray.Length * 0.75f)
{
// ... what to do here to multiplierFactor ...
}
myArray[i] *= (multiplier * multiplierFactor);
}
}
What i would like to do is: calculate multiplierFactor when 'i' has reached certain point in array (eg (int)(i > myArray.Length * 0.75f) ) such that start increasing the multiplierFactor from its original value of 1, go up to specified highest value (eg multiplierFactor=2 so it goes from 1 to 2 or any specified value) then after max point is reached (eg 2) start decreasing the multiplier and go back to original value over the left over indexes of the array. So at the last element the multiplierFactor is again back to original value of 1. Kind of like a sine wave.
Okay, you can try this. It should work:
if(i>= myArray.Length*0.75 && i<=myArray.Length*(0.75+0.25*0.5))
{
#positive slope line equation for multiplierFactor
multiplierFactor=1+((i+1-myArray.Length*0.75)/(myArray.Length*0.25*0.5))
}
else if(i>myArray.Length*(0.75+0.25*0.5))
{
#negative slope line equation for multiplierFactor
multiplierFactor=2-((i+1-myArray.Length*0.75)/(myArray.Length*0.25*0.5))
}
else
{
multiplierFactor=1
}

Algorithm to iterate N-dimensional array in pseudo random order

I have an array that I would like to iterate in random order. That is, I would like my iteration to visit each element only once in a seemingly random order.
Would it be possible to implement an iterator that would iterate elements like this without storing the order or other data in a lookup table first?
Would it be possible to do it for N-dimensional arrays where N>1?
UPDATE: Some of the answers mention how to do this by storing indices. A major point of this question is how to do it without storing indices or other data.
I decided to solve this, because it annoyed me to death not remembering the name of solution that I had heard before. I did however remember in the end, more on that in the bottom of this post.
My solution depends on the mathematical properties of some cleverly calculated numbers
range = array size
prime = closestPrimeAfter(range)
root = closestPrimitiveRootTo(range/2)
state = root
With this setup we can calculate the following repeatedly and it will iterate all elements of the array exactly once in a seemingly random order, after which it will loop to traverse the array in the same exact order again.
state = (state * root) % prime
I implemented and tested this in Java, so I decided to paste my code here for future reference.
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
public class PseudoRandomSequence {
private long state;
private final long range;
private final long root;
private final long prime;
//Debugging counter
private int dropped = 0;
public PseudoRandomSequence(int r) {
range = r;
prime = closestPrimeAfter(range);
root = modPow(generator(prime), closestPrimeTo(prime / 2), prime);
reset();
System.out.println("-- r:" + range);
System.out.println(" p:" + prime);
System.out.println(" k:" + root);
System.out.println(" s:" + state);
}
// https://en.wikipedia.org/wiki/Primitive_root_modulo_n
private static long modPow(long base, long exp, long mod) {
return BigInteger.valueOf(base).modPow(BigInteger.valueOf(exp), BigInteger.valueOf(mod)).intValue();
}
//http://e-maxx-eng.github.io/algebra/primitive-root.html
private static long generator(long p) {
ArrayList<Long> fact = new ArrayList<Long>();
long phi = p - 1, n = phi;
for (long i = 2; i * i <= n; ++i) {
if (n % i == 0) {
fact.add(i);
while (n % i == 0) {
n /= i;
}
}
}
if (n > 1) fact.add(n);
for (long res = 2; res <= p; ++res) {
boolean ok = true;
for (long i = 0; i < fact.size() && ok; ++i) {
ok &= modPow(res, phi / fact.get((int) i), p) != 1;
}
if (ok) {
return res;
}
}
return -1;
}
public long get() {
return state - 1;
}
public void advance() {
//This loop simply skips all results that overshoot the range, which should never happen if range is a prime number.
dropped--;
do {
state = (state * root) % prime;
dropped++;
} while (state > range);
}
public void reset() {
state = root;
dropped = 0;
}
private static boolean isPrime(long num) {
if (num == 2) return true;
if (num % 2 == 0) return false;
for (int i = 3; i * i <= num; i += 2) {
if (num % i == 0) return false;
}
return true;
}
private static long closestPrimeAfter(long n) {
long up;
for (up = n + 1; !isPrime(up); ++up)
;
return up;
}
private static long closestPrimeBefore(long n) {
long dn;
for (dn = n - 1; !isPrime(dn); --dn)
;
return dn;
}
private static long closestPrimeTo(long n) {
final long dn = closestPrimeBefore(n);
final long up = closestPrimeAfter(n);
return (n - dn) > (up - n) ? up : dn;
}
private static boolean test(int r, int loops) {
final int array[] = new int[r];
Arrays.fill(array, 0);
System.out.println("TESTING: array size: " + r + ", loops: " + loops + "\n");
PseudoRandomSequence prs = new PseudoRandomSequence(r);
final long ct = loops * r;
//Iterate the array 'loops' times, incrementing the value for each cell for every visit.
for (int i = 0; i < ct; ++i) {
prs.advance();
final long index = prs.get();
array[(int) index]++;
}
//Verify that each cell was visited exactly 'loops' times, confirming the validity of the sequence
for (int i = 0; i < r; ++i) {
final int c = array[i];
if (loops != c) {
System.err.println("ERROR: array element #" + i + " was " + c + " instead of " + loops + " as expected\n");
return false;
}
}
//TODO: Verify the "randomness" of the sequence
System.out.println("OK: Sequence checked out with " + prs.dropped + " drops (" + prs.dropped / loops + " per loop vs. diff " + (prs.prime - r) + ") \n");
return true;
}
//Run lots of random tests
public static void main(String[] args) {
Random r = new Random();
r.setSeed(1337);
for (int i = 0; i < 100; ++i) {
PseudoRandomSequence.test(r.nextInt(1000000) + 1, r.nextInt(9) + 1);
}
}
}
As stated in the top, about 10 minutes after spending a good part of my night actually getting a result, I DID remember where I had read about the original way of doing this. It was in a small C implementation of a 2D graphics "dissolve" effect as described in Graphics Gems vol. 1 which in turn is an adaption to 2D with some optimizations of a mechanism called "LFSR" (wikipedia article here, original dissolve.c source code here).
You could collect all possible indices in a list and then remove a random indece to visit. I know this is sort of like a lookup table, but i don't see any other option than this.
Here is an example for a one-dimensional array (adaption to multiple dimensions should be trivial):
class RandomIterator<T> {
T[] array;
List<Integer> remainingIndeces;
public RandomIterator(T[] array) {
this.array = array;
this.remainingIndeces = new ArrayList<>();
for(int i = 0;i<array.length;++i)
remainingIndeces.add(i);
}
public T next() {
return array[remainingIndeces.remove((int)(Math.random()*remainingIndeces.size()))];
}
public boolean hasNext() {
return !remainingIndeces.isEmpty();
}
}
On a side note: If this code is performance relevant, this method would perform worse by far, as the random removing from the list triggers copies if you use a list backed by an array (a linked-list won't help either, as indexed access is O(n)). I would suggest a lookup-structure (e.g. HashSet in Java) that stores all visited indices to circumvent this problem (though that's exactly what you did not want to use)
EDIT: Another approach is to copy said array and use a library function to shuffle it and then traverse it in linear order. If your array isn't that big, this seems like the most readable and performant option.
You would need to create a pseudo random number generator that generates values from 0 to X-1 and takes X iterations before repeating the cycle, where X is the product of all the dimension sizes. I don't know if there is a generic solution to doing this. Wiki article for one type of random number generator:
http://en.wikipedia.org/wiki/Linear_congruential_generator
Yes, it is possible. Imagine 3D array (you not likely use anything more than that). This is like a cube and where all 3 lines connect is a cell. You can enumerate your cells 1 to N using a dictionary, you can do this initialization in loops, and create a list of cells to use for random draw
Initialization
totalCells = ... (xMax * yMax * zMax)
index = 0
For (x = 0; x < xMax ; x++)
{
For (y = 0; y < yMax ; y++)
{
For (z = 0; z < zMax ; z++)
{
dict.Add(i, new Cell(x, y, z))
lst.Add(i)
i++
}
}
}
Now, all you have to do is iterate randomly
Do While (lst.Count > 0)
{
indexToVisit = rand.Next(0, lst.Count - 1)
currentCell = dict[lst[indexToVisit]]
lst.Remove(indexToVisit)
// Do something with current cell here
. . . . . .
}
This is pseudo code, since you didn't mention language you work in
Another way is to randomize 3 (or whatever number of dimensions you have) lists and then just nested loop through them - this will be random in the end.

apache commons math - NotStrictlyPositiveException when only 1 value exists in bin

I am trying to use apache commons math for kernel density estimation for a group of values. One bin happens to have only one value, and when I try to call cumulativeProbability() I get a NotStrictlyPositiveException. Is there any way to prevents this? I can't be sure that all the bins will have at least one value.
Thanks.
Given that this bug is still there, I wrote my own implementation of the EmpiricalDistribution class, following their guidelines.
I only re-implemented the functionality that I needed, i.e. computing the entropy of a distribution, but you can easily extend it to your needs.
public class EmpiricalDistribution {
private double[] values;
private int[] binCountArray;
private double maxValue, minValue;
private double mean, stDev;
public EmpiricalDistribution(double[] values) {
this.values = values;
int binCount = NumberUtil.roundToClosestInt(values.length / 10.0);
binCountArray = new int[binCount];
maxValue = Double.NEGATIVE_INFINITY;
minValue = Double.POSITIVE_INFINITY;
for (double value : values) {
if (value > maxValue) maxValue = value;
if (value < minValue) minValue = value;
}
double binRange = (maxValue - minValue) / binCount;
for (double value : values) {
int bin = (int) ((value - minValue) / binRange);
bin = Math.min(binCountArray.length - 1, bin);
binCountArray[bin]++;
}
mean = (new Mean()).evaluate(values);
stDev = (new StandardDeviation()).evaluate(values, mean);
}
public double getEntropy() {
double entropy = 0;
for (int valuesInBin : binCountArray) {
if (valuesInBin == 0) continue;
double binProbability = valuesInBin / (double) values.length;
entropy -= binProbability * FastMath.log(2, binProbability);
}
return entropy;
}
public double getMean() {
return mean;
}
public double getStandardDeviation() {
return stDev;
}
}
I get the same error with one of my distributions.
Reading the Javadoc of this class, it says the following:
USAGE NOTES:
The binCount is set by default to 1000. A good rule of thumb
is to set the bin count to approximately the length of the input
file divided by 10.
I've initialised my EmpiricalDistribution with a binCount equals to 10% of my initial data length and now everything is working ok:
double[] baseLine = getBaseLineValues();
...
// Initialise binCount
distribution = new EmpiricalDistribution(baseLine.length/10);
// Load base line data
distribution.load(baseLine);
// Now you can obtain random values based on this distribution
double randomValue = distribution.getNextValue();

as3 random array - randomize array - actionscript 3

How do you randomize an array using actionscript 3?
There is a short version using Array.sort() function:
var arr : Array = [0,1,2,3,4,5,6,7,8,9];
function randomize ( a : *, b : * ) : int {
return ( Math.random() > .5 ) ? 1 : -1;
}
trace( arr.sort( randomize ) );
If you don't get "enough" randomness you can sort twice :)
EDIT - explanation line by line:
For Array class method sort() you can pass not only sort options like Array.CASEINSENSITIVE, Array.DESCENDING and so on but also your own custom compare function reference (a callback) that accepts two parameters (two elements from array to compare). From AS3 documentation:
A comparison function should take two arguments to compare. Given the elements A and B, the result of compareFunction can have a negative, 0, or positive value:
A negative return value specifies that A appears before B in the sorted sequence.
A return value of 0 specifies that A and B have the same sort order.
A positive return value specifies that A appears after B in the sorted sequence.
Note: compare function parameters might be typed (if your array is typed) and have any name you want eg.:
function compareElements ( elementA : SomeClass, elementB : SomeClass ) : int;
This method is very useful when you need to sort array elements by their special properties. In randomization case compareFunction randomly returns -1, 0 or 1 and makes array elements to switch their places (indices). I have found that better randomization (in my subjective and mathematically untested opinion) is when method returns only -1 and 1. Also have in mind that sorting function with custom compare function doesn't compare elements sequentially so in some special cases randomization results may differ from what you might expect.
There's a better way that will also allow you to randomize the array in place, if you need that, and it will not make you create more then a single copy of your original array.
package
{
import flash.display.Sprite;
public class RandomizeArrayExample extends Sprite
{
public function RandomizeArrayExample()
{
super();
testDistribution();
}
private function testDistribution():void
{
var hash:Object = { };
var tester:Array = [1, 2, 3, 4];
var key:String;
for (var i:int; i < 1e5; i++)
{
randomize(tester);
key = tester.join("");
if (key in hash) hash[key]++;
else hash[key] = 1;
}
for (var p:String in hash) trace(p, "=>", hash[p]);
}
private function randomize(array:Array):Array
{
var temp:Object;
var tempOffset:int;
for (var i:int = array.length - 1; i >= 0; i--)
{
tempOffset = Math.random() * i;
temp = array[i];
array[i] = array[tempOffset];
array[tempOffset] = temp;
}
return array;
}
}
}
I had an alternative requirement where i wanted to randomly insert lots of source arrays into a target array randomly. Like Rytis i'm a big fan of the forEach, map and sort functions on Arrays.
var randomInsert:Function = function callback(item:*, index:int, array:Vector.<MyItem>):void
{
var j:Number = Math.floor(Math.random() * targetArray.length);
targetArray.splice(j,0,item);
}
targetArray = new Vector.<MyItem>();
sourceArray1.forEach(randomInsert, this);
sourceArray2.forEach(randomInsert, this);
here's an easier function. Works also on multidimensional arrays
function randomizeArray(array:Array):Array
{
var newArray:Array = new Array();
while (array.length > 0)
{
var mn=Math.floor(Math.random()*array.length)
newArray[newArray.length]=array[mn]
array.splice(mn,1)
}
return newArray;
}
I found this very helpful. I hope it can help you too.
// Array to Randomize
var firstArray:Array = ["One","Two","Three","Four","Five","six","seven","eight","nine","ten"];
trace(firstArray); // Prints in order
var newArray:Array = new Array();
function randomizeArray(array:Array):Array
{
var newArray:Array = new Array();
while (array.length > 0)
{
newArray.push(array.splice(Math.floor(Math.random()*array.length), 1));
}
return newArray;
}
var randomArray:Array = randomizeArray(firstArray);
trace(randomArray); // Prints out randomized :)
If you need your array to be shuffled (your elements can not repeat). You could use this function:
/**
* Shuffles array into new array with no repeating elements. Simple swap algorithm is used.
*/
public function shuffleArray(original:Array):Array
{
// How many swaps we will do
// Increase this number for better results (more shuffled array, but slower performance)
const runs:int = original.length * 3;
var shuffled:Array = new Array(original.length);
var i:int;
var a:int;
var b:int;
var temp:Object;
// Copy original array to shuffled
for(i=0; i<shuffled.length; i++){
shuffled[i] = original[i];
}
// Run random swap cycle 'runs' times
for(i=0; i<runs; i++){
// There is a chance that array element will swap with itself,
// and there is always small probability it will make your shuffle
// results not that good, hence try to experiment with
// different runs count as stated above
a = Math.floor(Math.random() * original.length);
b = Math.floor(Math.random() * original.length);
// Swap messages
temp = shuffled[a];
shuffled[a] = shuffled[b];
shuffled[b] = temp;
}
return shuffled;
}
Usage:
var testArray:Array = ["Water", "Fire", "Air", "Earth"];
trace(shuffleArray(testArray).concat());
this is how I randomize my array of 36 cards for a memory game
const QUANT_CARTAS: int = 36;
//get the 36 numbers into the array
for (var i: int = 0; i < QUANT_CARTAS; i++)
{
cartas.push(i);
}
//shuffles them =)
for (var moeda: int = QUANT_CARTAS - 1; moeda > 0; moeda--)
{
var pos: int = Math.floor(Math.random() * moeda);
var carta: int = cartas[moeda];
cartas[moeda] = cartas[pos];
cartas[pos] = carta;
}
// and add them using the random order...
for (i = 0; i < QUANT_CARTAS; i++)
{
var novaCarta: Carta = new Carta();
novaCarta.tipoCarta = cartas[i];
etcetcetc.............
}
choose random string from array
function keyGenerator(len:Number):String
{
function randomRange(minNum:Number, maxNum:Number):Number
{
return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);
}
var hexArray = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'];
var key = "";
for (var i=0; i<len; i++)
{
key += hexArray[randomRange(0,hexArray.length-1)];
}
return key;
}
usage:
trace(keyGenerator(16));

Algorithm for determining if strided arrays overlap?

In the library I'm working on, we have data sets (which may be subsets of other data sets) that are distributed in memory in three-dimensional rectangular strided arrays. That is, an array A can be subscripted as A(i,j,k), where each index ranges from zero to some upper bound, and the location of each element in memory is given by:
A(i,j,k) = A0 + i * A_stride_i + j * A_stride_j + k * A_stride_k
where A0 is a base pointer, and A_stride_i et al are dimensional strides.
Now, because these data sets may be subsets of other data sets rather than each occupying their own independent malloc'ed block of memory, it's entirely possible that they may overlap (where overlap means that A(i,j,k) < B(m,n,p) is neither always true nor always false), and if they overlap they may interleave with each other or they may collide with each other (where collide means that A(i,j,k) == B(m,n,p) for some sextet of indices).
Therein lies the question. Some operations on two data sets (for example, a copy) are only valid if the arrays do not collide with each other, but are valid if they overlap in an interleaved non-colliding fashion. I'd like to add a function for two data sets whether two data sets collide or not.
Is there an existing algorithm for doing this in a reasonably efficient and straightforward way?
It's fairly easy to check whether the data sets overlap or not, so the key question is: Given two data sets of this form that overlap, what is an efficient algorithm to determine if they interleave or collide?
Example:
As a simple example, suppose we have memory locations from 0 to F (in hex):
0 1 2 3 4 5 6 7 8 9 A B C D E F
I'll also consider only 2D arrays here, for simplicity. Suppose we have one of size 2,3 (that is, 0 <= i < 2 and 0 <= j < 3), with a stride_i = 1 and stride_j = 4, at a base address of 2. This will occupy (with occupied locations denoted by their i,j pair):
0 1 2 3 4 5 6 7 8 9 A B C D E F
* * * * * *
Likewise, if we have another array of the same sizes and strides, starting at a base address of 4, that will look like this:
0 1 2 3 4 5 6 7 8 9 A B C D E F
o o o o o o
In the terminology that I was using in describing the problem, these arrays "overlap", but they do not collide.
Restrictions and Assumptions:
We can assume that the strides are positive and, if desired, that they are in increasing order. Neither of things are true in the actual library, but it is reasonably simple to rearrange the array definition to get to this point.
We can assume that arrays do not self-interleave. This is also not enforced by the library, but would be a pathological case, and can be warned about separately. That is (assuming the strides are in increasing order, and i ranges from zero to max_i and so forth):
stride_j >= max_i * stride_i
stride_k >= max_j * stride_j
Points, of course, for methods that do not require these assumptions, as rearranging the array definition into a canonical order is a bit of work that's ideally avoided.
The two arrays cannot be assumed to have equal sizes or strides.
I don't think there's value in keeping track of things during construction -- there's no information occurring at construction that is not present when doing the test. Also, "construction" may simply be "consider the subset of this larger array with this base pointer, these strides, and these sizes."
Worst Likely Cases
svick's answer reminds me that I should probably add something about some typical "worse" cases that I expect this to see. One of the worst will be when we have an array that represents some very large number of complex values, stored in consecutive (real, imag) pairs, and then we have two sub-arrays containing the real and imaginary parts respectively -- so, you've got a few million elements in the array, alternating between the arrays. As this is not an unlikely case, it should be testable with something other than abysmal performance.
I think the following C# program should work. It uses the branch and bound method and works for arrays of any number of dimensions.
using System;
using System.Collections.Generic;
namespace SO_strides
{
sealed class Dimension
{
public int Min { get; private set; }
public int Max { get; private set; }
public int Stride { get; private set; }
private Dimension() { }
public Dimension(int max, int stride)
{
Min = 0;
Max = max;
Stride = stride;
}
public Dimension[] Halve()
{
if (Max == Min)
throw new InvalidOperationException();
int split = Min + (Max - Min) / 2;
return new Dimension[]
{
new Dimension { Min = Min, Max = split, Stride = Stride },
new Dimension { Min = split + 1, Max = Max, Stride = Stride }
};
}
}
sealed class ArrayPart
{
public int BaseAddr { get; private set; }
public Dimension[] Dimensions { get; private set; }
public int FirstNonconstantIndex { get; private set; }
int? min;
public int Min
{
get
{
if (min == null)
{
int result = BaseAddr;
foreach (Dimension dimension in Dimensions)
result += dimension.Min * dimension.Stride;
min = result;
}
return min.Value;
}
}
int? max;
public int Max
{
get
{
if (max == null)
{
int result = BaseAddr;
foreach (Dimension dimension in Dimensions)
result += dimension.Max * dimension.Stride;
max = result;
}
return max.Value;
}
}
public int Size
{
get
{
return Max - Min + 1;
}
}
public ArrayPart(int baseAddr, Dimension[] dimensions)
: this(baseAddr, dimensions, 0)
{
Array.Sort(dimensions, (d1, d2) => d2.Stride - d1.Stride);
}
private ArrayPart(int baseAddr, Dimension[] dimensions, int fni)
{
BaseAddr = baseAddr;
Dimensions = dimensions;
FirstNonconstantIndex = fni;
}
public bool CanHalve()
{
while (FirstNonconstantIndex < Dimensions.Length
&& Dimensions[FirstNonconstantIndex].Min == Dimensions[FirstNonconstantIndex].Max)
FirstNonconstantIndex++;
return FirstNonconstantIndex < Dimensions.Length;
}
public ArrayPart[] Halve()
{
Dimension[][] result = new Dimension[2][];
Dimension[] halves = Dimensions[FirstNonconstantIndex].Halve();
for (int i = 0; i < 2; i++)
{
result[i] = (Dimension[])Dimensions.Clone();
result[i][FirstNonconstantIndex] = halves[i];
}
return new ArrayPart[]
{
new ArrayPart(BaseAddr, result[0], FirstNonconstantIndex),
new ArrayPart(BaseAddr, result[1], FirstNonconstantIndex)
};
}
}
sealed class CandidateSet
{
public ArrayPart First { get; private set; }
public ArrayPart Second { get; private set; }
public CandidateSet(ArrayPart first, ArrayPart second)
{
First = first;
Second = second;
}
public bool Empty
{
get
{
return First.Min > Second.Max || Second.Min > First.Max;
}
}
public CandidateSet[] Halve()
{
int firstSize = First.Size;
int secondSize = Second.Size;
CandidateSet[] result;
if (firstSize > secondSize && First.CanHalve())
{
ArrayPart[] halves = First.Halve();
result = new CandidateSet[]
{
new CandidateSet(halves[0], Second),
new CandidateSet(halves[1], Second)
};
}
else if (Second.CanHalve())
{
ArrayPart[] halves = Second.Halve();
result = new CandidateSet[]
{
new CandidateSet(First, halves[0]),
new CandidateSet(First, halves[1])
};
}
else
throw new InvalidOperationException();
return result;
}
public static bool HasSolution(ArrayPart first, ArrayPart second)
{
Stack<CandidateSet> stack = new Stack<CandidateSet>();
stack.Push(new CandidateSet(first, second));
bool found = false;
while (!found && stack.Count > 0)
{
CandidateSet candidate = stack.Pop();
if (candidate.First.Size == 1 && candidate.Second.Size == 1)
found = true;
else
{
foreach (CandidateSet half in candidate.Halve())
if (!half.Empty)
stack.Push(half);
}
}
return found;
}
}
static class Program
{
static void Main()
{
Console.WriteLine(
CandidateSet.HasSolution(
new ArrayPart(2, new Dimension[] { new Dimension(1, 1), new Dimension(2, 4) }),
new ArrayPart(4, new Dimension[] { new Dimension(1, 1), new Dimension(2, 4) })
)
);
}
}
}

Resources