From the documentation:
A set in Dart is an unordered collection of unique items.
But if I run this sample code:
final a = {0, 1, 2};
final b = {2, 1, 0};
for (final i in a) {
print('a - $i');
}
for (final i in b) {
print('b - $i');
}
print(a == b);
I get the output
a - 0
a - 1
a - 2
b - 2
b - 1
b - 0
false
The 2 iterables a and b don't behave the same when looped over and == is false (But I guess == makes sense since the a and b are not the same instance).
However, what I don't understand is if a and b are constants:
const a = {0, 1, 2};
const b = {2, 1, 0};
for (final i in a) {
print('a - $i');
}
for (final i in b) {
print('b - $i');
}
print(a == b);
This yields the same output.
And if I order b as a:
const a = {0, 1, 2};
const b = {0, 1, 2};
for (final i in a) {
print('a - $i');
}
for (final i in b) {
print('b - $i');
}
print(a == b);
It logs:
a - 0
a - 1
a - 2
b - 0
b - 1
b - 2
true
I'm a bit surprised that const a = {0, 1, 2} and const b = {2, 1, 0} are not equal. Aren't const variable being reused, and aren't a and b supposed to be equal since sets are unordered?
What am I missing?
Dart sets are ordered in the sense that if you use their iterator, you get elements in some order. That order may or may not be predictable. The order is unspecified for sets in general, but some Set implementations may choose to specify a specific ordering.
The one thing that is required is that the ordering of a set doesn't change unless the set changes. So, if you iterate the same set twice, without changing it in-between, you get the same ordering — whatever it is.
LinkedHashSet promises insertion ordering.
SplayTreeSet promises comparator ordering.
Constant set literals promise source ordering (first occurrence if the same value occurs more than once). They're like immutable LinkedHashSets.
Related
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.
Right now I have this Ruby method that returns 3 different numbers:
# Find integers s and t such that gcd(a,b) = s*a + t*b
# pre: a,b >= 0
# post: return gcd(a,b), s, t
def egcd(a, b)
# let A, B = a, b
s, t, u, v = 1, 0, 0, 1
while 0 < b
# loop invariant: a = sA + tB and b = uA + vB and gcd(a,b) = gcd(A,B)
q = a / b
a, b, s, t, u, v = b, (a%b), u, v, (s-u*q), (t-v*q)
end
[a, s, t]
end
I want to only check the first return value, a.
if egcd(ARGV[3].to_i, 128) != 1
So this statement here does not work since it's returning 3 values, I just want to check if the first value is != 1. I'm fairly new to Ruby, does anyone know of a way to accomplish this? Thanks in advance!
Getting the first value of an array can be done in a few ways:
if egcd(ARGV[3].to_i, 128).first != 1
or
if egcd(ARGV[3].to_i, 128)[0] != 1
If you're only using the first value, I'd suggest re-writing your program to be a little more intuitive. I'd also consider re-writing this piece of code entirely as it doesn't read nicely at all.
Since your return value is an array, check to see if the first value of the array is not 1.
if egcd(ARGV[3].to_i, 128).first != 1
or
unless egcd(ARGV[3].to_i, 128).first == 1
You can do it this way:
if egcd(ARGV[3].to_i, 128)[0] != 1
...since the return is actually an array.
I am currently learning Racket (just for fun) and I stumbled upon this example:
(define doubles
(stream-cons
1
(stream-map
(lambda (x)
(begin
(display "map applied to: ")
(display x)
(newline)
(* x 2)))
doubles)))
It produces 1 2 4 8 16 ...
I do not quite understand how it works.
So it creates 1 as a first element; when I call (stream-ref doubles 1) it creates a second element which is obviously 2.
Then I call (stream-ref doubles 2) which should force creating the third element so it calls stream-map for a stream which already has 2 elements – (1 2) – so it should produce (2 4) then and append this result to the stream.
Why is this stream-map always applied to the last created element? How it works?
Thank you for your help!
This is a standard trick that makes it possible for lazy streams to be defined in terms of their previous element. Consider a stream as an infinite sequence of values:
s = x0, x1, x2, ...
Now, when you map over a stream, you provide a function and produce a new stream with the function applied to each element of the stream:
map(f, s) = f(x0), f(x1), f(x2), ...
But what happens when a stream is defined in terms of a mapping over itself? Well, if we have a stream s = 1, map(f, s), we can expand that definition:
s = 1, map(f, s)
= 1, f(x0), f(x1), f(x2), ...
Now, when we actually go to evaluate the second element of the stream, f(x0), then x0 is clearly 1, since we defined the first element of the stream to be 1. But when we go to evaluate the third element of the stream, f(x1), we need to know x1. Fortunately, we just evaluated x1, since it is f(x0)! This means we can “unfold” the sequence one element at a time, where each element is defined in terms of the previous one:
f(x) = x * 2
s = 1, map(f, s)
= 1, f(x0), f(x1), f(x2), ...
= 1, f(1), f(x1), f(x2), ...
= 1, 2, f(x1), f(x2), ...
= 1, 2, f(2), f(x2), ...
= 1, 2, 4, f(x2), ...
= 1, 2, 4, f(4), ...
= 1, 2, 4, 8, ...
This knot-tying works because streams are evaluated lazily, so each value is computed on-demand, left-to-right. Therefore, each previous element has been computed by the time the subsequent one is demanded, and the self-reference doesn’t cause any problems.
Example. I've got an array with 15 objects. I want to start enumerating from a given index. Say start at index 5 and then the index above, the index under, above, under etc... I do want it to wrap around.
So the order of indexes in my example would be. 5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0, 11, 14, 12, 13
It would be great to have a method signature similar to following line, but I don't require that to approva an answer:
- (void)enumerateFromIndex:(NSUInteger)index wrapAroundAndGoBothWays:(void (^)(id obj, NSUInteger idx, BOOL *stop))block
How can this be done? Would like to avoid copying array etc.
At this post we do it with no wrap around: Enumerate NSArray starting at givven index searching both ways (no wrap around)
Borrowing from #omz, here is the wrapping variant, which is even simpler:
#implementation NSArray (Extensions)
- (void)enumerateFromIndex:(NSUInteger)index wrapAroundAndGoBothWays:(void (^)(id obj, NSUInteger idx, BOOL *stop))block
{
BOOL stop = NO;
NSUInteger actual = index;
for (NSUInteger i = 0; i < self.count && !stop; i++) {
actual += (2*(i%2)-1)*i;
actual = (self.count + actual)%self.count;
block([self objectAtIndex:actual], actual, &stop);
}
}
#end
This is a mathematical problem. There is a nice solution. However, it involves sorting the list of indexes in advance.
The idea is to lay the integers from 0 to 15 out on a circle and taking the elements in the order they appear on an axis.
Since doing this in ObjC is so tedious, I present the python solution:
from math import pi, cos
def circlesort(N, start):
eps = 1e-8
res = range(N)
def f(x):
return -cos(2*pi*(x-start-eps)/N)
res.sort( lambda x,y:cmp(f(x), f(y)) )
return res
then
print circlesort(15, 5)
outputs
[5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0, 11, 14, 12, 13]
which is the desired result.
EDIT
Okay, here is a C implementation:
#include <stdlib.h>
#include <math.h>
#define sign(x) ((x)>0?1:(x)<0?-1:0)
void circlesort(int* values, int N, int start){
double f(int x)
{
return -cos(2*M_PI*((double)(x-start)-.25)/N);
}
int compare (const void * a, const void * b)
{
return sign( f(*(int*)a) - f(*(int*)b) );
}
qsort (values, N, sizeof(int), compare);
}
This will circlesort an array of integers of lenght N. Use it like this:
int i, N = 15;
int indexes[N];
for (i=0;i<N;i++)
indexes[i] = i;
circlesort(indexes, N, 5);
Now the array indexes is sorted in the desired order. Because there are nested functions, you should add -fnested-functions to the compiler flags.
EDIT 2
Considering the fact that there is a much simpler solution (see my other answer) this one is rather academic.
I hope that someone can shed a light on the (to me) unexpected behavioral difference between the two (result wise) equal queries.
A small program can be worth a thousand words, so here goes :
static void Main(string[] args)
{
var l1 = new List<int> { 1, 2, 3 };
var l2 = new List<int> { 2, 3, 4 };
var q1 = // or var q1 = l1.Join(l2, i => i, j => j, (i, j) => i);
from i in l1
join j in l2
on i equals j
select i;
var q2 = //or var q2 = l1.SelectMany(i => l2.Where(j => i == j));
from i in l1
from j in l2
where i == j
select i;
var a1 = q1.ToList(); // 2 and 3, as expected
var a2 = q2.ToList(); // 2 and 3, as expected
l2.Remove(2);
var b1 = q1.ToList(); // only 3, as expected
var b2 = q2.ToList(); // only 3, as expected
// now here goes, lets replace l2 alltogether.
// Afterwards, I expected the same result as q1 delivered...
l2 = new List<int> { 2, 3, 4 };
var c1 = q1.ToList(); // only 3 ? Still using the previous reference to l2 ?
var c2 = q2.ToList(); // 2 and 3, as expected
}
Now I know that Join internally uses a lookup class to optimize performance, and without too much knowledge, my guess is that the combination of that with captured variables might cause this behavior, but to say I really understand it, no :-)
Is this an example of what Joel calls "a leaky abstraction" ?
Cheers,
Bart
You're actually nearly there, given your query expansions in the comments:
var q1 = l1.Join(l2, i => i, j => j, (i, j) => i);
var q2 = l1.SelectMany(i => l2.Where(j => i == j));
Look at where l2 is used in each case. In the Join case, the value of l2 is passed into the method immediately. (Remember that the value is a reference to the list though... changing the contents of the list isn't the same as changing the value of l2.) Changing the value of l2 later doesn't affect what the query returned by the Join method remembers.
Now look at SelectManay: l2 is only used in the lambda expression... so it's a captured variable. That means that whenever the lambda expression is evaluated, the value of l2 at that moment in time is used... so it will reflect any changes to the value.