Enumerate NS_OPTIONS - ios

I have an NS_OPTIONS:
typedef NS_OPTIONS(NSUInteger, BrowserViewMenuOptions) {
BrowserViewMenuOptionNone = 0,
BrowserViewMenuOptionCopy = 1 << 0,
BrowserViewMenuOptionMore = 1 << 1,
BrowserViewMenuOptionShare = 1 << 2,
BrowserViewMenuOptionDelete = 1 << 3,
BrowserViewMenuOptionDownload = 1 << 4,
};
Suppose I have a value like this:
(BrowserViewMenuOptionCopy | BrowserViewMenuOptionMore | BrowserViewMenuOptionShare)
How can I enumerate it like we do for an array?

You cannot enumerate as such, as these are constant values as opposed to elements in a collection, however if the enum follows a pattern without gaps, then you can generate all the numerical values of the enum. Yours does, so:
for (unsigned i = 0; i < 5; i++) {
NSLog(#"value=%u", 1 << i);
}
In order to generate the names, you need a look-up table.

Related

How can I generate a unique, predictable, repeatable, non sequential alphanumeric identifier?

I have to generate identifiers composed of four alphanumerical characters, e.g. B41F.
I have the following requirements:
Each identifier must be unique (there is no central location to lookup existing identifiers)
The identifier must not be obviously sequential (e.g. 1A01, 1A02)
It must be predictable
It must be repeatable using solely the identifier index (on two different environment, the Nth identifier generated, which has index N, must be the same)
The problem is generic to any language. My implementation will be done in dart.
I think this could be done with a PRNG and some LUT, but I could not find any implementation or pseudo-code that respects requirement 4) without replaying the whole sequence. Also, some PRNG implementation have a random component that is not guaranteed to be repeatable over library update.
How can I achieve this? I'm looking for pseudo-code, code or hints.
You should not use a PRNG when identifiers must be unique. RNGs do not promise uniqueness. Some might have a long period before they repeat, but that's at their full bit-range, reducing it to a smaller number may cause conflicts earlier.
Your identifiers are really just numbers in base 36, so you need something like shuffle(index).toRadixString(36) to generate it.
The tricky bit is the shuffle function which must be a permutations of the numbers 0..36^4-1, one which looks random (non-sequential), but can be computed (efficiently?) for any input.
Since 36^4 is not a power of 2, most of the easy bit-shuffles likely won't work.
If you can live with 32^4 numbers only (2^20 ~ 1M) it might be easier.
Then you can also choose to drop O, I, 0 and 1 from the result, which might make it easier to read.
In that case, I'd do something primitive (not cryptographically secure at all), like:
// Represent 20-bit numbers
String represent(int index) {
RangeError.checkValueInInterval(index, 0, 0xFFFFF, "index");
var digits = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
return "${digits[(index >> 15) & 31]}${digits[(index >> 10) & 31]}"
"${digits[(index >> 5) & 31]}${digits[index & 31]}";
}
// Completely naive number shuffler for 20-bit numbers.
// All numbers made up on the spot.
int shuffle(int index) {
RangeError.checkValueInInterval(index, 0, 0xFFFFF, "index");
index ^= 0x35712;
index ^= index << 15;
index ^= index << 4;
index ^= index << 12;
index ^= index << 7;
index ^= index << 17;
return index & 0xFFFFF; // 20 bit only.
}
If you really want the full 36^4 range to be used, I'd probably do something like the shuffle, but in base-six arithmetic. Maybe:
String represent(int index) =>
RangeError.checkValueInInterval(index, 0, 1679615, "index")
.toRadixString(36).toUpperCase();
int shuffle(int index) {
RangeError.checkValueInInterval(index, 0, 1679615, "index");
const seed = [1, 4, 2, 5, 0, 3, 1, 4]; // seed.
var digits = List<int>.filled(8, 0);
for (var i = 0; i < 8; i++) {
digits[i] = index.remainder(6);
index = index ~/ 6;
}
void shiftAdd(List<int> source, int shift, int times) {
for (var n = digits.length - 1 - shift; n >= 0; n--) {
digits[shift + n] = (digits[shift + n] + source[n] * times).remainder(6);
}
}
shiftAdd(seed, 0, 1);
shiftAdd(digits, 3, 2);
shiftAdd(digits, 5, 1);
shiftAdd(digits, 2, 5);
var result = 0;
for (var i = digits.length - 1; i >= 0; i--) {
result = result * 6 + digits[i];
}
return result;
}
Again, this is something I made up on the spot, it "shuffles", but does not promise anything about the properties of the result, other than that they don't look sequential.

add value afterwards to key in table lua

Does someone know how to add an value to an key which already has an value ?
for example:
x = {}
x[1] = {string = "hallo"}
x[1] = {number = 10}
print(x[1].string) --nil
print(x[1].number) --10
It should be possible to print both things out. The same way how it is here possible:
x[1] = { string = "hallo" ; number = 10}
I just need to add some informations afterwards to the table and especially to the same key.
Thanks!
x = {} -- create an empty table
x[1] = {string = "hallo"} -- assign a table with 1 element to x[1]
x[1] = {number = 10} -- assign another table to x[1]
The second assignment overwrites the first assignment.
x[1]["number"] = 10 or short x[1].number = 10 will add a field number with value 10 to the table x[1]
Notice that your x[1] = { string = "hallo" ; number = 10} is acutally equivalent to
x[1] = {}
x[1]["string"] = "hallo"
x[1]["number"] = 10

Convert string into array and do operations

I have a string like: "1234567334535674326774324423". I need to create a method to do the following:
Make an array consisting of digits in the string like [1, 2, 3, ..., 2, 3]
Sum all the odd positions of the array
Sum all the even positions of the array
Multiply the odd sum by 3
Sum step 4 and step 3.
Get the minimum number to sum to step 5 to get the sum that is a multiple of 5.
I don't know how to solve this with rails. If anyone can help me, I would be glad.
I have this:
barcode_array = #invoice.barcode.each_char.map {|c| c.to_i}
impares = [barcode_array[0]] + (1...barcode_array.size).step(2).collect { |i| barcode_array[i] }
pares = (2...barcode_array.size).step(2).collect { |i| barcode_array[i] }
suma_impares = impares.inject(:+)
mult_impares = suma_impares * 3
suma total = mult_impares + pares
I solved it. Here is the code if anyone needs it:
barcode_array = #invoice.barcode.each_char.map {|c| c.to_i}
impares = [barcode_array[0]] + (1...barcode_array.size).step(2).collect { |i| barcode_array[i] }
pares = (2...barcode_array.size).step(2).collect { |i| barcode_array[i] }
suma_impares = impares.inject(:+).to_i
mult_impares = suma_impares * 3
suma_pares = pares.inject(:+).to_i
suma_total = mult_impares + suma_pares
verificador = 10 - (suma_total - (suma_total / 10).to_i * 10)
#invoice.barcode = #invoice.barcode.to_s + verificador.to_s
I'm not sure what you mean in step 6, but here's how I would tackle 1-5:
s = '1234567334535674326774324423'
a = s.chars.map(&:to_i) # convert to an array of integers
odd_sum = 0
even_sum = 0
# sum up odds and evens
a.each_with_index {|n, i| n.even? ? even_sum += n : odd_sum += n}
total = even_sum + odd_sum * 3

Return strings from table values Lua

I am trying to learn how to print strings from a value in a table. For example.
TestTable = { "Apples" = 0, "Oranges" = 1, "Grapes" = 1, "Bananas" = 0}
for i=1, #TestTable do
if TestTable[i] == 1 then
print(TestTable[i]) --> Oranges Grapes
end
end
Not sure if that made sense, but I want to print all the strings with the 1 value.
Unless the __len metamethod is defined, the # operator can only be used on a sequence, but TestTable is not one.
You can use pairs to iterate the table:
TestTable = { Apples = 0, Oranges = 1, Grapes = 1, Bananas = 0}
for k, v in pairs(TestTable) do
if v == 1 then
print(k)
end
end

Reverse bit operation in objective-c / c++

I have opposite question for
If i have:
typedef enum {
SUNDAY = (1 << 0),
MONDAY = (1 << 1),
TUESDAY = (1 << 2),
WEDNESDAY = (1 << 3),
THURSDAY = (1 << 4),
FRIDAY = (1 << 5),
SATURDAY = (1 << 6),
} PFDateDays;
And my input is 65 for example (SUNDAY,SATURDAY) there is a clever way for etract this values from enum?
Here is my method:
-(NSMutableArray*)selectFromMyEnum {
NSMutableArray *returnArray = [[NSMutableArray alloc] init];
int myInput = 62;
NSArray *enumArray = #[#(SATURDAY),#(FRIDAY),#(THURSDAY),#(WEDNESDAY),#(TUESDAY),#(MONDAY),#(SUNDAY)];
for(NSNumber *numberInEnumArray in enumArray) {
if(myInput >= [numberInEnumArray integerValue]) {
[returnArray addObject:numberInEnumArray];
myInput -= [numberInEnumArray integerValue];
}
}
NSLog(#"%#",returnArray);
return returnArray;
}
And this is output:
(
64, //SATURDAY
1 //SUNDAY
)
So this is correct. But maybe there is method I don't know about that allow me to do this without this pointless assign enum to array etc..
Well the first thing that comes to my mind is this. Since your enum is nicely laid out for flagging you can do something like this:
Start with your highest enum value (SATURDAY) and use a bitwise and (&) to check if your value contains it. Then shift the comparison value right by 1 and repeat until your comparison value is zero.
PFDateDays comparison = SATURDAY;
//If your enum doesn't end at 1 like the above example,
//you could also use >= SUNDAY
while(((int)comparison) > 0) {
if((myVal & comparison) == comparison)
//Do what you want, this value is valid
comparison = comparison >> 1;
}

Resources