Ada: Integer Overflow - overflow

so I am hashing and have defined these types/functions:
subtype string2 is String(1..2);
function cString2 is new Ada.Unchecked_Conversion(string2, long_integer);
function cChar is new Ada.Unchecked_Conversion(character, long_integer);
and MUST use this hash function:
HA = (((cString2(s1) + cString2(s2)) * 256) + cChar(char)) mod 128
(the function is bad on purpose, but I must implement it) The problem occurs when adding and/or trying to multiply 256 by the sum of the two long integers, for it overflows. I need to somehow treat the strings as POSITIVE integer values and also not have my function overflow. THANKS!!!

The type Long_Integer is a signed integer type, and guaranteed to cover the range –2**31+1 .. +2**31–1 (if it exists):
LRM 3.5.4(22):
If Long_Integer is predefined for an implementation, then its range shall include the range –2**31+1 .. +2**31–1.
With your declarations you are likely to include at least 2 bytes of random junk in your converted values, but as the sizes don't match, the result is implementation defined and possibly invalid or abnormal.
I suggest that you read up on the 'Pos attribute and Ada.Unchecked_Conversion in the LRM.

You can compare the quality of various Hash functions using the approach shown here, which tallies collisions in a hash table of dictionary words. The resulting Counts are stored in an instance of Ada.Containers.Ordered_Maps.
As a concrete example, the library Hash function
function Hash is new Ada.Strings.Bounded.Hash(ASB);
produces a result having unique hashes for over half of the words and just seven collisions in the worst case:
Word count: 235886
Table size: 393241
Load factor: 59.99%
0: 215725 (0.00%)
1: 129710 (54.99%)
2: 38727 (32.84%)
3: 7768 (9.88%)
4: 1153 (1.96%)
5: 143 (0.30%)
6: 14 (0.04%)
7: 1 (0.00%)
In contrast, this Hash function
function Hash(Key : ASB.Bounded_String) return Ada.Containers.Hash_Type is
S : String := ASB.To_String(Key);
H : Ada.Containers.Hash_Type := 0;
begin
for C of S loop
H := H * 3 + Character'Pos(C);
end loop;
return H;
end;
produces a result having unique hashes for fewer than half of the words and twenty collisions each for two different hash values in the worst case:
Word count: 235886
Table size: 393241
Load factor: 59.99%
0: 236804 (0.00%)
1: 107721 (45.67%)
2: 32247 (27.34%)
3: 9763 (12.42%)
4: 3427 (5.81%)
5: 1431 (3.03%)
6: 813 (2.07%)
7: 441 (1.31%)
8: 250 (0.85%)
9: 150 (0.57%)
10: 88 (0.37%)
11: 41 (0.19%)
12: 27 (0.14%)
13: 14 (0.08%)
14: 11 (0.07%)
15: 7 (0.04%)
16: 2 (0.01%)
17: 1 (0.01%)
19: 1 (0.01%)
20: 2 (0.02%)

Related

Trouble specifying datasummary() formula

I am getting weird outputs from my datasummary code. The idea is to create a table that shows the mean and SD for numeric variables and the number of observations for the full sample. I also want to display the shares for the two levels of a binary factor variable. Currently, i get the SD and mean from the only numeric variable (which makes sense), and the N shown is also only shown for the numeric variable. The N shown is also not the number of observations, but the first number in the numeric variable vector. This is my current code
age is the numeric variable
v2 - v4 are factor variables
obama is a factor variable which i want the table to show shares per each of the 2 levels.
datasummary(formula = age + (educated parent= education) + religion + sex ~ Heading("Entire sample") * 1 * (Mean + SD + N) + obama * Percent(), fmt = 3, data = data, title = 'Table 1: Votes for Obama in 2012 - Summary statistics', notes = c('1 = voted for Obama', 'educated parent: 1 = at least one parent has a degree', 'Source: General social survey'))
I am getting the warnings
Warning messages:
1: Summary statistic is length 1693
2: Summary statistic is length 1261
3: Summary statistic is length 432
4: Summary statistic is length 335
5: Summary statistic is length 379
6: Summary statistic is length 123
7: Summary statistic is length 856
8: Summary statistic is length 728
9: Summary statistic is length 965
Which are the values i want to be displayed under the "N" - column.
The table i get as an output looks like this
Table 1:
0 1
age 37.507 62.493
educated parent 0 27.998 46.486
1 9.510 16.007
religion None 3.662 16.125
Catholic 8.919 13.467
Other 1.713 5.552
Protestant 23.213 27.348
sex Male 18.252 24.749
Female 19.256 37.744
1 = voted for Obama
educated parent: 1 = at least one parent has a degree
Source: General social survey
The data is taken from gss_sm from the socviz package. I have created a new religion and a new education variable. Religion is a 4 level factor, and education is a 2 level factor.
I have tried making my own n fuction,
`n<-function() {
if(class(x)!="numeric"){
n<-length(x)
}
else{
n<-sum(!is.na(x))
}
formatC(n,digits=0)
}
`
and plugging that in in the place of "N".
It seems like as if it is the N function that isnt working.

Permutations subject to partial orders

I have two partial orders s_1 and s_2 of natural numbers. How to compute the possible permutations of the numbers of the two sets following the partial orders. We suppose that the two orders are compatible.
For example:
s_1=(1, 2, 4)
s_2=(2,3)
In this example, we search the number of permutations of the numbers from 1, 2, 3 and 4 following the orders in s_1 and s_2.
I would appreciate any suggestions for the general case.
Supposing the partial orderings are compatible, you can split them into binary relations. Your example would become:
s_1 = (1,2)
s_2 = (2,3)
s_3 = (2,4)
You can write an algorithm to traverse all legal orderings from this information. A simple approach would be to recursively search through the available choices of the partially ordered set. Here is an example pseudocode:
Recursive Search For All Legal Permutations Subject to Partial Ordering
1: procedure FindPOPerms(Poset)
2: MinNode = minimum value in Poset
3: MaxNode = maximum value in Poset
3: Available = MinNode→MaxNode
4: NNodes = No. of elements in Available
5: NPoset = No. of rows in Poset
6: Sequence = column array of zeros with length NNodes
7: Candidates = difference between Available set and column 2 of Poset
8: Selection = Candidates(1)
9: Available = set difference between Available and Selection
10: Poset = all Poset rows where column 1 is not equal to Selection
11: Iter = 0
12: POPerms = POPermSearch(Available, Candidates, Poset, Iter, Sequence)
13: end procedure
14: procedure POPermSearch(Available, Candidates, Poset, Iter, Sequence)
15: Iter = Iter+1
16: POPerms = empty array
17: if Available is not empty then
18: for i=1→number of elements in Candidates
19: S = Candidates(i)
20: A = set difference between Available and S
21: P = all Poset rows where column 1 is not equal to S
22: C = set difference between A and column 2 of P
23: Seq = Sequence
24: Seq(Iter) = S
25: POP = POPermSearch(A, C, P, Iter, Seq)
26: POPerms = add POP as new row to POPerms
27: end for
28: else
29: POPerms = Sequence
30: end if
31: end procedure
The input Poset for your case would be a 3x2 array:
1
2
2
3
2
4
with POPerms 2x4 output array:
1
2
3
4
1
2
4
3

Convert a two-letter String to a 3-digit number

I am working on a software problem and I found myself needing to convert a 2-letter string to a 3-digit number. We're talking about English alphabet only (26 letters).
So essentially I need to convert something like AA, AR, ZF, ZZ etc. to a number in the range 0-999.
We have 676 combinations of letters and 1000 numbers, so the range is covered.
Now, I could just write up a map manually, saying that AA = 1, AB = 2 etc., but I was wondering if maybe there is a better, more "mathematical" or "logical" solution to this.
The order of numbers is of course not relevant, as long as the conversion from letters to numbers is unique and always yields the same results.
The conversion should work both ways (from letters to numbers and from numbers to letters).
Does anyone have an idea?
Thanks a lot
Treat A-Z as 1-26 in base 27, with 0 reserved for blanks.
E.g. 'CD' -> 3 * 27 + 4 = 85
85 -> 85 / 27, 85 % 27 = 3, 4 = C, D
If you don’t have to use consecutive numbers, you can view a two-letter string as a 36-based number. So, you can just use the int function to convert it into an Integer.
int('AA', 36) # 370
int('AB', 36) # 371
#...
int('ZY', 36) # 1294
int('ZZ', 36) # 1295
As for how to convert the number back to a string, you can refer to the method on How to convert an integer to a string in any base?
#furry12 because the diff between the first number and the last one is 1295-370=925<999. It is quite lucky, so you can minus every number for like 300, the results will be in the range of 0-999
def str2num(s):
return int(s, 36) - 300
print(str2num('AA')) # 70
print(str2num('ZZ')) # 995

This is spoj's Playing with gcd id najpwg http://www.spoj.com/problems/NAJPWG/ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm getting tle in this code any suggestions.I'm calculating the sum n/i where
n is the input and i goes from 2 to n.
for example for 5 pairs will be (2,2),(3,3),(4,4),(5,5),(2,4)
#include<stdio.h>
‏
int main()
{
int i,j,t,n,m;
long long k;
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%d",&n);
m=n/2;
k=0;
for(j=2;j<=m;j++)
{
k+=(n/j);
}
k+=(n-m);
printf("Case %d: %lld\n",i+1,k);
}
return 0;
}`
There are a lot of problems with your code.
Broadly classifying -
Optimization can be talked about when the issue no.2 gets resolved.
Code gives wrong answer. Your algorithm is,summarily, incorrect. Dump this approach and think in terms of "Euler Totient" and elementary dynamic programming.
For example,
Let's say, the number is N.
Now, N would contain all the pairs that N-1 had. In addition to that it would also contain some newer ones( for which you can take help of Euler Totient function).
Sample Test cases for your practice -
input-
25
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1021
99998
99999
100000
output-
Case 1: 0
Case 2: 0
Case 3: 1
Case 4: 2
Case 5: 4
Case 6: 5
Case 7: 9
Case 8: 10
Case 9: 14
Case 10: 17
Case 11: 23
Case 12: 24
Case 13: 32
Case 14: 33
Case 15: 41
Case 16: 48
Case 17: 56
Case 18: 57
Case 19: 69
Case 20: 70
Case 21: 82
Case 22: 204311
Case 23: 1960304047
Case 24: 1960339246
Case 25: 1960399246
*

Consolidate 10 bit Value into a Unique Byte

As part of an algorithm I'm writing, I need to find a way to convert a 10-bit word into a unique 8-bit word. The 10-bit word is made up of 5 pairs, where each pair can only ever equal 0, 1 or 2 (never 3). For example:
|00|10|00|01|10|
This value needs to somehow be consolidated into a single, unique byte.
As each pair can never equal 3, there are a wide range of values that this 10-bit word will never represent, which makes me think that it is possible to create an algorithm to perform this conversion. The simplest way to do this would be to use a lookup table, but it seems like a waste of resources to store ~680 values which will only be used once in my program. I've already tried to incorporate one of the pairs into the others somehow, but every attempt I've made has resulted in a non-unique value, and I'm now very quickly running out of ideas!
Any help?
The number you have is essentially base 3. You just need to convert this to base 2.
There are 5 pairs, so 3^5 = 243 numbers. And 8 bits is 2^8 = 256 numbers, so it's possible.
The simplest way to convert between bases is to go to base 10 first.
So, for your example:
00|10|00|01|10
Base 3: 02012
Base 10: 2*3^3 + 1*3^1 + 2*3^0
= 54 + 3 + 2
= 59
Base 2:
59 % 2 = 1
/2 29 % 2 = 1
/2 14 % 2 = 0
/2 7 % 2 = 1
/2 3 % 2 = 1
/2 1 % 2 = 1
So 111011 is your number in binary
This explains the above process in a bit more detail.
Note that once you have 59 above stored in a 1-byte integer, you'll probably already have what you want, thus explicitly converting to base 2 might not be necessary.
What you basically have is a base 3 number and you want to convert this to a single number 0 - 255, luckily 5 digits in ternary (base 3) gives 243 combinations.
What you'll need to do is:
Digit Action
( 1st x 3^4)
+ (2nd x 3^3)
+ (3rd x 3^2)
+ (4th x 3)
+ (5th)
This will give you a number 0 to 242.
You are considering to store some information in a byte. A byte can contain at most 2 ^ 8 = 256 status.
Your status is totally 3 ^ 5 = 243 < 256. That make the transfer possible.
Consider your pairs are ABCDE (each character can be 0, 1 or 2)
You can just calculate A*3^4 + B*3^3 + C*3^2 + D*3 + E as your result. I guarantee the result will be in range 0 -- 255.

Resources