Index variable (_i) in for loops? - coffeescript

Take a look at this simple code:
eat = (x) -> console.log "nom", x
# dog only eats every second cat
feast = (cats) -> eat cat for cat in cats when _i % 2 == 0
feast ["tabby cat"
"siamese cat"
"norwegian forest cat"
"feral cat"
"american bobtail"
"manx"]
$ coffee a.coffee
nom tabby cat
nom norwegian forest cat
nom american bobtail
It seems the _i variable is the current index. Is this a feature, bug, or NaN? I haven't heard anyone else talking about this, so I wonder if there's some reason I shouldn't use it in my code?

tldr-again; The author of CoffeeScript just told me I'm right: Don't use _i.
14:29 <jashkenas> You shouldn't use internal variables.
...
14:42 <meagar> I was hoping something more deeply involved in the language would be able to put some authority behind that opinion
14:43 <meagar> ... I was basically hoping for an authoritative "don't do that"
14:44 <jashkenas> you just got it ;)
14:44 <jashkenas> for item, index in list -- there's your reference to the index.
tldr; This is at best an undocumented feature for which a functionally equivalent documented feature exists. As such, it should not be used.
Your argument of "less typing" is highly dubious; compare:
for x in [1, 2, 3] when _i % 2 == 0
console.log "#{_i} -> #{x}"
for x,i in [1, 2, 3] when i % 2 == 0
console.log "#{i} -> #{x}"
feature, bug, or NaN?
None of these things; it's undefined behaviour. You are assuming that _i will be the variable used for iteration in the compiled JavaScript.
You definitely shouldn't use _i, or assume _i will be defined. That's an implementation detail, and they're free to change it at any time. It's also won't be _i if your loop is nested in another loop; it will be _j or _k etc.
Most importantly, you can do this exact thing without relying on the underlying implementation's JavaSript variables. If you want to loop with an index, just use for value,key in array:
array = ['a', 'b', 'c']
console.log(index) for item, index in array # 0, 1, 2
Specifically, in your example:
feast = (cats) -> eat cat for cat, index in cats when index % 2 == 0

No need to guess, or make assumptions, about what Coffeescript does. Just look at the compiled Javascript. From the 'Try Coffeescript' tab:
feast = (cats) -> eat cat for cat in cats when _i % 2 == 0
produces
feast = function(cats) {
var cat, _i, _len, _results;
_results = [];
for (_i = 0, _len = cats.length; _i < _len; _i++) {
cat = cats[_i];
if (_i % 2 === 0) {
_results.push(eat(cat));
}
}
return _results;
};
...
feast = (cats) -> eat cat for cat, index in cats when index % 2 == 0
produces nearly the identical JS, differing only in that index is used along with or in place of _i.
feast = function(cats) {
var cat, index, _i, _len, _results;
_results = [];
for (index = _i = 0, _len = cats.length; _i < _len; index = ++_i) {
cat = cats[index];
if (index % 2 === 0) {
_results.push(eat(cat));
}
}
return _results;
};
Both work, but index makes your intentions clearer to humans (including your future self). And as others have argued, it is good programming practice to avoid use of undocumented implementation features - unless you really need them. And if you are doing something funny, document it.

Related

jruby concurrent pool threads mixing up when combined for result

There is an array with indices [[0, n_0], [1, n_1], ..., [n, n_n]]. For each n_i a function is called. It is necessary to reorder the result from the threads by first component after every thread has terminated. As far as I could find a way to do this, I organized that the index is hard-coded by asking if the index is e.g. 0 and then starting the code separately for the hard-coded index 0. So far this a possible way to do it (even though the code looks as if someone didn't understand what a loop is for).
rest = []
tpl.each do |idx, vn|
if idx == 0
pool.post do
res = funk(vn)
p ['idx 0: ', res]
rest += [[0, res]]
end#pool.post
elsif idx == 1
pool.post do
res = funk(vn)
p ['idx 1: ', res]
rest += [[1, res]]
end#pool.post
end;end
But now there is a strange behaviour:
Index 0 and 1 are calculated accurately, but when the result of 1 is added one line later, the result of the former function is added (again).
["idx 1: ", [4]]
["idx 0: ", [16900]]
rest: [[0, [16900]], [1, [16900], ...]
This is not always the case, so it depends on the order of the appearance of the results.
If e.g. the calculation of index 0 is finished after the calculation of index 1, then idx 1 is missing, or wrong. But other cases of confused results also appear: idx 0 before idx 1, but result of idx 0 is the result of idx 1.
?
It looks like if the threads are not really separated. Can that be enforced, or is there a smarter way of keeping indeces?
One option, I found out, is to synchronize the threads, but that would make the algorithm slower again, so a better solution is:
The results don't get mixed up, if the rest-tuple already has the structure to differentiate the results coming in:
rest = [[], []]
tpl.each do |idx, vn|
if idx == 0
pool.post do
res = funk(vn)
p ['idx 0: ', res]
rest[0] << [0, res]
end#pool.post
elsif idx == 1
pool.post do
res = funk(vn)
p ['idx 1: ', res]
rest[1] << [1, res]
end#pool.post
end;end

Minimum cost solution to connect all elements in set A to at least one element in set B

I need to find the shortest set of paths to connect each element of Set A with at least one element of Set B. Repetitions in A OR B are allowed (but not both), and no element can be left unconnected. Something like this:
I'm representing the elements as integers, so the "cost" of a connection is just the absolute value of the difference. I also have a cost for crossing paths, so if Set A = [60, 64] and Set B = [63, 67], then (60 -> 67) incurs an additional cost. There can be any number of elements in either set.
I've calculated the table of transitions and costs (distances and crossings), but I can't find the algorithm to find the lowest-cost solution. I keep ending up with either too many connections (i.e., repetitions in both A and B) or greedy solutions that omit elements (e.g., when A and B are non-overlapping). I haven't been able to find examples of precisely this kind of problem online, so I hoped someone here might be able to help, or at least point me in the right direction. I'm not a graph theorist (obviously!), and I'm writing in Swift, so code examples in Swift (or pseudocode) would be much appreciated.
UPDATE: The solution offered by #Daniel is almost working, but it does occasionally add unnecessary duplicates. I think this may be something to do with the sorting of the priorityQueue -- the duplicates always involve identical elements with identical costs. My first thought was to add some kind of "positional encoding" (yes, Transformer-speak) to the costs, so that the costs are offset by their positions (though of course, this doesn't guarantee unique costs). I thought I'd post my Swift version here, in case anyone has any ideas:
public static func voiceLeading(from chA: [Int], to chB: [Int]) -> Set<[Int]> {
var result: Set<[Int]> = Set()
let im = intervalMatrix(chA, chB: chB)
if im.count == 0 { return [[0]] }
let vc = voiceCrossingCostsMatrix(chA, chB: chB, cost: 4)
// NOTE: cm contains the weights
let cm = VectorUtils.absoluteAddMatrix(im, toMatrix: vc)
var A_links: [Int:Int] = [:]
var B_links: [Int:Int] = [:]
var priorityQueue: [Entry] = []
for (i, a) in chA.enumerated() {
for (j, b) in chB.enumerated() {
priorityQueue.append(Entry(a: a, b: b, cost: cm[i][j]))
if A_links[a] != nil {
A_links[a]! += 1
} else {
A_links[a] = 1
}
if B_links[b] != nil {
B_links[b]! += 1
} else {
B_links[b] = 1
}
}
}
priorityQueue.sort { $0.cost > $1.cost }
while priorityQueue.count > 0 {
let entry = priorityQueue[0]
if A_links[entry.a]! > 1 && B_links[entry.b]! > 1 {
A_links[entry.a]! -= 1
B_links[entry.b]! -= 1
} else {
result.insert([entry.a, (entry.b - entry.a)])
}
priorityQueue.remove(at: 0)
}
return result
}
Of course, since the duplicates have identical scores, it shouldn't be a problem to just remove the extras, but it feels a bit hackish...
UPDATE 2: Slightly less hackish (but still a bit!); since the requirement is that my result should have equal cardinality to max(|A|, |B|), I can actually just stop adding entries to my result when I've reached the target cardinality. Seems okay...
UPDATE 3: Resurrecting this old question, I've recently had some problems arise from the fact that the above algorithm doesn't fulfill my requirement |S| == max(|A|, |B|) (where S is the set of pairings). If anyone knows of a simple way of ensuring this it would be much appreciated. (I'll obviously be poking away at possible changes.)
This is an easy task:
Add all edges of the graph in a priority_queue, where the biggest priority is the edge with the biggest weight.
Look each edge e = (u, v, w) in the priority_queue, where u is in A, v is in B and w is the weight.
If removing e from the graph doesn't leave u or v isolated, remove it.
Otherwise, e is part of the answer.
This should be enough for your case:
#include <bits/stdc++.h>
using namespace std;
struct edge {
int u, v, w;
edge(){}
edge(int up, int vp, int wp){u = up; v = vp; w = wp;}
void print(){ cout<<"("<<u<<", "<<v<<")"<<endl; }
bool operator<(const edge& rhs) const {return w < rhs.w;}
};
vector<edge> E; //edge set
priority_queue<edge> pq;
vector<edge> ans;
int grade[5] = {3, 3, 2, 2, 2};
int main(){
E.push_back(edge(0, 2, 1)); E.push_back(edge(0, 3, 1)); E.push_back(edge(0, 4, 4));
E.push_back(edge(1, 2, 5)); E.push_back(edge(1, 3, 2)); E.push_back(edge(1, 4, 0));
for(int i = 0; i < E.size(); i++) pq.push(E[i]);
while(!pq.empty()){
edge e = pq.top();
if(grade[e.u] > 1 && grade[e.v] > 1){
grade[e.u]--; grade[e.v]--;
}
else ans.push_back(e);
pq.pop();
}
for(int i = 0; i < ans.size(); i++) ans[i].print();
return 0;
}
Complexity: O(E lg(E)).
I think this problem is "minimum weighted bipartite matching" (although searching for " maximum weighted bipartite matching" would also be relevant, it's just the opposite)

Specman On the Fly Generation: How to constrain a list whose values are differ from each other at least 2

I need to generate a random list values with the next constrain:
my_list[i] not in [my_list[i-1] .. my_list[i-1] + 1]
i.e. all values in the list are different and with at least difference of 2 between each other. All code variations I've tried failed, e.g.:
var prev_val : uint = 0;
gen my_list keeping {
it.size() == LIST_SIZE;
it.all_different(it);
for each (val) in it {
val not in [prev_val .. prev_val + 1];
prev_val = val;
};
};
How such list can be generated? Thank you for your help
I am not sure I fully understand the request but following your code:
gen my_list keeping {
it.size() == LIST_SIZE;
it.all_different(it);
keep for each (val) in it {
val != prev;
val != prev + 1;
};
};
This will generate a list (all items will be generate together) according to your rule:
my_list[i] not in [my_list[i-1] .. my_list[i-1] + 1]
But the following list is a valid solution: 0,2,1,3,5,4,6,8,7,9,11,10,12,...
which doesn't follow "the all values in the list are different and with at least difference of 2 between each other".
To generate a list according to the "text request", you must use double keep for each and abs:
gen my_list keeping {
it.size() == LIST_SIZE;
for each (val1) using index (i1) in it {
for each (val2) using index (i2) in it {
i1 < i2 => abs(val1-val2) >= 2;
};
};
If you want my_list to be sorted (and will be solved faster) :
gen my_list keeping {
it.size() == LIST_SIZE;
it.size() == LIST_SIZE;
it.all_different(it);
for each (val) in it {
val >= prev + 2;
};
};
You could try the following:
gen my_list keeping {
it.size() == 10;
it.all_different(it);
for each (val) in it {
index > 0 =>
val not in [value(it[index - 1]) .. value(it[index - 1]) + 1];
};
};
The solver requires the it[index - 1] expression in the constraint be "fixed" at the point of generation, hence the use of value(...). This means that the list will be generated element by element.
If that's a problem, you could change to:
index > 0 =>
val != it[index - 1] + 1;
This should be equivalent, since the all_different(...) constraint should make sure that an element doesn't have the same value as the previous one. Naturally, this won't work if you have a wider set.

Merging two sorted lists, one with additional 0s

Consider the following problem:
We are given two arrays A and B such that A and B are sorted
except A has B.length additional 0s appended to its end. For instance, A and B could be the following:
A = [2, 4, 6, 7, 0, 0, 0]
B = [1, 7, 9]
Our goal is to create one sorted list by inserting each entry of B
into A in place. For instance, running the algorithm on the above
example would leave
A = [1, 2, 4, 6, 7, 7, 9]
Is there a clever way to do this in better than O(n^2) time? The only way I could think of is to insert each element of B into A by scanning linearly and performing the appropriate number of shifts, but this leads to the O(n^2) solution.
Some pseudo-code (sorta C-ish), assuming array indexing is 0-based:
pA = A + len(A) - 1;
pC = pA; // last element in A
while (! *pA) --pA; // find the last non-zero entry in A
pB = B + len(B) - 1;
while (pA >= A) && (pB >= B)
if *pA > *pB
*pC = *pA; --pA;
else
*pC = *pB; --pB;
--pC
while (pB >= B) // still some bits in B to copy over
*pC = *pB; --pB; --pC;
Not really tested, and just written off the top of my head, but it should give you the idea... May not have the termination and boundary conditions exactly right.
You can do it in O(n).
Work from the end, moving the largest element towards the end of A. This way you avoid a lot of trouble to do with where to keep the elements while iterating. This is pretty easy to implement:
int indexA = A.Length - B.Length - 1;
int indexB = B.Length - 1;
int insertAt = A.Length;
while (indexA > 0 || indexB > 0)
{
insertAt--;
A[insertAt] = max(B[indexB], A[indexA]);
if (A[indexA] <= B[indexB])
indexB--;
else
indexA--;
}

How to find the Intersection of n arrays

I have n arrays or variable length
arr1 = [1,2,3]
arr2 = [1,3,5,8]
....
How can I compute the intersection of those n arrays ?
Consider checking out underscore.js library. It provides function for what you need and a bunch of other usefull functions.
Example from docs:
_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2]
Simple plain JS implementation can be found here. Same idea in CoffeeScript:
intersect_all = (lists) ->
if lists.length is 0
return []
else return lists[0] if lists.length is 1
partialInt = lists[0]
i = 1
while i < lists.length
partialInt = intersection(partialInt, lists[i])
i++
partialInt
The most efficient way is to use hashsets:
function hashset (elements) {
var i, set = {};
if (!Array.isArray(elements)) return elements;
for (i = 0; i < elements.length; i++) {
set[elements[i]] = true;
}
return set;
};
function intersect (a, b) {
var k
, s1 = hashset(a)
, s2 = hashset(b)
, s3 = {}
for (k in s1) {
if (s2[k]) s3[k] = true;
}
return s3;
};
Object.keys(intersect(arr1,arr2));
// ["1", "3"]
You will find CoffeeScript source of this code, benchmarks for it and some additional information in this question.
If you're going to to intersect huge arrays then I strongly recommend you to use this approach.
Either just use something like _.intersection or study the source of that implementation and rewrite it if you like.