coffeescript prime number generation - coffeescript

I am trying to generate prime numbers like this:
generatePrimeNumbersBelowN = (n) ->
for i in [2..n-1]
isPrime = true
for j in [2..i-1]
isPrime = false if i % j == 0
break if not isPrime
console.log(i, "is Prime Number.") if isPrime
generatePrimeNumbersBelowN(100);
I am getting prime numbers from 3 to 97, inclusive. I am new to JavaScript/CoffeeScript, so please tell me what's happening to 2?
Here's the generated JS code:
var generatePrimeNumbersBelowN;
generatePrimeNumbersBelowN = function(n) {
var i, isPrime, j, k, l, ref, ref1, results;
results = [];
for (i = k = 2, ref = n - 1; 2 <= ref ? k <= ref : k >= ref; i = 2 <= ref ? ++k : --k) {
isPrime = true;
for (j = l = 2, ref1 = i - 1; 2 <= ref1 ? l <= ref1 : l >= ref1; j = 2 <= ref1 ? ++l : --l) {
if (i % j === 0) {
isPrime = false;
}
if (!isPrime) {
break;
}
}
if (isPrime) {
results.push(console.log(i, "is Prime Number."));
} else {
results.push(void 0);
}
}
return results;
};
generatePrimeNumbersBelowN(100);

generatePrimeNumbersBelowN = (n) ->
for i in [2..n-1]
isPrime = true
for j in [2..i-1]
isPrime = false if i % j == 0
break if not isPrime
console.log(i, "is Prime Number.") if isPrime
When i is 2, j ranges from 2 down to 1. You then check i % j which is 2 % 1 which is zero and claim that 2 is not a prime.
Because for x in [b..a] delivers a downward loop from b to a, while loop construct solves this problem.
generatePrimeNumbersBelowN = (n) ->
i = 2
while i < n
isPrime = true
j = 2
while j < i
isPrime = false if i % j == 0
break if not isPrime
j++
console.log(i, "is Prime Number.") if isPrime
i++
generatePrimeNumbersBelowN(100);

Related

how to make K different elements in bool array with or-tools?

I want make K different elements in bool array,I use code: model.Add(len(set([shifts[(i)] for i in range(10)]))==4) ,but it not work! How can I do this?
model = cp_model.CpModel()
solver = cp_model.CpSolver()
shifts = {}
ones = [model.NewBoolVar("") for _ in range(10)]
for i in range(10):
shifts[(i)] = model.NewIntVar(0, 10, "shifts(%i)" % i)
for i in range(10):
model.Add(shifts[(i)] >0).OnlyEnforceIf(ones[(i)])
model.Add(shifts[(i)] == 0).OnlyEnforceIf(ones[(i)].Not())
model.Add(sum(ones[(i)] for i in range(10)) == 5)
# I want make 4 different but it not work!
#model.Add(len(set([shifts[(i)] for i in range(10)]))==4)
status = solver.Solve(model)
print("status:",status)
res=[]
for i in range(10):
res.append(solver.Value(shifts[(i)]))
print(res)
Encode your integers using booleans and add another boolean for each value to mark it as used
from ortools.sat.python import cp_model
model = cp_model.CpModel()
solver = cp_model.CpSolver()
shifts = {}
used = [model.NewBoolVar("") for j in range(10)]
for i in range(10):
for j in range(10):
shifts[i, j] = model.NewBoolVar(f"shifts({i}, {j})")
# shifts[i,j] => used[j]
model.AddImplication(shifts[i, j], used[j])
model.Add(sum(shifts[i, j] for j in range(10)) == 1)
model.Add(sum(shifts[i, 0].Not() for i in range(10)) == 5)
for j in range(10):
# all(shifts[_, j] == 0) => used[j].Not()
model.AddBoolOr([shifts[i, j] for i in range(10)] + [used[j].Not()])
model.Add(sum(used) == 4)
status = solver.Solve(model)
print("status:", status)
res = []
for i in range(10):
for j in range(10):
if solver.Value(shifts[i, j]):
res.append(j)
print(res)

Converting a roman numeral to integer

For a computer science assignment my goal is to convert a character string (the roman numeral) to an integer. I'm to write a function to do this in Matlab. My code to do this is shown below.
function [x] = roman2decimal(s)
s1 = substr1(s,1);
s2 = substr2(s,2,2);
s = substr2(s, 3, numel(s));
sum = 0;
if (s1~='')
%Case I - if any of these conditions are true
if (s1=='C' && s2=='M')
sum = sum + 900;
end
if (s1=='C' && s2=='D')
sum = sum + 400;
end
if (s1=='X' && s2=='C')
sum = sum + 90;
end
if (s1=='X' && s2=='L')
sum = sum + 40;
end
if (s1=='I' && s2=='X')
sum = sum + 9;
end
if (s1=='I' && s2=='V')
sum = sum + 4;
end
s=s1
s2=substr2(s, 3, numel(s))
end
% case 2 - no case 1 conditions were true
if(s1=='M')
sum = sum + 1000;
end
if(s1=='D')
sum = sum + 500;
end
if(s1=='C')
sum = sum + 100;
end
if(s1=='L')
sum = sum + 50;
end
if(s1=='X')
sum = sum + 10;
end
if(s1=='V')
sum = sum + 5;
end
if(s1=='I')
sum = sum + 1;
end
s1=s2
s=s2
sum
end
function [c]=substr1(s,pos)
if(pos >= 1 && numel(s) >= pos) c=s(pos);
else c='';
end
end % substr1
function [c]=substr2(s,pos1,pos2)
if(pos1 >=1 && pos2 >= pos1 && pos2 <= numel(s)) c=s(pos1:pos2);
else c='';
end
end % substr2
The issue I'm having is that when I call the function for a character string that's more than 2 characters long, s1 always computes to the second character in the string, e.g. for 'CM' s1=M, s2=M.
If I call the substr1 function outside of this function, it works fine (e.g. returns the first character in the string).
I was wondering if there was something wrong with my algorithm/syntax and if you could help?
Much appreciated.
Here is an answer inspired by #Robert, yet quite different:
myStr = 'MCMLXXXVIII';
key = 'MDCLXVI';
values = [1000, 500,100,50,10,5,1];
% Calculate the 'weight' of each letter
[~, loc]=ismember(myStr,key)
relevantValues = values(loc);
% Determine whether we should substract or add
s = [-sign(diff(relevantValues)), 1];
%% To avoid zeros in s
while ~all(s)
f = find(s == 0);
s(f) = s(f+1);
end
s*relevantValues'
This vectorized approach minimizes the amount of string operations and avoids eval statements.
This solution is in C and has passed all the 3999 test cases in LeetCode
int romanToInt(char* s) {
int i = 0, value = 0;
for (int i =0; s[i] != '\0'; i++)
{
switch(s[i]) {
case 'I':
if(s[i+1] != '\0' ){
if(s[i+1] == 'V' ||s[i+1] == 'X' )
value = value -1;
else
value = value+1;
}else {
value = value+1;
}
break;
case 'V':
value = value + 5;
break;
case 'X':
if(s[i+1] != '\0' ){
if(s[i+1] == 'L' ||s[i+1] == 'C' )
value = value -10;
else
value = value+10;
}else {
value = value+10;
}
break;
case 'L':
value = value + 50;
break;
case 'C':
if(s[i+1] != '\0' ){
if(s[i+1] == 'D' ||s[i+1] == 'M' )
value = value -100;
else
value = value+100;
}else {
value = value+100;
}
break;
case 'D':
value = value + 500;
break;
case 'M':
value = value + 1000;
break;
}
}
return value;
}

Filter points using hist in matlab

I have a vector. I want to remove outliers. I got bin and no of values in that bin. I want to remove all points based on the number of elements in each bin.
Data:
d1 =[
360.471912914169
505.084636471948
514.39429429184
505.285068055647
536.321181755858
503.025854206322
534.304229816684
393.387035881967
396.497969729985
520.592172434431
421.284713703215
420.401106087984
537.05330275495
396.715779872694
514.39429429184
404.442344469518
476.846474245118
599.020867750031
429.163139144079
514.941744277933
445.426761656729
531.013596812737
374.977332648255
364.660115724218
538.306752697753
519.042387479096
1412.54699036882
405.571202133485
516.606049132218
2289.49623498271
378.228766753667
504.730621222846
358.715764917016
462.339366699398
512.429858614816
394.778786157514
366
498.760463549388
366.552861126468
355.37022947906
358.308526273099
376.745272034036
366.934599077274
536.0901883079
483.01740134285
508.975480745389
365.629593988233
536.368800360349
557.024236456548
366.776498701866
501.007025898839
330.686029339009
508.395475983019
429.563732174866
2224.68806802212
534.655786464525
518.711297351426
534.304229816684
514.941744277933
420.32368479542
367.129404978681
525.626188464768
388.329756778952
1251.30895065927
525.626188464768
412.313764019587
513.697381733643
506.675438520558
1517.71183364959
550.276294237722
543.359917550053
500.639590923451
395.129864728041];
Histogram computation:
[nelements,centers] = hist(d1);
nelements=55 13 0 0 1 1 1 0 0 2
I want to remove all points apearing less than 5 (in nelements). It means only first 2 elements in nelements( 55, 13 ) remains.
Is there any function in matlab.
You can do it along these lines:
threshold = 5;
bin_halfwidth = (centers(2)-centers(1))/2;
keep = ~any(abs(bsxfun(#minus, d1, centers(nelements<threshold))) < bin_halfwidth , 2);
d1_keep = d1(keep);
Does this do what you want?
binwidth = centers(2)-centers(1);
centersOfRemainingBins = centers(nelements>5);
remainingvals = false(length(d1),1);
for ii = 1:length(centersOfRemainingBins )
remainingvals = remainingvals | (d1>centersOfRemainingBins (ii)-binwidth/2 & d1<centersOfRemainingBins (ii)+binwidth/2);
end
d_out = d1(remainingvals);
I don't know Matlab function for this problem, but I think, that function with follow code is what are you looking for:
sizeData = size(data);
function filter_hist = filter_hist(data, binCountRemove)
if or(max(sizeData) == 0, binCountRemove < 1)
disp('Error input!');
filter_hist = [];
return;
end
[n, c] = hist(data);
sizeN = size(n);
intervalSize = c(2) - c(1);
if sizeData(1) > sizeData(2)
temp = transpose(data);
else
temp = data;
end
for i = 1:1:max(sizeN)
if n(i) < binCountRemove
a = c(i) - intervalSize / 2;
b = c(i) + intervalSize / 2;
sizeTemp = size(temp);
removeInds = [];
k = 0;
for j = 1:1:max(sizeTemp)
if and(temp(j) > a, less_equal(temp(j), b) == 1)
k = k + 1;
removeInds(k) = j;
end
end
temp(removeInds) = [];
end
end
filter_hist = transpose(temp);
%Determines when 'a' less or equal to 'b' by accuracy
function less_equal = less_equal(a, b)
delta = 10^-6; %Accuracy
if a < b
less_equal = 1;
return;
end
if abs(b - a) < delta
less_equal = 1;
return;
end
less_equal = 0;
You can do something like this
nelements=nelements((nelements >5))

Solving 2 equations - 9 Unknowns, with constraints.

I'm trying to solve a riddle with the use of matlab.
This is realy more about matlab than the riddle itself (The riddle is taken from a daily newspaper).
The riddle gives two 3 digits numbers represented by letters. I need to find the digit (0-9) the doesn't participate.
aba-dcc=efe ; aba+dcc=ghi
Now, I have 2 equations with 9 unknowns.
I've managed to solve it by checking all permutations of the vector 0:9, in a while loop.
vecAns = 0:9;
P = perms(vecAns);
P = P(:,1:9);
A = [ 101 10 -100 -11 -101 -10 0 0 0 ;...
101 10 100 11 0 0 -100 -10 -1];
resVec = [0;0];
found=false;
i=1;
h = waitbar(0,'Computing');
while found==false
Res=A*P(i,:)';
if (Res(1)==0)&&(Res(2)==0)
break;
end
i=i+1;
waitbar(i/length(P),h,sprintf('%d%%',i/length(P)*100));
end
close(h)
Is there a way (without adding mathematical considerations) to solve the problem.
For example, I know that all the unknowns must be integers and within the range 0-9.
If there isn't a way. How can make it more efficient?
You don't have to enumerate all the permutations. You can start with the first 4 digits (a, b, c and d), and check if they produce a difference and sum that matches efe and ghi. You also need to make sure all the digits are distinct.
I'm not very proficient in writing matlab code, so I'll demonstrate it with C# code:
//aba-dcc=efe
//aba+dcc=ghi
for (int a = 1; a <= 9; a++) // 'a' cannot be zero
for (int b = 0; b <= 9; b++)
if (a != b)
for (int c = 0; c <= 9; c++)
if (c != a && c != b)
for (int d = 1; d <= 9; d++) // 'd' cannot be zero
if (d != a && d != b && d != c)
{
int aba = a*101 + b*10;
int dcc = c*11 + d*100;
int efe = aba - dcc;
if (efe < 0) continue;
int ghi = aba + dcc;
if (ghi > 999) continue;
int e = efe % 10;
if (e == a || e == b || e == c || e == d) continue;
int f = (efe/10)%10;
if (f == a || f == b || f == c || f == d || f == e) continue;
if (efe != e*101 + f*10) continue;
int i = ghi%10;
if (i == a || i == b || i == c || i == d || i == e || i == f) continue;
int h = (ghi/10)%10;
if (h == a || h == b || h == c || h == d || h == e || h == f || h == i) continue;
int g = (ghi/100)%10;
if (g == a || g == b || g == c || g == d || g == e || g == f || g == i || g == h) continue;
Console.WriteLine("{0:d3}-{1:d3}={2:d3} ; {0:d3}+{1:d3}={3:d3}", aba, dcc, efe, ghi);
}
This completes in less than a millisecond on my computer.
Output:
717-233=484 ; 717+233=950
(% is modulus, and / is integer division. continue skips to the next iteration of the loops.)

for loop with range in CoffeeScript

Noob question. I am trying to write a for loop with a range. For example, this is what I want to produce in JavaScript:
var i, a, j, b, len = arr.length;
for (i = 0; i < len - 1; i++) {
a = arr[i];
for (j = i + 1; i < len; j++) {
b = arr[j];
doSomething(a, b);
}
}
The closest I've come so far is the following, but
It generates unnecessary and expensive slice calls
accesses the array length inside the inner loop
CoffeeScript:
for a, i in a[0...a.length-1]
for b, j in a[i+1...a.length]
doSomething a, b
Generated code:
var a, b, i, j, _i, _j, _len, _len1, _ref, _ref1;
_ref = a.slice(0, a.length - 1);
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
a = _ref[i];
_ref1 = a.slice(i + 1, a.length);
for (j = _j = 0, _len1 = _ref1.length; _j < _len1; j = ++_j) {
b = _ref1[j];
doSomething(a, b);
}
}
(How) can this be expressed in CoffeeScript?
Basically, transcribing your first JS code to CS:
len = arr.length
for i in [0...len - 1] by 1
a = arr[i]
for j in [i + 1...len] by 1
b = arr[j]
doSomething a, b
Seems like the only way to avoid the extra variables is with a while loop http://js2.coffee
i = 0
len = arr.length
while i < len - 1
a = arr[i]
j = i + 1
while j < len
b = arr[j]
doSomething a, b
j++
i++
or a bit less readable:
i = 0; len = arr.length - 1
while i < len
a = arr[i++]; j = i
while j <= len
doSomething a, arr[j++]