I'm having a great deal of difficulty translating the following for loop into Swft
for (int i = 0; i * denomAmount <= amount; i++ {
}
my attempt is
for i in stride(from: 0, to: amount, by: denom){
}
but obviously it amount is not the maximum value of i. So what is the best way to approach this?
Most likely either demonAmount or amount is being updated inside the loop. So I would use a while loop:
var i = 0
while i * demonAmount <= amount {
// the loop code
i += 1
}
Related
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)
Today, when trying quicksort, instead of taking last element as pivot and partitioning,i took the first element as pivot, But it is not producing the correct partitioned output.
int pivot = ar[0];
int pindex = 0;
for(int i = 0;i < ar.size();i++)
{
if(ar[i] <= pivot)
{
swap(ar[i],ar[pindex]);
pindex++;
}
}
swap(ar[pindex],ar[ar.size()-1]);
I could not understand why, i always use this for partition, but this is not working when i take first element as partition.
But this worked even if i took first element as partition
int i, j, pivot, temp;
pivot = ar[0];
i = 0;
j = ar.size()-1;
while(1)
{
while(ar[i] < pivot && ar[i] != pivot)
i++;
while(ar[j] > pivot && ar[j] != pivot)
j--;
if(i < j)
{
temp = ar[i];
ar[i] = ar[j];
ar[j] = temp;
}
else
{
break;
}
}
What are the differences between them.
At last found that, this method is Hoare's partition method, where as the typical quick sort method we all follow is lomuto's partition.
See this wiki page, it has all details https://en.wikipedia.org/wiki/Quicksort
I'm back again with what is likely a simple issue, however its got me stumped.
I've written very small, very basic piece of code in an xcode playground.
My code simply iterates over a function 10 times, printing the output each time.
var start = 0
var x = 0
var answer = 2 * x
func spin() {
print(answer)
}
while start < 10 {
spin()
x++
start++
}
Now for my issue, It seems my code properly increments the 'start' variable.... running and printing 10 times. However it prints out a list of 0's. For some reason the 'x' variable isn't incrementing.
I've consulted the few ebooks I have for swift, aswell as the documentation, and as far as i can see my code should work.
Any ideas?
P.s. As per the documentation I have also tried ++x, to no avail.
edit
Updated, working code thanks to answers below:
var start = 0
var x = 0
var answer = 2 * x
func spin() {
print("The variable is", x, "and doubled it is", answer)
}
while start <= 10 {
spin()
x++
start++
answer = 2 * x
}
You have just assigned 2 * x to answer at the beginning of the program, when x == 0, and the value of answer remains its initial value through out the program. That's how Value Types work in Swift as well as in almost any other languages
If you wish to always have answer to be 2 times of x, you should write like this
var start = 0
var x = 0
var answer = 2 * x
func spin() {
print(answer)
}
while start < 10 {
spin()
x++
start++
answer = 2 * x
}
And thanks to Leo Dabus's answer, you may also define a Computed Property to caculate the value of 2 * x each time you try to get the value of answer. In this way, answer becomes readonly and you cannot assign other values to it. And each time you try to get the value of answer, it performs the 2 * x calculation.
var start = 0
var x = 0
var answer: Int {
return 2 * x
}
func spin() {
print(answer)
}
while start < 10 {
spin()
x++
start++
}
What you need is a read only computed property. Try like this:
var answer: Int { return 2 * x }
I have followed the tutorial:
www.edumobile.org/iphone/iphone-programming-tutorials/a-simple-stopwatch-for-iphone
and I get 1 error and 1 warning, both on the same line 71
for (int i = [timeArray count] – 1; i >= 0; i–) {
error – a parse issue Expected )
warning – Unused entity issue Expression result unused
Any ideas what is wrong?
Change this,
for (int i = [timeArray count] – 1; i >= 0; i–) {
to,
for (int i = [timeArray count] – 1; i >= 0; i--) {
Compiler is saying that it is not able to parse the character '–'. If it is not able to recognize the for loop syntax and parse it, it will throw this error.
As ACB mentioned, the expression needs to be i-- instead of i-.
Just a couple of notes - Douglas Crawford actually recommends to avoid using -- and ++ in favor of doing i -= 1. While a smidgen verbose, there is no room for doubt over what it actually does versus something like
int example = --i + b;
may confuse some to the value of i after the end of the expression.
Also, as a minor optimization, you should put the size of the array in a local value as opposed to calling [timeArray count] every loop iteration
int timeArraySize = [timeArray count] - 1;
for (int i = timeArraySize; i >= 0; i -= 1) {
Hope that helps!
I have this code:
count = $content.find('.post').length;
for x in [1...count]
/*
prev_el_height += $("#content .post:nth-child(" + x + ")").height();
*/
prev_el_height += $content.find(".post:nth-child(" + x + ")").height();
I expected this to turn into
for (x = 1; x < count; x++) { prev_el ... }
but it turns into this:
for (x = 1; 1 <= count ? x < count : x > count; 1 <= count ? x++ : x--) {
Can somebody please explain why?
EDIT: How do I get my expected syntax to output?
In CoffeeScript, you need to use the by keyword to specify the step of a loop. In your case:
for x in [1...count] by 1
...
You're asking to loop from 1 to count, but you're assuming that count will always be greater-than-or-equal-to one; the generated code doesn't make that assumption.
So if count is >= 1 then the loop counter is incremented each time:
for (x = 1; x < count; x++) { /* ... */ }
But if count is < 1 then the loop counter is decremented each time:
for (x = 1; x > count; x--) { /* ... */ }
Well, you want x to go from 1 to count. The code is checking whether count is bigger or smaller than 1.
If count is bigger than 1, then it has to increment x while it is smaller than count.
If count is smaller than 1, then it has to decrement x while it is bigger than count.
For future reference:
$('#content .post').each ->
prev_el_height += $(this).height()
Has the same effect, assuming :nth-child is equivalent to .eq(), and x going past the number the elements is a typo.