Papyrus - OCL constraint to verified property - constraints

My class has 2 properties (String) that are two types of people's document numbers. To verify if the documents has valid numbers, a calculation is realized (verifiers digits). Below an example how is realized a consistensy of one of them:
Number: 973.345.650-02 (The punctuations must be ignored)
FIRST VERIFIER DIGIT CALCULATION
9 * 10 = 90
7 * 9 = 63
3 * 8 = 24
3 * 7 = 21
4 * 6 = 24
5 * 5 = 25
6 * 4 = 24
5 * 3 = 15
0 * 2 = 0
----------
Sum = 286
286 % 11 = 0
If rest < 2 then first digit = 0
Or if rest >= 2 then first digit = 11 - rest
In this case, rest < 2 (0), then first verifier digit = 0
SECOND VERIFIER DIGIT CALCULATION
9 * 11 = 99
7 * 10 = 70
3 * 9 = 27
3 * 8 = 24
4 * 7 = 28
5 * 6 = 30
6 * 5 = 30
5 * 4 = 20
0 * 3 = 0
0 * 2 = 0 ==> FIRST VERIFIER DIGIT
----------
Sum = 328
328 % 11 = 9
Same rule of first verifier digit
If rest < 2 then first digit = 0
Or if rest >= 2 then first digit = 11 - rest
The rest is greater than 2 (9), then second verifiter digit = 11 - 9 ==> 2
JAVA METHOD
public static boolean isValidCPF(String cpf) {
cpf = cpf.replaceAll("[./-]", "");
if (cpf.length() < 11) {
return false;
}
int equalDigits = 0;
char compareChar = cpf.charAt(0);
for (int i = 1; i <= 9; i++) {
if (compareChar == cpf.charAt(i)) {
equalDigits++;
} else {
break;
}
}
if (equalDigits == 9) {
return false;
}
int[] digit = new int[2];
int sum = 0, multiply = 2;
for (int k = 8; k <= 9; k++) {
for (int i = k; i >= 0; i--) {
sum += Character.getNumericValue(cpf.charAt(i)) * multiply++ ;
}
digit[k-8] = (sum % 11) < 2 ? 0 : 11 - (sum % 11);
sum = 0;
multiply = 2;
}
if (cpf.equals(cpf.substring(0 , 9) + digit[0] + digit[1])) {
return true;
}
return false;
}
I guess that OCL "sequence" must be used in this case (loop through digits) converting each one to Integer for calculation and using "body" in constraint, but I don't know how.
I want to apply the contraint to UML model in Papyrus (that's I know how to do).
Thanks in advance.

You must think declaratively in aggregates so to emulate
for (int i = 1; i <= 9; i++) {
if (compareChar == cpf.charAt(i)) {
equalDigits++;
} else {
break;
}
}
you might try something like
Sequence{2..10}->select(i | cpf->at(i) = compareChar)->size()
NB OCL indexes start at 1.

Related

Arduino memcpy distorts serial output

I am writing some code for an Arduino Uno that involves copying parts of arrays. The use of memcpy causes an entirely unrelated variable to occasionally appear corrupted in the serial output. Here is the code necessary to show the issue.
byte cchar[8][8];
byte fbold[16][16];
void setup() {
Serial.begin(9600);
}
void loop() {
for (byte i = 0; i < 8; i++) {
memcpy(cchar + i*8, fbold + 16 * i , 8);
Serial.println(i);
Serial.println(i);
}
delay(500);
}
I believe that this should output the following on repeat:
1
1
2
2
3
3
4
4
5
5
6
6
7
7
but oddly, it is more like this: (taken directly from serial monitor)
0
0
1
1
2
2ff
4
5
4
4
5
5
6
6
7
7
0
0
1
1
2
2
3
3
4
4
5
5ff
7
07
7
With the memcpy command removed, it outputs as I would expect.
The logical conclusion would be that my memcpy is corrupting i.
But why though? i is supposedly never more than 7, cchar is 64 bytes long, and I'm only copying 8 bytes, right? So how would I be copying outside of cchar?
the problems is pointer arithmetic. sizeof(*cchar) is 8 so address of cchar + 1 is 8 bytes after address of cchar
this works
byte cchar[8][8];
byte fbold[16][16];
void setup() {
Serial.begin(115200);
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
fbold[i][j] = j;
}
}
for (int i = 0; i < 8; i++) {
memcpy(cchar + i, fbold + i, 8);
for (int j = 0; j < 8; j++) {
Serial.print(cchar[i][j]);
Serial.print(',');
}
Serial.println();
}
}
void loop() {
}

Generate list of strings

Here's what is inside my CSV file
Symbol
0 AACAF
1 AACAY
2 AACTF
3 AAGC
4 AAGIY
5 AAIGF
6 AAMAF
7 AAPH
8 AAPT
9 AAST
10 AATDF
11 AATGF
12 AATRL
13 AAUKF
14 AAWC
15 ABBY
16 ABCAF
17 ABCCF
18 ABCE
19 ABCFF
20 ABCZF
21 ABCZY
22 ABEPF
23 ABHD
24 ABHI
25 ABLT
26 ABLYF
27 ABNAF
28 ABNK
29 ABNRY
I would like to build a function which could create strings by batch of three symbols, e.g.
'AACAF,AACAY,AACTF'
'AAGC,AAGIY,AAIGF'
'AAMAF,AAPH,AAPT'
'AAST,AATDF,AATGF'
'AATRL,AAUKF,AAWC'
'AABY,ABCAF,ABCCF'
'ABCE,ABCFF,ABCZF'
'ABCZY,ABEPF,ABHD'
'ABHI,ABLT,ABLYF'
'ABNAF,ABNK,ABNRY'
I started what I want in using python, but I don't know how to complete it. I think I could use the csv module to do that.
with open(path, 'r') as csvfile:
rows=[row for row in csvfile]
batch_size = 100
listing = []
string = ''
count = 0
for index, row in enumerate(rows):
if count >= batch_size:
listing.append(string)
string = ''
count = 0
','.join((string,row))
count += 1
How could I do that with python 3.6?
arr = pandas.read_csv(path).Symbol.values
symbol_groups = numpy.split(arr, len(arr) // 3)
result = [','.join(symbols) for symbols in symbol_groups]
Should be doing what you're looking for.
with open(path, 'r') as csvfile:
rows=[row.strip('\n') for row in csvfile]
batch_size = 100
listing = []
string = ''
count = 0
for index, row in enumerate(rows[1:]):
if count >= batch_size or index == len(rows[1:])-1:
listing.append(string)
string = ''
count = 0
if count == 0:
string = ''.join((string,row))
else:
string = ','.join((string,row))
count += 1

Standard Positional to Bijective Base Conversion

We know that a b-based standard positional number system uses digits,
0, 1, 2, ..., b-1. But a bijective number system uses digits, 1, 2, ..., b. So a 4-based standard number system sequence looks like,
0
1
2
3
10
11
12
13
20
21
22
23
30
31
32
33 (base-4, 16th number standard)
100 (base-4, 17th number standard)
101
.
.
.
On the other hand bijective number system for 4-based looks like,
λ (base-4, 1st number, empty-string)
1
2
3
4
11
12
13
14
21
22
23
24
31
32
33 (base-4, 16th number bijective)
34 (base-4, 17th number bijective)
41
.
.
.
Example:
34152 (in bijective base-5) = 3×54 + 4×53 + 1×52 + 5×51 + 2×1 = 2427 (in decimal).
119A (in bijective base-10, with "A" representing the digit value ten) = 1×103 + 1×102 + 9×101 + 10×1 = 1200 (in decimal).
I wonder if there is any easy way to find n'th position bijective value in same base.
For example,
lets say in base-4 5th positional value = 10 (standard) but 5th positional value = 11 (bijective). Any pseudocode is ok to understand the concept.
If a number in the standard base-n system contains no zeros, the number has the same representation as bijective base-n.
So you need to look for zeros in the standard number. When you find a zero, replace it with the maximum symbol in the bijective and decrement the element to the left.
Simple example:
10 decimal -> A bijective because 0 becomes A and 1 decrements to zero
20 decimal -> 1A bijective because 0 becomes A and 2 decrements to 1
As a special case you must handle sequences of zero.
Simple example:
200 decimal -> 19A bijective (i.e. step 1: 1A0 step 2: 19A)
You can also look at it like this
200 decimal is constructed as 2*100 + 0*10 + 0*1 = 200 decimal
For bijective you can't have zero so you'll do:
19A bijective is constructed as 1*100 + 9*10 + 10*1 = 200 decimal
To finish a bit more complex example:
110 decimal -> AA bijective (i.e. step 1: 10A step 2: AA)
This routine implements the conversion. (Which resolved to #4386427's method.) If you want the other version, where 100 (base 4 std) -> 41 (base 4 bij') then compile with -D NO_EMPTY_STRING
#include <stdio.h>
#include <string.h>
void print_be_digits(const char *prefix, const unsigned char *le_num, size_t len)
{
size_t i;
printf("%s", prefix);
for(i=0; i<len; i++)
{
printf("%d ", (int)le_num[len-i-1]);
}
printf("\n");
}
void nth_bij(int n, int k)
{
ssize_t i;
size_t std_len;
size_t bij_len;
size_t work;
unsigned char le_std_digits[256];
unsigned char le_bij_digits[256];
//convert to standard radix-k digits
work = n;
for(std_len = 0; work; std_len++)
{
le_std_digits[std_len] = work % k;
work /= k;
}
print_be_digits(" std: ", le_std_digits, std_len);
//convert standard to bij
memcpy(le_bij_digits, le_std_digits, std_len);
bij_len = std_len;
#ifdef NO_EMPTY_STRING
// Step 1: increment LSd
le_bij_digits[0]++;
#endif
// Step 2: borrow on zeros
// scan back from the end
for(i=bij_len-1; i>= 0; i--)
{
//if we find a zero, borrow, and ripple toward MSd as necessary
if(le_bij_digits[i] == 0)
{
size_t j;
//Ripple borrow toward MSd, as necessary
for(j=i+1; j<bij_len; j++)
{
le_bij_digits[j-1] = k; //k is the radix
if(--le_bij_digits[j])
{
break;
}
}//end ripple
//adjust bij_len if we rippled to the end
if(j == bij_len)
{
bij_len--;
}
}
}//end scan
print_be_digits(" bij: ", le_bij_digits, bij_len);
}
Simple driver:
int main(int argc, char *argv[])
{
printf("Test: 16 decimal (->base 4): \n");
nth_bij(16,4);
printf("\n");
printf("Test: 8 decimal (->base 2): \n");
nth_bij(8,2);
printf("\n");
printf("Test: 13 decimal (->base 2): \n");
nth_bij(13,2);
printf("\n");
printf("Test: 2427 decimal (->base 5): \n");
nth_bij(2427, 5);
printf("\n");
printf("Test: 1200 decimal (->base 10): \n");
nth_bij(1200, 10);
printf("\n");
}
Compiling for my version:
$ gcc -D NO_EMPTY_STRING bij.c
$ ./a.exe
Test: 16 decimal (->base 4):
std: 1 0 0
bij: 4 1
Test: 8 decimal (->base 2):
std: 1 0 0 0
bij: 1 2 1
Test: 13 decimal (->base 2):
std: 1 1 0 1
bij: 2 2 2
Test: 2427 decimal (->base 5):
std: 3 4 2 0 2
bij: 3 4 1 5 3
Test: 1200 decimal (->base 10):
std: 1 2 0 0
bij: 1 1 10 1
Compiling for #4386427's version:
$ gcc bij.c
$ ./a.exe
Test: 16 decimal (->base 4):
std: 1 0 0
bij: 3 4
Test: 8 decimal (->base 2):
std: 1 0 0 0
bij: 1 1 2
Test: 13 decimal (->base 2):
std: 1 1 0 1
bij: 2 2 1
Test: 2427 decimal (->base 5):
std: 3 4 2 0 2
bij: 3 4 1 5 2
Test: 1200 decimal (->base 10):
std: 1 2 0 0
bij: 1 1 9 10

Why dfs using stack is not giving correct result

See DFS image Here
I am using stack to print sequence of dfs. According to input and that image of graph, sequence is 1 2 4 8 5 6 3 7 . But My code is giving output as 1 2 4 8 7 6 5 3 . Can anyone explain how can i fix it??
Input:
8 10
1 3
1 2
2 5
2 4
3 7
3 6
4 8
5 8
6 8
7 8
Correct Output:
Sequence: 1 2 4 8 5 6 3 7
My Code :
#include <bits/stdc++.h>
using namespace std;
vector<int>edges[100];
stack<int>q;
vector<int>item;
int level[100],parent[100],visited[100],tn;
void dfs(int s)
{
int j,k,fr;
q.push(s);
level[s]=0;
for(j=1;j<=tn;j++)
{
visited[j]=0;
}
visited[s]=1;
while(!q.empty())
{
fr=q.top();
q.pop();
item.push_back(fr);
for(k=0;k<edges[fr].size();k++)
{
if(visited[edges[fr][k]]==0)
{
q.push(edges[fr][k]);
//cout<<"Pushed="<<fr<<"="<<edges[fr][k];
visited[edges[fr][k]]=1;
}
}
//cout<<endl;
}
}
int main()
{
int i,e,p,n,u,v,f,m;
cin>>tn>>e;
for(i=1;i<=e;i++)
{
cin>>u>>v;
edges[u].push_back(v);
edges[v].push_back(u);
}
dfs(1);
cout<<"Sequence="<<endl;
for(m=0;m<item.size();m++)
{
cout<<item[m];
}
return 0;
}
My Code is showing this output: 1 2 4 8 7 6 5 3
The marking of the nodes as visited in the implementation contains a bug; the function can be rewritten as follows.
void dfs(int s)
{
int j, k, fr;
q.push(s);
level[s] = 0;
for (j = 1; j <= tn; j++)
{
visited[j] = 0;
}
while (!q.empty())
{
fr = q.top();
q.pop();
if (0 == visited[fr])
{
visited[fr] = 1;
item.push_back(fr);
for (k = 0; k < edges[fr].size(); k++)
{
q.push(edges[fr][k]);
}
}
}
}
In this version, a node gets marked only if it is taken from the stack. Note that a check whether the node has been already visited is necessary, as a node on the stack might be visited by a later iteration. This implementation yields the sequence
1 2 4 8 7 3 6 5
which, however, is not the one described as desired solution. However, note that without additional tie-breaking rules, the DFS algorithm permits some ambiguity in the sequence of visits. The sequence
1 2 4 8 5 6 3 7
can be generated by pushing a neighbor with smallest id to the stack last, causing it to be visited in the next iteration.

Number of divisiors upto 10^6

I have been trying to solve this problem.
http://www.spoj.com/problems/DIV/
for calcuating interger factors, I tried two ways
first: normal sqrt(i) iteration.
int divCount = 2;
for (int j = 2; j * j <= i ; ++j) {
if( i % j == 0) {
if( i / j == j )
divCount += 1;
else
divCount += 2;
}
}
second: Using prime factorization (primes - sieve)
for(int j = 0; copy != 1; ++j){
int count = 0;
while(copy % primes.get(j) == 0){
copy /= primes.get(j);
++count;
}
divCount *= ( count + 1);}
While the output is correct, I am getting TLE. Any more optimization can be done? Please help. Thanks
You're solving the problem from the wrong end. For any number
X = p1^a1 * p2^a2 * ... * pn^an // p1..pn are prime
d(X) = (a1 + 1)*(a2 + 1)* ... *(an + 1)
For instance
50 = 4 * 25 = 2^2 * 5^2
d(50) = (1 + 2) * (1 + 2) = 9
99 = 3^2 * 11^1
d(99) = (2 + 1) * (1 + 1) = 6
So far so good you need to generate all the numbers such that
X = p1^a1 * p2^a2 <= 1e6
such that
(a1 + 1) is prime
(a2 + 1) is prime
having a table of prime numbers from 1 to 1e6 it's a milliseconds task
It is possible to solve this problem without doing any factoring. All you need is a sieve.
Instead of a traditional Sieve of Eratosthenes that consists of bits (representing either prime or composite) arrange your sieve so each element of the array is a pointer to an initially-null list of factors. Then visit each element of the array, as you would with the Sieve of Eratosthenes. If the element is a non-null list, it is composite, so skip it. Otherwise, for each element and for each of its powers less than the limit, add the element to each multiple of the power. At the end of this process you will have a list of prime factors of the number. That wasn't very clear, so let me give an example for the numbers up to 20. Here's the array, initially empty:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Now we sieve by 2, adding 2 to each of its multiples:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2 2 2 2 2 2 2 2 2 2
Since we also sieve by powers, we add 2 to each multiple of 4:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2
And likewise, by each multiple of 8 and 16:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2
2 2
2
Now we're finished with 2, so we go to the next number, 3. The entry for 3 is null, so we sieve by 3 and its power 9:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2
2 2
2
3 3 3 3 3 3
3 3
Then we sieve by 5, 7, 11, 13, 17 and 19:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2
2 2
2
3 3 3 3 3 3
3 3
5 5 5 5
7 7
11
13
17
19
Now we have a list of all the prime factors of all the numbers less than the limit, computed by sieving rather than factoring. It's easy then to calculate the number of divisors by scanning the lists; count the number of occurrences of each factor in the list, add 1 to each total, and multiply the results. For instance, 12 has 2 factors of 2 and 1 factor of 3, so take (2+1) * (1+1) = 3 * 2 = 6, and indeed 12 has 6 factors: 1, 2, 3, 4, 6 and 12.
The final step is to check if the number of divisors has exactly two factors. That's easy: just look at the list of prime divisors and count them.
Thus, you have solved the problem without doing any factoring. That ought to be very fast, just a little bit slower than a traditional Sieve of Eratosthenes and very much faster than factoring each number to compute the number of divisors.
The only potential problem is space consumption for the lists of prime factors. But you shouldn't worry too much about that; the largest list will have only 19 factors (since the smallest factor is 2, and 2^20 is greater than your limit), and 78498 of the lists will have only a single factor (the primes less than a million).
Even though the above mentioned problem doesn't require calculating number of divisors, It still can be solved by calculating d(N) (divisors of N) within the time limit (0.07s).
The idea is to pretty simple. Keep track of smallest prime factor f(N) of every number. This can be done by standard prime sieve. Now, for every number i keep dividing it by f(i) and increment the count till i = 1. You now have set of prime counts for each number i.
int d[MAX], f[MAX];
void sieve() {
for (int i = 2; i < MAX; i++) {
if (!f[i]) {
f[i] = i;
for (int j = i * 2; j < MAX; j += i) {
if (!f[j]) f[j] = i;
}
}
d[i] = 1;
}
for (int i = 1; i < MAX; i++) {
int k = i;
while (k != 1) {
int s = 0, fk = f[k];
while (k % fk == 0) {
k /= fk; s++;
}
d[i] *= (s + 1);
}
}
}
Once, d(N) is figured out, rest of the problem becomes much simpler. Keeping a smallest prime factor of every number also helps to solve lots of other problems.

Resources