coffeescript for loop refactoring - coffeescript

I am quite new to coffeescript and I am wondering if any more experienced users could point suggest a refactoring for the following code:
splitCollection: =>
maxLength = Math.ceil(#collection.length / 3)
sets = Math.ceil(#collection.length / maxLength)
start = 0
for x in [1..sets]
if x != sets
#render new BusinessUnits(#collection.models.slice(start, (maxLength + start)))
else
#render new BusinessUnits(#collection.models.slice(start, (#collection.length)))
start+= maxLength
There does not appear to be a while loop in coffeescript which seems to suggest a better mechanism.
Any suggestions appreciated.

Looks like you are using Backbone.js, which includes Underscore.js, which has the groupBy function.
You could create a "bucketNumber" function:
bucketNumber = (value, index) ->
Math.floor( index / #collection.length * 3 )
Then group your collection:
sets = #collection.groupBy bucketNumber
Now, assuming ten items, sets should look something like this:
{0: [{}, {}, {}], 1: [{}, {}, {}], 2: [{}, {}, {}, {}]}
From here, it becomes rather straight-forward
for bucketNumber, bucket of sets
#render new BusinessUnits( bucket )
Here is a jsFiddle showing it in action

You don't need to keep track of your position twice, x is enough:
splitCollection: =>
setSize = Math.ceil #collection.length / 3
sets = Math.ceil #collection.length / maxLength
for x in [1..sets]
#render new BusinessUnits #collection.models[x * setSize...(x+1) * setSize]
Note that there is nothing wrong with passing slice an end greater than the array length.

If I understand your code, you want to split an array in 3 parts (the last one can have less items). In this case write the reusable abstraction for the task. Using underscore:
splitCollection: =>
group_size = Math.ceil(#collection.size() / 3)
_.each _(#collection.models).inGroupsOf(group_size), (group) ->
#render(new BusinessUnits(group))
_.inGroupsOf can be written:
_.mixin({
inGroupsOf: function(array, n) {
var output = [];
for(var index=0; index < array.length; index += n) {
output.push(array.slice(index, index+n));
}
return output;
}
});

Related

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)

Programs for printing reverse triangle patterns with * in scala

I am trying to explore Scala. I am new to Scala. This might be a simple question and searched in google to get below scenario to solve. But couldn't get answers. Instead of Scala I am getting Java related things.
My requirement to print format like below.
* * * * *
* * * *
* * *
*
Can someone suggest me how to get this format.
Thanks in advance.
Kanti
Just for the sake of illustration, here are two possible solution to the problem.
The first one is completely imperative, while the second one is more functional.
The idea is that this serves as an example to help you think how to solve problems in a programmatic way.
As many of us have already commented, if you do not understand the basic ideas behind the solution, then this code will be useless in the long term.
Here is the imperative solution, the idea is simple, we need to print n lines, each line contains n - i starts (where i is the number of the line, starting at 0). The starts are separated by an empty space.
Finally, before printing the starts, we need some padding, looking at example inputs, you can see that the padding starts at 0 and increases by 1 for each line.
def printReverseTriangle(n: Int): Unit = {
var i = 0
var padding = 0
while (i < n) {
var j = padding
while (j > 0) {
print(" ")
j -= 1
}
var k = n - i
while (k > 0) {
print("* ")
k -= 1
}
println()
i += 1
padding += 1
}
}
And here is a more functional approach.
As you can see, in this case we do not need to mutate anything, all the high level operators do that for us. And we only need to focus on the description of the solution.
def printReverseTriangle(size: Int): Unit = {
def makeReverseTriangle(size: Int): List[String] =
List.tabulate(size) { i =>
(" " * (size - i)) + ("* " * i)
}.reverse
println(makeReverseTriangle(size).mkString("\n"))
}
To add an alternative to Luis's answer, here's a recursive solution:
import scala.annotation.tailrec
def printStars(i: Int): Unit = {
#tailrec
def loop(j: Int): Unit = {
if(j > 0) {
val stars = Range(0, j).map(_ => "*").mkString(" ") // make stars
if(i == j) println(stars) // no need for spaces
else println((" " * (i - j)) + stars) // spaces before the stars
loop(j - 1)
}
}
loop(i)
}
printStars(3)
// * * *
// * *
// *
This function will take a maximum triangle size (i), and for that size until i is no longer greater than 0 it will print out the correct number of stars (and spaces), then decrement by 1.
Note: Range(0, j).map(_ => "*").mkString(" ") can be replaced with List.tabulate(j)(_ => "*").mkString(" ") per Luis's answer - I'm not sure which is faster (I've not tested it).

Access RDD elements by index

I have an RDD as below and would like to access the elements within each row by its index number in a loop. Is this possible?
(98,(344,(Dead Man Walking (1995),0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0)))
(50,(501,(Richard III (1995),0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1)))
(1,(321,(Toy Story (1995),0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0)))
So far, I have come up with the below code
val combgenr = mvnmcnt.map(x => (x._2._2.productIterator.foreach{
var n = 4
i => (
if (i == "1") {println((x._1.toInt,x._2._1.toInt,x._2._2._1),n)
})
n += 1
}))
But the I get an extra line in my result(below), the reason for which I don't know.
((98,344,Dead Man Walking (1995)),13)
()
((50,501,Richard III (1995)),13)
((50,501,Richard III (1995)),22)
((50,501,Richard III (1995)),23)
()
((1,321,Toy Story (1995)),8)
((1,321,Toy Story (1995)),9)
((1,321,Toy Story (1995)),10)
()
Any ideas?

Functional version of a typical nested while loop

I hope this question may please functional programming lovers. Could I ask for a way to translate the following fragment of code to a pure functional implementation in Scala with good balance between readability and execution speed?
Description: for each elements in a sequence, produce a sub-sequence contains the elements that comes after the current elements (including itself) with a distance smaller than a given threshold. Once the threshold is crossed, it is not necessary to process the remaining elements
def getGroupsOfElements(input : Seq[Element]) : Seq[Seq[Element]] = {
val maxDistance = 10 // put any number you may
var outerSequence = Seq.empty[Seq[Element]]
for (index <- 0 until input.length) {
var anotherIndex = index + 1
var distance = input(index) - input(anotherIndex) // let assume a separate function for computing the distance
var innerSequence = Seq(input(index))
while (distance < maxDistance && anotherIndex < (input.length - 1)) {
innerSequence = innerSequence ++ Seq(input(anotherIndex))
anotherIndex = anotherIndex + 1
distance = input(index) - input(anotherIndex)
}
outerSequence = outerSequence ++ Seq(innerSequence)
}
outerSequence
}
You know, this would be a ton easier if you added a description of what you're trying to accomplish along with the code.
Anyway, here's something that might get close to what you want.
def getGroupsOfElements(input: Seq[Element]): Seq[Seq[Element]] =
input.tails.map(x => x.takeWhile(y => distance(x.head,y) < maxDistance)).toSeq

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.