JavaScript (ES6), 8585 61 bytes
a=>(l=a.length)&&!(l&l-1)&a.every((e,i)=>e==a[j=i&-i]*a[i-j])
Previous version which checked elements to ensure that they were 1
or -1
:
a=>(l=a.length)&&!(l&l-1)&a.every((e,i)=>i?(j=i&-i)<i?e==a[j]*a[i-j]:e==1|e==-1:e==1)
Explanation:
- The length cannot be zero
- The length must be a power of 2
- The first element must be 1
- Elements in positions that are a power of 2 must be either 1 or -1
- Elements in other positions are the product of all the elements in the positions corresponding to the bitmask, e.g.
a[22] == a[2] * a[4] * a[16]
. Sincea[20] == a[4] * a[16]
has already been checked, onlya[22] == a[2] * a[20]
needs to be checked. - The above check gives degenerate results for
i
not having at least two bits set. In the case of zero bits set, it checks thata[0] == a[0] * a[0]
, which is false fora[0] == -1
, while in the case of one bit set, it checks thata[i] == a[0] * a[i]
.