Excel: How to negate a boolean array? - arrays

I want to use "NOT" for arrays. I.e.:
"NOT"((True, False, True)) = (False, True, False)
I want to use this technique within a sumproduct formula, namely
=SUMPRODUCT(($R$2:$R$9000=$W$5:$AF$5)*($S$2:$S$9000))
Now, I want to use the negated array and am still looking for an elegant version how to do it. I tried:
=SUMPRODUCT(NOT($R$2:$R$9000=$W$5:$AF$5)*($S$2:$S$9000))
and
=SUMPRODUCT(($R$2:$R$9000<>$W$5:$AF$5)*($S$2:$S$9000))
which both did not work out as assumed. I know that I could use
=SUMPRODUCT(($R$2:$R$9000<>$W$5)*($R$2:$R$9000<>$X$5)*...*($R$2:$R$9000<>$AF$5)*($S$2:$S$9000))
But I hope for a more elegant version.
Do you know a more elegant answer?
Many greetings,
Peter

I was hoping for a more elegant solution for this myself, but I think this is the best I've figured so far: --(<bitmask>)=0.
In your case, SUMPRODUCT(--(($R$2:$R$9000=$W$5:$AF$5)*($S$2:$S$9000))=0), or even SUMPRODUCT((($R$2:$R$9000=$W$5:$AF$5)*($S$2:$S$9000))=0) should work since the * operator already converts the bitmask to integers.
The idea is to convert the {TRUE,FALSE,TRUE} bitmask into integers {1,0,1} with the --. Then if they're FALSE (0) the result of the =0 comparison is TRUE. If TRUE (1), then the result is FALSE.
If you use something like <bitmask>+<bitmask> to simulate an element-wise OR, it should still work because the TRUEs (sums) will still be >0.
Does that work for you?

Related

Ruby elegant way to provide default array values for version string

This is a trivial question, unsure if I should really be asking here, but would like to see if anyone has a more elegant way to write this in ruby.
I have a version string of format x.y.z or x.y or x. I would like a simple elegant way to convert this into an array where default 0 value is inserted if segment is missing. I have a few different ways to do this, but I was hoping for something a bit cleaner. Atm my current solution is this
version_string.split('.').each_with_index.with_object(['0','0','0']) { |(segment, i), version_array| version_array[i] = segment }
Seems to work fine, and I can always move to a simple method call to make code look cleanup, but something about the use of each_with_index and `with_object kinda bugs me. Just curious to see if rest of Ruby community have anything to add
How about (min Ruby 2.6)
version_string.split('.').then { |x, y = '0', z = '0'| [x,y,z] }

Find the first "1" in zero array

I have an array "0000011111"
I need to find the first occurrence of "1".
How can I do that in efficient way ?
my solution is: (I think there is a better way)
$array = array(0,0,1,1,1);
for($i=0;$i<count($array);$i++)
{
if($array[$i] == 1)
{
var_dump($i);
return;
}
}
Your solution is already as efficient as possible, but there's a built-in method in PHP that will do this for you:
$array = array(0,0,1,1,1);
var_dump(array_search(1, $array)); // int(2)
Note that array_search will return the boolean FALSE in the case where there are no 1s in the array.
EDIT
I made the assumption that the original code is PHP just because it looked that way. :-)
Unfortunately, since there is no necessity for any of the numbers to be "1" and since you are only going through the array once, this is the most efficient solution. Binary search or any such algorithm wont work as this array is quite obviously not sorted.
Sample inputs:
0101101
1000101
In either case, binary search would not work.
If you can somehow convert the array efficiently to a number, It is possible to find the first 1 efficiently with log base 2.
var number = 0b010000010;
console.log(Math.floor(Math.log2(number)))
EDIT The main reason for doing this is because there are hardware instructions for doing log base 2 that make it constant time.
Of course if you cannot store your array as a binary string, because it is too long or something like that, this solution is not for you.

How to do a parameterization in C?

I'm trying to find an algorithm for the game master mind with 4 numbers, where each number can be between 0 to 5, giving 1296 possibilities. With the first guess being 1,1,0,0
there are less options left.
I would like to know how to remove the options which are not suitable according to the first guess.
How to use an array(solutions) and array(current solutions)? Should I use parameterization for that?
Is there an algorithm in C to do that?
Thanks a lot for the help!
The simplest to implement is to simply loop trough all your elements and make the once that no longer work false. This might be the best idea here as looping trough 1300 elements is still quite fast however be aware that there is a faster solution in just finding which type of solutions are no longer available.
For mastermind there are multiple algorithms, see wikipedia, however for your first implementation I think they are too difficult.
You could start by using either
Thijser's idea (slightly better than brute-forcing all possibilities),
or try to emulate a human player: using that a white key-peg means correct color in wrong position and a black key-peg meaning correct color in correct position. You can write an easy recursion to take that info into account:
white-peg -> move the colors around ;
black-peg remove colors to find out which of the colors was the one that was correct-in-correct-pos.

matlab: structural data and multi-level indexing

I have a simple problem with structures.
Lets create:
x(1).a(:, :) = magic(2);
x(2).a(:, :) = magic(2)*2;
x(3).a(:, :) = magic(2)*3;
how to list a(1, 1) from all x-es?
i wanted to do it like:
x(1, :).a(1,1)
but there is an error "Scalar index required for this type of multi-level indexing."
How to approach it? I know I can do it with a loop, but that's probably the worst solution :)
Thanks!
This is not the best datastructure to use if this is the sort of query you'd like to make on it, precisely because this sort of indexing cannot be done directly.
However, here is one approach that works:
cellfun(#(X) X(1,1), {x.a})
The syntax {x.a} converts x from a 'struct array' into a cell array. Then we use cellfun to apply a function as a map over the cell array. The anonymous function #(X) X(1,1) takes one argument X and returns X(1,1).
You can also get your data in this way:
B = cat(3,x.a);
out = reshape(B(1,1,:),1,[]);
By the way, loops are not evil. Sometimes they are even faster than vectorized indexation. Try it both ways, see what suits you best in terms of:
Speed - use the profiler to check
Code clarity - depends on the context. Sometimes vectorized code looks better, sometimes the opposite.

How to check if Fortran array contains value?

I've seen this asked for other languages, but having just found out how nicely Fortran can handle arrays, I thought there might be an easy way to do this without loops.
Currently I'm searching over a 3D array looking at 'nearest neighbours' to see if they contain the letter 'n', and whenever it finds this value, I want it to perform some clusterLabel assignment (which isn't relevant for this question)
I wanted to use if(lastNeighArray.eq."n") then...<rest of code>
but for obvious reasons it doesn't like checking an array against a value. Neither does it like me using lastNeighArray(:), even though I'd like it to check each of the elements one at a time. where(lastNeighArray.eq."n") doesn't work as I have a case statement inside the where loop and I get the error WHERE statements and constructs must not be nested.
So I'm a little stuck. What I really want is something like when(lastNeighArray.eq."n") but that doesn't exist.
I've also looked at any and forall but they don't seem like the right choice.
ANY should actually be the right choice
if ( ANY( lastNeighArray=="n" ) ) then
there is also ALL if you wanted the whole array to contain that value.

Resources