Hashing Elements by Mid-Square - data-structures

I'm making a hash function for a hash table of size 10 (indexes 0-9), and hashing elements using mid-square method.
The Problem is I'm confused whether i should use 1 middle digit or 2 digits then taking mod 10 of it.
The problem is if I choose to take 2 mid digit then taking mod 10, this method will fail if the squared number has 3 digits. Which two digits will I take then?
and if I choose to have 1 middle digit, then I'll have problem taking mid digit when squared number has even number of digits. I know in this situation both of the mid two element are made from contribution of all elements of the original number.
Right now, I'm going with {floor(n/2+1)}th digit. This way it works for three digit squared number, and when the squared number has even no. of digits, it's taking the later digit of the middle two.
I wanna know what more efficient approach of doing this?
Thanks.

I was taught that the correct way to mid square hash is to use 1 digit if the length of the resulting square is odd, if it's even then use the middle 2 digits.

Related

How to use the Pisano Period to find the Last Digit of the Sum of Fibonacci Numbers?

I'm taking an online algorithms course, and I've come across a problem where I need to find the last digit of the sum of the Fibonacci numbers up the nth (current) number.
I need some help connecting the dots. As I understand it, the "Last Digit of the Sum of Fibonacci Numbers" problem has a solution that is somehow related to the Pisano Period.
But I don't really understand what that means.
The Pisano Period was used to calculate the remainder given some value of m for an extremely large Fibonacci Number, which was the focus of a prior problem (I.E., Solve Fn mod m = ???).
Forum posts (and the instruction set) seem to suggest that the length can somehow help us quickly zero in on the sum for the current Fibonacci without having to actually build up to it normally through a loop.
I would rather avoid just looking at someone else's solution if possible, so if anyone has any useful hints that can help me see the missing link, I would really appreciate it.
The last digit of a Fibonacci number is just that number reduced modulo 10. Pisaso periods are the periods of which the sequence of fibonacci numbers, modulo some base, repeat. So, if you're interested in F(x) mod 10, you'd interested in the Pisaso Period p(10).
If we have this period, say it was something like [1, 5, 2, 7, 0] (its not, but for sake of example), we'd know that the 3rd integer in the sequence ended with a "2". And because it repeats, we'd know the 8th integer also ends in a "2", and the 13th...
Generalizing this, we could say that the last digit of the number N could be found at the ith index in our list we just built, for i satisfying N = 5 * k + i, where k is just any integer, and 5 comes from the fact that our list has 5 elements (and thus repeats every 5 values). Rewriting this, we could say i = N mod 5.
Putting that all together (spoilers), we just need to find the actual values of the repeating sequence mod 10, and then take our input value N (for finding the Nth Fibonacci number mod 10), and index into said repeatingSequence at index N mod len(repeatingSequence) for our answer.
For reference, for base 10, the actual repeating sequence is:
011235831459437077415617853819099875279651673033695493257291

Stuck on complexity analysis of a tricky program

Really stuck the complexity analysis of this problem .
Given digits 0–9 , we need to find all the numbers of max length k whose digits will be in increasing order .
for example if k = 3 , numbers can be 0,00,000,01,02,03,04,.... 1,11,111,12,...
So the question basically that if repetitions allowed for digits,
How many such combinations are possible to find all the numbers less than size k (less than digit length k) such that digits from left to right will be non-decreasing order.
Numbers with at most k digits that are weakly increasing are in 1-1 correspondence with binary strings of length k+10, with exactly ten 1's. The number of consecutive 0s just before the ith one and one in the binary string is the number of i digits in the original number. For example, if k=7, then 001119 maps to 00100011111111010 (2 zeros, 3 ones, 0 twos, 0 threes, ..., 0 eights, 1 nine, 1 digit left over to make the number of digits up to 7).
These binary strings are easy to count: there's choose(k+10, 10)-1 of them (missing one because the empty number is disallowed). This can be computed in O(1) arithmetic operations (actually 10 additions, 18 multiplications and one division).
I don't have enough reputation neither, so I cannot answer Paul's or Globe's answer.
Globe's answer choose(k+9,9) is not perfect, because it only counts the solutions where the numbers have exactly k digits. But the original problems allows numbers with less digits too.
Paul's answer choose(k+10,10) counts these shorter numbers too, but it also allows numbers with zero digits. Let's say k=7 then the following binary string describes a number with no digits: 11111111110000000. We have to exclude this one.
So the solution is: choose(k+10,10)-1
I don't have enough reputation to comment on Paul's answer, so I'm adding another answer. The formula isn't choose(k+10, 10) as specified by Paul, it's choose(k+9, 9).
For instance if we have k=2, choose(2+10, 10) gives us 66, when there are only 55 numbers that satisfy the property.
We pick stars and separators, where the separators divide our digits into buckets from 0 to 9, and stars tell us how many digits to pick from a bucket. (E.g. **|**||*||||||* corresponding to 001139)
The reasoning behind it being k+9 and not k+10 is as follows:
we have to pick 9 separators between 10 digits, so while we have k choices for the stars, we only have 9 choices for the separators.

What's would be a good algorithm (in words) of how to solve #8 in Project Euler with Lua?

This is the question:
Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product?
In lua, what would be the best way, loop or no loop, to splice and return the 900 hundred something 13 digits in a number, string, or array? (I will just use recursion to find the product of those 13 digits)
Please don't return the answer to the actual problem.
I think an easy way to do this that doesn't require any splicing or additional storage is this :
Multiply the first 13 digits. You can use sub to extract those digits from positions in the string, and tonumber to convert them to number to multiply. Let's say we call the result product.
Go through positions pos = 14 to 1000 and recalculate product as product / number-from-position-pos-13 * number-from-position-pos. Compare it with the largest product seen so far and remember position if it's the largest one.
Return position.
Since the sequence may include zeroes, they may require a separate handling. Instead of multiplying by zero, you can keep track of how many zeroes the current sequence has and don't update the largest number if the number of zeroes in the sequence is more than zero. When you have zero in position pos-13, you decrease the number of zeros and when you have zero in position pos, you increase the zero counter.

finding the count of cells in a given 2d array satisfying the given constraints

Given a 2-D array starting at (0,0) and proceeding to infinity in positive x and y axes. Given a number k>0 , find the number of cells reachable from (0,0) such that at every moment -> sum of digits of x+ sum of digits of y <=k . Moves can be up, down ,left or right. given x,y>=0 . Dfs gives answers but not sufficient for large values of k. anyone can help me with a better algorithm for this?
I think they asked you to calculate the number of cells (x,y) reachable with k>=x+y. If x=1 for example, then y can take any number between 0 and k-1 and the sum would be <=k. The total number of possibilities can be calculated by
sum(sum(1,y=0..k-x),x=0..k) = 1/2*k²+3/2*k+1
That should be able to do the trick for large k.
I am somewhat confused by the "digits" in your question. The digits make up the index like 3 times 9 makes 999. The sum of digits for the cell (999,888) would be 51. If you would allow the sum of digits to be 10^9 then you could potentially have 10^8 digits for an index, resulting something around 10^(10^8) entries, well beyond normal sizes for a table. I am therefore assuming my first interpretation. If that's not correct, then could you explain it a bit more?
EDIT:
okay, so my answer is not going to solve it. I'm afraid I don't see a nice formula or answer. I would approach it as a coloring/marking problem and mark all valid cells, then use some other technique to make sure all the parts are connected/to count them.
I have tried to come up with something but it's too messy. Basically I would try and mark large parts at once based on the index and k. If k=20, you can mark the cell range (0,0..299) at once (as any lower index will have a lower index sum) and continue to check the rest of the range. I start with 299 by fixing the 2 last digits to their maximum value and look for the max value for the first digit. Then continue that process for the remaining hundreds (300-999) and only fix the last digit to end up with 300..389 and 390..398. However, you can already see that it's a mess... (nevertheless i wanted to give it to you, you might get some better idea)
Another thing you can see immediately is that you problem is symmetric in index so any valid cell (x,y) tells you there's another valid cell (y,x). In a marking scheme / dfs/ bfs this can be exploited.

Find if any permutation of a number is within a range

I need to find if any permutation of the number exists within a specified range, i just need to return Yes or No.
For eg : Number = 122, and Range = [200, 250]. The answer would be Yes, as 221 exists within the range.
PS:
For the problem that i have in hand, the number to be searched
will only have two different digits (It will only contain 1 and 2,
Eg : 1112221121).
This is not a homework question. It was asked in an interview.
The approach I suggested was to find all permutations of the given number and check. Or loop through the range and check if we find any permutation of the number.
Checking every permutation is too expensive and unnecessary.
First, you need to look at them as strings, not numbers,
Consider each digit position as a seperate variable.
Consider how the set of possible digits each variable can hold is restricted by the range. Each digit/variable pair will be either (a) always valid (b) always invalid; or (c) its validity is conditionally dependent on specific other variables.
Now model these dependencies and independencies as a graph. As case (c) is rare, it will be easy to search in time proportional to O(10N) = O(N)
Numbers have a great property which I think can help you here:
For a given number a of value KXXXX, where K is given, we can
deduce that K0000 <= a < K9999.
Using this property, we can try to build a permutation which is within the range:
Let's take your example:
Range = [200, 250]
Number = 122
First, we can define that the first number must be 2. We have two 2's so we are good so far.
The second number must be be between 0 and 5. We have two candidate, 1 and 2. Still not bad.
Let's check the first value 1:
Any number would be good here, and we still have an unused 2. We have found our permutation (212) and therefor the answer is Yes.
If we did find a contradiction with the value 1, we need to backtrack and try the value 2 and so on.
If none of the solutions are valid, return No.
This Algorithm can be implemented using backtracking and should be very efficient since you only have 2 values to test on each position.
The complexity of this algorithm is 2^l where l is the number of elements.
You could try to implement some kind of binary search:
If you have 6 ones and 4 twos in your number, then first you have the interval
[1111112222; 2222111111]
If your range does not overlap with this interval, you are finished. Now split this interval in the middle, you get
(1111112222 + 222211111) / 2
Now find the largest number consisting of 1's and 2's of the respective number that is smaller than the split point. (Probably this step could be improved by calculating the split directly in some efficient way based on the 1 and 2 or by interpreting 1 and 2 as 0 and 1 of a binary number. One could also consider taking the geometric mean of the two numbers, as the candidates might then be more evenly distributed between left and right.)
[Edit: I think I've got it: Suppose the bounds have the form pq and pr (i.e. p is a common prefix), then build from q and r a symmetric string s with the 1's at the beginning and the end of the string and the 2's in the middle and take ps as the split point (so from 1111112222 and 1122221111 you would build 111122222211, prefix is p=11).]
If this number is contained in the range, you are finished.
If not, look whether the range is above or below and repeat with [old lower bound;split] or [split;old upper bound].
Suppose the range given to you is: ABC and DEF (each character is a digit).
Algorithm permutationExists(range_start, range_end, range_index, nos1, nos2)
if (nos1>0 AND range_start[range_index] < 1 < range_end[range_index] and
permutationExists(range_start, range_end, range_index+1, nos1-1, nos2))
return true
elif (nos2>0 AND range_start[range_index] < 2 < range_end[range_index] and
permutationExists(range_start, range_end, range_index+1, nos1, nos2-1))
return true
else
return false
I am assuming every single number to be a series of digits. The given number is represented as {numberOf1s, numberOf2s}. I am trying to fit the digits (first 1s and then 2s) within the range, if not the procudure returns a false.
PS: I might be really wrong. I dont know if this sort of thing can work. I haven't given it much thought, really..
UPDATE
I am wrong in the way I express the algorithm. There are a few changes that need to be done in it. Here is a working code (It worked for most of my test cases): http://ideone.com/1aOa4
You really only need to check at most TWO of the possible permutations.
Suppose your input number contains only the digits X and Y, with X<Y. In your example, X=1 and Y=2. I'll ignore all the special cases where you've run out of one digit or the other.
Phase 1: Handle the common prefix.
Let A be the first digit in the lower bound of the range, and let B be the first digit in the upper bound of the range. If A<B, then we are done with Phase 1 and move on to Phase 2.
Otherwise, A=B. If X=A=B, then use X as the first digit of the permutation and repeat Phase 1 on the next digit. If Y=A=B, then use Y as the first digit of the permutation and repeat Phase 1 on the next digit.
If neither X nor Y is equal to A and B, then stop. The answer is No.
Phase 2: Done with the common prefix.
At this point, A<B. If A<X<B, then use X as the first digit of the permutation and fill in the remaining digits however you want. The answer is Yes. (And similarly if A<Y<B.)
Otherwise, check the following four cases. At most two of the cases will require real work.
If A=X, then try using X as the first digit of the permutation, followed by all the Y's, followed by the rest of the X's. In other words, make the rest of the permutation as large as possible. If this permutation is in range, then the answer is Yes. If this permutation is not in range, then no permutation starting with X can succeed.
If B=X, then try using X as the first digit of the permutation, followed by the rest of the X's, followed by all the Y's. In other words, make the rest of the permutation as small as possible. If this permutation is in range, then the answer is Yes. If this permutation is not in range, then no permutation starting with X can succeed.
Similar cases if A=Y or B=Y.
If none of these four cases succeed, then the answer is No. Notice that at most one of the X cases and at most one of the Y cases can match.
In this solution, I've assumed that the input number and the two numbers in the range all contain the same number of digits. With a little extra work, the approach can be extended to cases where the numbers of digits differ.

Resources