filling 2dArrays with another 2DArray in Lua - for-loop

is there a way to fill a 2d Array with another 2dArray in Lua? what im using right now is this
local T4 = {
{0, 0, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 1, 1, 1, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}
};
function myFunc()
local Pieces = {}
for x = 1, 5 do
Pieces[x]={}
for y = 1, 5 do
Pieces[y][x] = T4[y][x]--the error is probably here
end
end
end
but this is not working,ive got a good reason to do this and its because this process gets repeated a lot of times so using T4 is not an option
also im not getting an error,the program just stops there,so any idea how to do this?

You've got your indexes messed up:
function myFunc()
local Pieces = {}
for y = 1, 5 do
Pieces[y]={}
for x = 1, 5 do
Pieces[y][x] = T4[y][x]
end
end
return Pieces
end
You could copy any table using something like this:
function copytable(t)
local copy = {}
for key,val in pairs(t) do
if type(val) == 'table' then
copy[key] = copytable(val)
else
copy[key] = val
end
end
return copy
end
This is off the top of my head so use with cation. It definitely doesn't deal with cyclic references (a table which contains a reference to the same table).

Related

How can you efficiently flip a large range of indices's values from 1 to 0 or vice versa

You're given an N sized array arr. Suppose there's a contiguous interval arr[a....b] where you want to flip all the 1s to 0s and vice versa. Now suppose that there are a large (millions or billions) of these intervals (they could have different starting and end points) that you need to process. Is there an efficient algorithm to get this done?
Note that a and b are inclusive. N can be any finite size essentially. The purpose of the question was just to practice algorithms.
Consider arr = [0,0,0,0,0,0,0]
Consider that we want to flips the following inclusive intervals [1,3], [0,4]
After process [1,3], we have arr = [0,1,1,1,0,0,0] and after processing [0,4], we have arr = [1,0,0,0,1,0,0], which is the final array.
The obvious efficient way to do that is to not do that. Instead first collect at what indices the flipping changes, and then do one pass to apply the collected flipping information.
Python implementation of a naive solution, the efficient solution, and testing:
def naive(arr, intervals):
for a, b in intervals:
for i in range(a, b+1):
arr[i] ^= 1
def efficient(arr, intervals):
flips = [0] * len(arr)
for a, b in intervals:
flips[a] ^= 1
flips[b+1] ^= 1
xor = 0
for i, flip in enumerate(flips):
xor ^= flip
arr[i] ^= xor
def test():
import random
n = 30
arr = random.choices([0, 1], k=n)
intervals = []
while len(intervals) < 100:
a = random.randrange(n-1)
b = random.randrange(n-1)
if a <= b:
intervals.append((a, b))
print(f'{arr = }')
expect = arr * 1
naive(expect, intervals)
print(f'{expect = }')
result = arr * 1
efficient(result, intervals)
print(f'{result = }')
print(f'{(result == expect) = }')
test()
Demo output:
arr = [1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0]
expect = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
result = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
(result == expect) = True
Cast to Int Array and use bitwise not if you are using C or C++. But this is an SIMD task so its parallelizable if you wish.

Why is only one value in my hash being changed?

I'm making a simple RPG as a learning project, and am having an issue with part of the character creator.
This code should determine what skill string is assigned to player[:caste][:skill] and player[:sub][:skill], then increase each respective skill's value in player[:skills] by 2. This code should work regardless of what string is assigned to player[:caste][:skill] and player[:sub][:skill], as long as it is equal to player[:skills].to_s.
Currently, it is only applying the change to player[:skills][:endurance] but not player[:skills][:athletics].
player = {
caste: {skill: "athletics"},
sub: {skill: "endurance"},
skills: {acrobatics: 0, athletics: 0, engineering: 0, endurance: 0, heal: 0, history: 0, influence: 0, insight: 0, magicka: 0, perception: 0, riding: 0, stealth: 0, streetwise: 0, thievery: 0},
}
player[:skills] = player[:skills].map do |skill, mod|
[skill, (mod += 2 if skill.to_s == player[:caste][:skill])]
[skill, (mod += 2 if skill.to_s == player[:sub][:skill])]
end.to_h
In other words, my code is returning the following player[:skills] hash:
skills: {acrobatics: 0, athletics: 0, engineering: 0, endurance: 2, heal: 0, history: 0, influence: 0, insight: 0, magicka: 0, perception: 0, riding: 0, stealth: 0, streetwise: 0, thievery: 0}
but I want it to return:
skills: {acrobatics: 0, athletics: 2, engineering: 0, endurance: 2, heal: 0, history: 0, influence: 0, insight: 0, magicka: 0, perception: 0, riding: 0, stealth: 0, streetwise: 0, thievery: 0}
Please let me know if there is a simpler way to do this. I've also tried the following:
player[:skills] = player[:skills].map do |skill, mod|
[skill, (mod += 2 if skill.to_s == (player[:caste][:skill] || player[:sub][:skill]))]
end.to_h
which only affects the skill found in player[:caste][:skill].
When I run your code I get this as the result.
{:acrobatics=>nil, :athletics=>nil, :engineering=>nil, :endurance=>2, :heal=>nil, :history=>nil, :influence=>nil, :insight=>nil, :magicka=>nil, :perception=>nil, :riding=>nil, :stealth=>nil, :streetwise=>nil, :thievery=>nil}
That's because map returns last statement executed. In addition you actually only set a value for skill when it's matches the sub skill otherwise, it is set to nil.
So whats happening in your code is that each iteration is returning the following which is the result of the last statement in the block passed into map.
[:acrobatics, nil]
[:athletics, nil]
[:engineering, nil]
[:endurance, 2]
[:heal, nil]
[:history, nil]
[:influence, nil]
[:insight, nil]
[:magicka, nil]
[:perception, nil]
[:riding, nil]
[:stealth, nil]
[:streetwise, nil]
[:thievery, nil]
The final result being an array that looks like this.
[[:acrobatics, nil], [:athletics, nil], [:engineering, nil], [:endurance, 2], [:heal, nil], [:history, nil], [:influence, nil], [:insight, nil], [:magicka, nil], [:perception, nil], [:riding, nil], [:stealth, nil], [:streetwise, nil], [:thievery, nil]]
Which is finally mapped to a new hash
{:acrobatics=>nil, :athletics=>nil, :engineering=>nil, :endurance=>2, :heal=>nil, :history=>nil, :influence=>nil, :insight=>nil, :magicka=>nil, :perception=>nil, :riding=>nil, :stealth=>nil, :streetwise=>nil, :thievery=>nil}
The reason you get all those nil's is because in your statements the result of the case were the if statement is not true is nil.
For example:
[skill (mod += 2 if skill.to_s == player[:caste][:skill])]
will return [the_skill, nil] for the cases were skill.to_s == player[:caste][:skill] is not true
To see what's happening try this in irb.
x = 0
=> 0
x += 1 if false
=> nil
x += 1 if true
=> 1
You could get past that using something like this.
[skill, skill.to_s == player[:caste][:skill] ? mod + 2 : mod ]
or using the above example:
x = 0
=> 0
x = false ? x + 1 : x
=> 0
x = true ? x + 1 : x
=> 1
The following modified version of your code should work.
player[:skills] = player[:skills].map do |skill, mod|
[skill, skill.to_s == player[:caste][:skill] || skill.to_s == player[:sub][:skill] ? mod + 2 : mod ]
end.to_h
However, here is a slightly more verbose, but hopefully much easier to follow way to accomplish what you want to do and allows for added modifications in the future with out the code getting too confusing.
player = {
caste: {skill: "athletics"},
sub: {skill: "endurance"},
skills: {acrobatics: 0, athletics: 0, engineering: 0, endurance: 0, heal: 0, history: 0, influence: 0, insight: 0, magicka: 0, perception: 0, riding: 0, stealth: 0, streetwise: 0, thievery: 0},
}
player_caste_skill = player[:caste][:skill]
player_sub_skill = player[:sub][:skill]
current_skills = player[:skills]
updated_skills = {}
current_skills.each_pair do |skill, prev_value|
new_value = prev_value
case skill.to_s
when player_caste_skill, player_sub_skill
new_value = prev_value + 2
when "some_other_skill"
new_value = prev_value + 3
end
updated_skills[skill] = new_value
end
puts current_skills
puts updated_skills
I'd set a default value (Hash#default) to the player[:skill] hash, just to avoid errors in case of missing key (it adds the key!!), allowing to add also a new key without the need to initialise to 0 each skill.
player[:skills].default = 0
Then scan the keys you need to increment in just one liner:
[:caste, :sub].each { |key| player.dig(key, :skill).to_sym.then { |skill| player[:skills][skill] += 2 } }
Thanks to the initialisation, your player can also be
player = {
caste: {skill: "athletics"},
sub: {skill: "endurance"},
skills: {}
}
Returning a result like:
player #=> {:caste=>{:skill=>"athletics"}, :sub=>{:skill=>"endurance"}, :skills=>{:athletics=>2, :endurance=>2}}
Where:
player[:skills][:whatever] #=> 0
I would iterate through defined skills rather than through skill values.
player.
map { |_, h| h[:skill] }.
compact.
map(&:to_sym).
each { |skill| player[:skills][skill] += 2 }
Now player is updated accordingly, as you might check by exaimning player with p player or like.
Change the code to be something like this:
player = {
caste: {skill: "athletics"},
sub: {skill: "endurance"},
skills: {acrobatics: 0, athletics: 0, engineering: 0, endurance: 0, heal: 0,
history: 0, influence: 0, insight: 0, magicka: 0, perception: 0, riding: 0,
stealth: 0, streetwise: 0, thievery: 0},
}
player[:skills] = player[:skills].map do |skill, mod|
[skill, (mod += 2 if [player[:caste][:skill], player[:sub][:skill]].include?
(skill.to_s))]
end.to_h
The reason your code didn't work because map return the last line as a result for the current iteration, So in the athletics case the last line which is
[skill, (mod += 2 if skill.to_s == player[:sub][:skill])]
will be false which will be nil that's why only endurance case works.
hope it helps.

Linearly reading a multi-dimensional array obeying dimensional sub-sectioning

I have an API for reading multi-dimensional arrays, requiring to pass a vector of ranges to read sub-rectangles (or hypercubes) from the backing array. I want to read this array "linearly", all elements in some given order with arbitrary chunk sizes. Thus, the task is with an off and a len, to translate the elements covered by this range into the smallest possible set of hyper-cubes, i.e. the smallest number of read commands issued in the API.
For example, we can calculate index vectors for the set of dimensions giving a linear index:
def calcIndices(off: Int, shape: Vector[Int]): Vector[Int] = {
val modsDivs = shape zip shape.scanRight(1)(_ * _).tail
modsDivs.map { case (mod, div) =>
(off / div) % mod
}
}
Let's say the shape is this, representing an array with rank 4 and 120 elements in total:
val sz = Vector(2, 3, 4, 5)
val num = sz.product // 120
A utility to print these index vectors for a range of linear offsets:
def printIndices(off: Int, len: Int): Unit =
(off until (off + len)).map(calcIndices(_, sz))
.map(_.mkString("[", ", ", "]")).foreach(println)
We can generate all those vectors:
printIndices(0, num)
[0, 0, 0, 0]
[0, 0, 0, 1]
[0, 0, 0, 2]
[0, 0, 0, 3]
[0, 0, 0, 4]
[0, 0, 1, 0]
[0, 0, 1, 1]
[0, 0, 1, 2]
[0, 0, 1, 3]
[0, 0, 1, 4]
[0, 0, 2, 0]
[0, 0, 2, 1]
[0, 0, 2, 2]
[0, 0, 2, 3]
[0, 0, 2, 4]
[0, 0, 3, 0]
[0, 0, 3, 1]
[0, 0, 3, 2]
[0, 0, 3, 3]
[0, 0, 3, 4]
[0, 1, 0, 0]
...
[1, 2, 1, 4]
[1, 2, 2, 0]
[1, 2, 2, 1]
[1, 2, 2, 2]
[1, 2, 2, 3]
[1, 2, 2, 4]
[1, 2, 3, 0]
[1, 2, 3, 1]
[1, 2, 3, 2]
[1, 2, 3, 3]
[1, 2, 3, 4]
Let's look at an example chunk that should be read,
the first six elements:
val off1 = 0
val len1 = 6
printIndices(off1, len1)
I will already partition the output by hand into hypercubes:
// first hypercube or read
[0, 0, 0, 0]
[0, 0, 0, 1]
[0, 0, 0, 2]
[0, 0, 0, 3]
[0, 0, 0, 4]
// second hypercube or read
[0, 0, 1, 0]
So the task is to define a method
def partition(shape: Vector[Int], off: Int, len: Int): List[Vector[Range]]
which outputs the correct list and uses the smallest possible list size.
So for off1 and len1, we have the expected result:
val res1 = List(
Vector(0 to 0, 0 to 0, 0 to 0, 0 to 4),
Vector(0 to 0, 0 to 0, 1 to 1, 0 to 0)
)
assert(res1.map(_.map(_.size).product).sum == len1)
A second example, elements at indices 6 until 22, with manual partitioning giving three hypercubes or read commands:
val off2 = 6
val len2 = 16
printIndices(off2, len2)
// first hypercube or read
[0, 0, 1, 1]
[0, 0, 1, 2]
[0, 0, 1, 3]
[0, 0, 1, 4]
// second hypercube or read
[0, 0, 2, 0]
[0, 0, 2, 1]
[0, 0, 2, 2]
[0, 0, 2, 3]
[0, 0, 2, 4]
[0, 0, 3, 0]
[0, 0, 3, 1]
[0, 0, 3, 2]
[0, 0, 3, 3]
[0, 0, 3, 4]
// third hypercube or read
[0, 1, 0, 0]
[0, 1, 0, 1]
expected result:
val res2 = List(
Vector(0 to 0, 0 to 0, 1 to 1, 1 to 4),
Vector(0 to 0, 0 to 0, 2 to 3, 0 to 4),
Vector(0 to 0, 1 to 1, 0 to 0, 0 to 1)
)
assert(res2.map(_.map(_.size).product).sum == len2)
Note that for val off3 = 6; val len3 = 21, we would need four readings.
The idea of the following algorithm is as follows:
a point-of-interest (poi) is the left-most position
at which two index representations differ
(for example for [0, 0, 0, 1] and [0, 1, 0, 0] the poi is 1)
we recursively sub-divide the original (start, stop) linear index range
we use motions in two directions, first by keeping the start constant
and decreasing the stop through a special "ceil" operation on the start,
later by keeping the stop constant and increasing the start through
a special "floor" operation on the stop
for each sub range, we calculate the poi of the boundaries, and
we calculate "trunc" which is ceil or floor operation described above
if this trunc value is identical to its input, we add the entire region
and return
otherwise we recurse
the special "ceil" operation takes the previous start value and
increases the element at the poi index and zeroes the subsequent elements;
e.g. for [0, 0, 1, 1] and poi = 2, the ceil would be [0, 0, 2, 0]
the special "floor" operation takes the previous stop value and
zeroes the elements after the poi index;
e.g. for [0, 0, 1, 1], and poi = 2, the floor would be [0, 0, 1, 0]
Here is my implementation. First, a few utility functions:
def calcIndices(off: Int, shape: Vector[Int]): Vector[Int] = {
val modsDivs = (shape, shape.scanRight(1)(_ * _).tail, shape.indices).zipped
modsDivs.map { case (mod, div, idx) =>
val x = off / div
if (idx == 0) x else x % mod
}
}
def calcPOI(a: Vector[Int], b: Vector[Int], min: Int): Int = {
val res = (a.drop(min) zip b.drop(min)).indexWhere { case (ai,bi) => ai != bi }
if (res < 0) a.size else res + min
}
def zipToRange(a: Vector[Int], b: Vector[Int]): Vector[Range] =
(a, b).zipped.map { (ai, bi) =>
require (ai <= bi)
ai to bi
}
def calcOff(a: Vector[Int], shape: Vector[Int]): Int = {
val divs = shape.scanRight(1)(_ * _).tail
(a, divs).zipped.map(_ * _).sum
}
def indexTrunc(a: Vector[Int], poi: Int, inc: Boolean): Vector[Int] =
a.zipWithIndex.map { case (ai, i) =>
if (i < poi) ai
else if (i > poi) 0
else if (inc) ai + 1
else ai
}
Then the actual algorithm:
def partition(shape: Vector[Int], off: Int, len: Int): List[Vector[Range]] = {
val rankM = shape.size - 1
def loop(start: Int, stop: Int, poiMin: Int, dir: Boolean,
res0: List[Vector[Range]]): List[Vector[Range]] =
if (start == stop) res0 else {
val last = stop - 1
val s0 = calcIndices(start, shape)
val s1 = calcIndices(stop , shape)
val s1m = calcIndices(last , shape)
val poi = calcPOI(s0, s1m, poiMin)
val ti = if (dir) s0 else s1
val to = if (dir) s1 else s0
val st = if (poi >= rankM) to else indexTrunc(ti, poi, inc = dir)
val trunc = calcOff(st, shape)
val split = trunc != (if (dir) stop else start)
if (split) {
if (dir) {
val res1 = loop(start, trunc, poiMin = poi+1, dir = true , res0 = res0)
loop (trunc, stop , poiMin = 0 , dir = false, res0 = res1)
} else {
val s1tm = calcIndices(trunc - 1, shape)
val res1 = zipToRange(s0, s1tm) :: res0
loop (trunc, stop , poiMin = poi+1, dir = false, res0 = res1)
}
} else {
zipToRange(s0, s1m) :: res0
}
}
loop(off, off + len, poiMin = 0, dir = true, res0 = Nil).reverse
}
Examples:
val sz = Vector(2, 3, 4, 5)
partition(sz, 0, 6)
// result:
List(
Vector(0 to 0, 0 to 0, 0 to 0, 0 to 4), // first hypercube
Vector(0 to 0, 0 to 0, 1 to 1, 0 to 0) // second hypercube
)
partition(sz, 6, 21)
// result:
List(
Vector(0 to 0, 0 to 0, 1 to 1, 1 to 4), // first read
Vector(0 to 0, 0 to 0, 2 to 3, 0 to 4), // second read
Vector(0 to 0, 1 to 1, 0 to 0, 0 to 4), // third read
Vector(0 to 0, 1 to 1, 1 to 1, 0 to 1) // fourth read
)
The maximum number of reads, if I'm not mistaken, would be 2 * rank.

Nested if else inside .each iteration

I'm wondering if this makes sense or if the syntax is wrong and basically if this is acceptable. I wanted to nest an if/else condition within my iteration of the array.
def change_numbers(first_array, second_array)
second_array.each do |index|
if first_array[index] == 0
first_array[index] = 1
else
first_array[index] = 0
end
end
end
The array is a simple (binary) array and will only consist of 0s and 1s and I want to use the second array's elements as the indices of the first array that I am going to change.
Example:
first_array = [0, 0, 0, 0, 1, 1, 1, 1, 1]
second_array = [3, 5, 7]
Result:
first_array = [0, 0, 0, 1, 1, 0, 1, 0, 1]
If you don't want to use an if/else you can do:
second_array.each do |index|
first_array[index] = (first_array[index] + 1) % 2
end
def change_numbers(first_array, second_array)
second_array.each { |index| first_array[index] = 1 - first_array[index] }
end
A bit-wise XOR:
ar = [0, 0, 0, 0, 1, 1, 1, 1, 1]
indices = [3, 5, 7]
indices.each{|i| ar[i] ^= 1 }
You can try this -
def change_numbers(first_array, second_array)
second_array.each do |index|
first_array[index] = ((first_array[index] == 0) ? 1 : 0)
end
end

how many ways are there to see if a number is even, and which one is the fastest and clearest?

given any number, what's the best way to determine it is even? how many methods can you think of, and what is the fastest way and clearest way?
bool isEven = ((number & 0x01) == 0)
The question said "any number", so one could either discard floats or handle them in another manner, perhaps by first scaling them up to an integral value first - watching out for overflow - i.e. change 2.1 to 21 (multiply by 10 and convert to int) and then test. It may be reasonable to assume, however, that by mentioning "any number" the person who posed the question is actually referring to integral values.
bool isEven = number % 2 == 0;
isEven(n) = ((-1) ^ n) == 1
where ^ is the exponentiation/pow function of your language.
I didn't say it was fast or clear, but it has novelty value.
The answer depends on the position being applied for. If you're applying for an Enterprise Architect position, then the following may be suitable:
First, you should create a proper Service-Oriented Architecture, as certainly the even-odd service won't be the only reusable component in your enterprise. An SOA consists of a service, interface, and service consumers. The service is function which can be invoked over the network. It exposes an interface contract and is typically registered with a Directory Service.
You can then create a Simple Object Access Protocol (SOAP) HTTP Web Service to expose your service.
Next, you should prevent clients from directly calling your Web Service. If you allow this, then you will end up with a mess of point-to-point communication, which is very hard to maintain. Clients should access the Web Service through an Enterprise Service Bus (ESB).
In addition to providing a standard plug-able architecture, additional components like service orchestration can occur on the bus.
Generally, writing a bespoke even/odd service should be avoided. You should write a Request for proposal (RFP), and get several vendors to show you their even/odd service. The vendor's product should be able to plug into your ESB, and also provide you with an Service level agreement (SLA).
This is even easier in ruby:
isEven = number.even?
Yes.. The fastest way is to check the 1 bit, because it is set for all odd numbers and unset for all even numbers..
Bitwise ANDs are pretty fast.
If your type 'a' is an integral type, then we can define,
even :: Integral a => a -> Bool
even n = n `rem` 2 == 0
according to the Haskell Prelude.
For floating points, of course within a reasonable bound.
modf(n/2.0, &intpart, &fracpart)
return fracpart == 0.0
With some other random math functions:
return gcd(n,2) == 2
return lcm(n,2) == n
return cos(n*pi) == 1.0
If int is 32 bits then you could do this:
bool is_even = ((number << 31) >> 31) == 0;
With using bit shifts you'll shift the right-most bit to the left-most position and then back again, thus making all other bits 0's. Then the number you're left with is either 0 or 1. This method is somewhat similar to "number & 1" method where you again make all bits 0's except the first one.
Another approach, similar to this one is this:
bool is_even = (number << 31) == 0;
or
bool is_odd = (number << 31) < 0;
If the number is even (the right-most bit is 0), then shifting it 31 positions will make the whole number 0. If the bit is 1, i.e. the number is odd, then the resulting number would be negative (every integer with left-most bit 1 is negative except if the number is of type unsigned, where it won't work). To fix signed/unsigned bug, you can just test:
bool is_odd = (number << 31) != 0;
Actually I think (n % 2 == 0) is enough, which is easy to understand and most compilers will convert it to bit operations as well.
I compiled this program with gcc -O2 flag:
#include <stdio.h>
int main()
{
volatile int x = 310;
printf("%d\n", x % 2);
return 0;
}
and the generated assembly code is
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $310, 28(%esp)
movl 28(%esp), %eax
movl $.LC0, (%esp)
movl %eax, %edx
shrl $31, %edx
addl %edx, %eax
andl $1, %eax
subl %edx, %eax
movl %eax, 4(%esp)
call printf
xorl %eax, %eax
leave
ret
which we can see that % 2 operation is already converted to the andl instruction.
Similar to DeadHead's comment, but more efficient:
#include <limits.h>
bool isEven(int num)
{
bool arr[UINT_MAX] = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
// ...and so on
};
return arr[num];
}
As fast as an array index, which may or may not be faster than bitwise computations (it's difficult to test because I don't want to write the full version of this function). For what it's worth, that function above only has enough filled in to find even numbers up to 442, but would have to go to 4294967295 to work on my system.
With reservations for limited stack space. ;) (Is this perhaps a candidate for tail calls?)
public static bool IsEven(int num) {
if (num < 0)
return !IsEven(-num - 1);
if (num == 0)
return true;
return IsEven(-num);
}
a % 2.
It's clear
It's fast on every decent compiler.
Everyone who cries "But! But! What if compiler doesn't optimize it" should find normal compiler, shut up and read about premature optimization, read again, read again.
If it's low level check if the last (LSB) bit is 0 or 1 :)
0 = Even
1 = Odd
Otherwise, +1 #sipwiz: "bool isEven = number % 2 == 0;"
Assumming that you are dealing with an integer, the following will work:
if ((testnumber & -2)==testnumber) then testnumber is even.
basically, -2 in hex will be FFFE (for 16 bits) if the number is even, then anding with with -2 will leave it unchanged.
** Tom **
You can either using integer division and divide it by two and inspect the remainder or use a modulus operator and mod it by two and inspect the remainder. The "fastest" way depends on the language, compiler, and other factors but I doubt there are many platforms for which there is a significant difference.
Recursion!
function is_even (n number) returns boolean is
if n = 0 then
return true
elsif n = 1 then
return false
elsif n < 0 then
return is_even(n * -1)
else
return is_even(n - 2)
end if
end
Continuing the spirit of "how many ways are there...":
function is_even (n positive_integer) returns boolean is
i := 0
j := 0
loop
if n = i then
return (j = 0)
end if;
i := i + 1
j := 1 - j
end loop
end
In response to Chris Lutz, an array lookup is significantly slower than a BITWISE_AND operation. In an array lookup you're doing a memory lookup which will always be slower than a bitwise operation because of memory latency. This of course doesn't even factor in the problem of putting all possible int values into your array which has a memory complexity of O(2^n) where n is your bus size (8,16,32,64).
The odd/even property is only defined in integers. So any answer dealing with floating point is invalid. The abstract representation of this problem is Int -> bool (to use Haskell notation).
Another useless novelty solution:
if (2 * (n/2) == n)
return true;
else
return false;
Only with integers, and it depends on how the langugage handles integer division.
n/2 == n/2 if it's even or n/2-.5 if it's odd.
So 2*(n/2) == n if it's even or n - 1 if it's odd.
Here's a recursive way to do it in python:
def is_even(n: int) -> bool:
if n == 0:
return True
else:
return is_odd(n-1)
def is_odd(n: int) -> bool:
if n == 0:
return False
else:
return is_even(n-1)
Of course, you can add in logic to check if n is negative as well.

Resources