Google Code Jam 2008 Round 1A Q 3 - algorithm

For the problem statement in google codejam 2008: Round 1A Question 3
In this problem, you have to find the last three digits before the
decimal point for the number (3 + √5)n.
For example, when n = 5, (3 + √5)5 = 3935.73982... The
answer is 935.
For n = 2, (3 + √5)2 = 27.4164079... The answer is 027.
My solution based on the idea that T(i) = 6*T(i-1) - 4*T(n-2) + 1, where T(i) is the integer part for n=i is as below:
#include<stdio.h>
int a[5000];
main(){
unsigned long l,n;
int i,t;
a[0]=1;
a[1]=5;
freopen("C-small-practice.in","r",stdin);
scanf("%d",&t);
for(i=2;i<5000;i++)
a[i]=(6*a[i-1]-4*a[i-2]+10001)%1000;
i=t;
for(i=1;i<=t;i++){
scanf("%ld",&n);
printf("Case #%d: %.3d\n",i,a[(int)n]);
}
fclose(stdin);
}
in the line a[i]=(6*a[i-1]-4*a[i-2]+10001)%1000; i know there will be integer overflow, but i dont know why by adding 10,000 i am getting the right answer.
I am using GCC compiler where sizeof(int)=4
Can anyone explain what is happening ?

First off, the line
a[i]=(6*a[i-1]-4*a[i-2]+10001)%1000;
shouldn't actually cause any overflow, since you're keeping all previous values below 1000.
Second, did you consider what happens if 6*a[i-1]-4*a[i-2]+1 is negative? The modulus operator doesn't have to always return a positive value; it can also return negative values as well (if the thing you are dividing is itself negative).
By adding 10000, you've ensured that no matter what the previous values were, the value of that expression is positive, and hence the mod will give a positive integer result.
Expanding on that second point, here's 6.5.5.6 of the C99 specification:
When integers are divided, the result of the / operator is the algebraic
quotient with any fractional part discarded. If the quotient a/b is
representable, the expression (a/b)*b + a%b shall equal a.
A note beside the word "discarded" states that / "truncates toward zero". Hence, for the second sentence to be true, the result of a % b when a is negative must itself be negative.

Related

Finding nth largest number among three numbers

Given numbers k, a, b, c. How to find the kth largest number among a, b, and c without using if or any array or loop. min or max functions are provided.
You need something like that C++ fragment. In other languages it might look different.
auto 1st = max(a,max(b,c));
auto 3rd = min(a,min(b,c));
auto 2nd = a+b+c-1st-3rd;
return (2-k)*(3-k)*1st/2 + (k-1)*(3-k)*2nd + (k-1)*(k-2)*3rd/2;
It is assumed that k equals one of the numbers 1, 2, 3.
Incorporating 2 comments results in the more beautiful:
#define maybe(x) x*(x!=n1&&x!=n3)
auto n1 = max(a,max(b,c));
auto n3 = min(a,min(b,c));
auto n2 = maybe(a)+maybe(b)+maybe(c);
return n1*(k==1) + n2*(k==2) + n3*(k==3);
Also, my 1st version ignored the fact that identifiers can't start with a digit.
In some languages, (k==1) cannot be used as an integer, or is not guaranteed to be 0 or 1. In these languages, the 1st version may work better.
Regarding the overflow: That depends on the type.
For integer types, a+b+c-n1-n3 may cause an overflow, but is still correct. That's why: The result of a+b+c-n1-n3 will be correct in the lower bits. For example, if we use 32 bit numbers, a, b and c will be 32-bit-numbers and the result will be correct in the lowest 32 bits. That is, the result will be exactly a or be or c. Thus it is correct. Given the fact that for float numbers ^ won't work and the question did not specify the type of the numbers, I go back from ^ to + and -.
For non-integer types, an overflow may introduce a rounding error. To avoid that, I now chose an implementation that does not use + or - at all except when adding 0.

"interval is empty", Lua math.random isn't working for large numbers?

I didn't know if this is a bug in Lua itself or if I was doing something wrong. I couldn't find anything about it anywhere. I am using Lua for Windows (Lua 5.1.4):
>return math.random(0, 1000000000)
1251258
This returns a random integer between 0 and 10000000000, as expected. This seems to work for all other values. But if I add a single 0:
>return math.random(0, 10000000000)
stdin:1: bad argument #2 to 'random' (interval is empty)
Any number higher than that does the same thing.
I tried to figure out exactly how high a number has to be to cause this and found something even weirder:
>return math.random(0, 2147483647)
-75617745
If the value is 2147483647 then it gives me negative numbers. Any higher than that and it throws an error. Any lower than that and it works fine.
That's 0b1111111111111111111111111111111 in binary, 31 binary digits exactly. I am not sure what that means though.
This unexpected behavior (bug?) is due to how math.random treats the input arguments passed in Lua 5.1. From lmathlib.c:
case 2: { /* lower and upper limits */
int l = luaL_checkint(L, 1);
int u = luaL_checkint(L, 2);
luaL_argcheck(L, l<=u, 2, "interval is empty");
lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
break;
}
As you may know in C, a standard int can represent values -2,147,483,648 to 2,147,483,647. Adding +1 to 2,147,483,647, like in your use-case, will overflow and wrap around the value giving -2,147,483,648. The end result is negative since you're multiplying a positive with a negative number.
Furthermore, anything above 2,147,483,647 will fail the luaL_argcheck due to overflow wraparound.
There are a few ways to address this problem:
Upgrade to Lua 5.2. That one has since fixed this issue by treating the input arguments as lua_Number instead.
Switch to LuaJIT which does not have this integer overflow issue.
Patch the Lua 5.1 source yourself with the fix and recompile.
Modify your random range so it does not overflow.
If you need a range that is larger than what the random function supports (32 bit signed integers or 2^31 due to sign bit, because math.random is at C level), but smaller than the range of Lua "number" type (based on What is the maximum value of a number in Lua?, 2^52, or maybe even 2^53), you could try generating two random numbers: scale the first to the range desired; add the second to "fill the gap". For example, say you want a range of 0 to 2^36. The largest from math.random is 2^31. So you could do:
-- 2^36 = 2^31 * 2^5 so
scale = 2^5
baseRand = scale * math.random(0, 2^31)
-- baseRand is now between 0 and 2^36 but there are gaps of 2^5 in the set
-- of possible values; fill the gaps with second random number:
fillGap = math.random(0, 2^5)
randNum = baseRand + fillGap
This will work as long as the desired range is less than the Lua interpreter's maximum for Lua numbers, which is a configurable compile time parameter but if you use stock build it is 2^52, a very large number (although not as large as largest long integer, 2^63).
Note also that largest positive N-bit integer is 2^N-1 (not 2^N), but the above technique can be applied to any range, you could have for instance scale = 10^6 then randNum = 10^6 * math.random(0, 10^8) + math.random(0, 10^6).

Finding all n digit binary numbers with r adjacent digits as 1 [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Let me explain with an example. If n=4 and r=2 that means all 4 digit binary numbers such that two adjacent digits can be 1. so the answer is 0011 0110 1011 1100 1101
Q. i am unable to figure out a pattern or an algorithm.
Hint: The 11 can start in position 0, 1, or 2. On either side, the digit must be zero, so the only "free" digits are in the remaining position and can cycle through all possible values.
For example, if there are n=10 digits and you're looking for r=3 adjacent ones, the pattern is
x01110y
Where x and y can cycle through all possible suffixes and prefixes for the remaining five free digits. Note, on the sides, the leading and trailing zero gets dropped, leaving six free digits in x0111 and 1110y.
Here's an example using Python:
from itertools import product
def gen(n, r):
'Generate all n-length sequences with r fixed adjacent ones'
result = set()
fixed = tuple([1] * r + [0])
for suffix in product([0,1], repeat=n-r-1):
result.add(fixed + suffix)
fixed = tuple([0] + [1] * r + [0])
rem = n - r - 2
for leadsize in range(1, rem):
for digits in product([0,1], repeat=rem):
result.add(digits[:leadsize] + fixed + digits[leadsize:])
fixed = tuple([0] + [1] * r)
for prefix in product([0,1], repeat=n-r-1):
result.add(prefix + fixed)
return sorted(result)
I would start with simplifying the problem. Once you have a solution for the simplest case, generalize it and then try to optimize it.
First design an algorithm that will find out if a given number has 'r' adjacent 1s. Once you have it, the brute-force way is to go through all the numbers with 'n' digits, checking each with the algorithm you just developed.
Now, you can look for optimizing it. For example: if you know whether 'r' is even or odd, you can reduce your set of numbers to look at. The counting 1's algorithm given by KNR is order of number of set bits. Thus, you rule out half of the cases with lesser complexity then actual bit by bit comparison. There might be a better way to reduce this as well.
Funny problem with very simple recursive solution. Delphi.
procedure GenerateNLengthWithROnesTogether(s: string;
N, R, Len, OnesInRow: Integer; HasPatternAlready: Boolean);
begin
if Len = N then
Output(s)
else
begin
HasPatternAlready := HasPatternAlready or (OnesInRow >= R);
if HasPatternAlready or (N - Len > R) //there is chance to make pattern}
then
GenerateNLengthWithROnesTogether('0' + s, N, R, Len + 1, 0, HasPatternAlready);
if (not HasPatternAlready) or (OnesInRow < R - 1) //only one pattern allowed
then
GenerateNLengthWithROnesTogether('1' + s, N, R, Len + 1, OnesInRow + 1, HasPatternAlready);
end;
end;
begin
GenerateNLengthWithROnesTogether('', 5, 2, 0, 0, False);
end;
program output:
N=5,R=2
11000 01100 11010 00110
10110 11001 01101 00011
10011 01011
N=7, R=3
1110000 0111000 1110100 0011100
1011100 1110010 0111010 1110110
0001110 1001110 0101110 1101110
1110001 0111001 1110101 0011101
1011101 1110011 0111011 0000111
1000111 0100111 1100111 0010111
1010111 0110111
As I've stated in the comment above, I am still unclear about the full restrictions of the output set. However, the algorithm below can be refined to cover your final case.
Before I can describe the algorithm, there is an observation: let S be 1 repeated m times, and D be the set of all possible suffixes we can use to generate valid outputs. So, the bit string S0D0 (S followed by the 0 bit, followed by the bit string D followed by the 0 bit) is a valid output for the algorithm. Also, all strings ror(S0D0, k), 0<=k<=n-m are valid outputs (ror is the rotate right function, where bits that disappear on the right side come in from left). These will generate the bit strings S0D0 to 0D0S. In addition to these rotations, the solutions S0D1 and 1D0S are valid bit strings that can be generated by the pair (S, D).
So, the algorithm is simply enumerating all valid D bit strings, and generating the above set for each (S, D) pair. If you allow more than m 1s together in the D part, it is simple bit enumeration. If not, it is a recursive definition, where D is the set of outputs of the same algorithm with n'=n-(m+2) and m' is each of {m, m-1, ..., 1}.
Of course, this algorithm will generate some duplicates. The cases I can think of are when ror(S0D0,k) matches one of the patterns S0E0, S0E1 or 1E0S. For the first case, you can stop generating more outputs for larger k values. D=E generator will take care of those. You can also simply drop the other two cases, but you need to continue rotating.
I know there is an answer, but I wanted to see the algorithm at work, so I implemented a crude version. It turned out to have more edge cases than I realized. I haven't added duplication check for the two last yields of the family() function, which causes duplication for outputs like 11011, but the majority of them are eliminated.
def ror(str, n):
return str[-n:]+str[:-n]
def family(s, d, r):
root = s + '0' + d + '0'
yield root # root is always a solution
for i in range(1, len(d)+3):
sol=ror(root, i)
if sol[:r]==s and sol[r]=='0' and sol[-1]=='0':
break
yield sol
if d[-r:]!=s: # Make sure output is valid
yield s + '0' + d + '1'
if d[:r]!=s: # Make sure output is valid (todo: duplicate check)
yield '1' + d + '0' + s
def generate(n, r):
s="1"*r
if r==0: # no 1's allowed
yield '0'*n
elif n==r: # only one combination
yield s
elif n==r+1: # two cases. Cannot use family() for this
yield s+'0'
yield '0'+s
else:
# generate all sub-problem outputs
for rr in range(r+1):
if n-r-2>=rr:
for d in generate(n-r-2, rr):
for sol in family(s, d, r):
yield sol
You use it either as [s for s in generate(6,2)], or in a loop as
for s in generate(6,3):
print(s)

How many digits will be after converting from one numeral system to another

The main question: How many digits?
Let me explain. I have a number in binary system: 11000000 and in decimal is 192.
After converting to decimal, how many digits it will have (in dicimal)? In my example, it's 3 digits. But, it isn't a problem. I've searched over internet and found one algorithm for integral part and one for fractional part. I'm not quite understand them, but (I think) they works.
When converting from binary to octal, it's more easy: each 3 bits give you 1 digit in octal. Same for hex: each 4 bits = 1 hex digit.
But, I'm very curious, what to do, if I have a number in P numeral system and want to convert it to the Q numeral system? I know how to do it (I think, I know :)), but, 1st of all, I want to know how many digits in Q system it will take (u no, I must preallocate space).
Writing n in base b takes ceiling(log base b (n)) digits.
The ratio you noticed (octal/binary) is log base 8 (n) / log base 2 (n) = 3.
(From memory, will it stick?)
There was an error in my previous answer: look at the comment by Ben Schwehn.
Sorry for the confusion, I found and explain the error I made in my previous answer below.
Please use the answer provided by Paul Tomblin. (rewritten to use P, Q and n)
Y = ln(P^n) / ln(Q)
Y = n * ln(P) / ln(Q)
So Y (rounded up) is the number of characters you need in system Q to express the highest number you can encode in n characters in system P.
I have no answer (that wouldn't convert the number already and take up that many space in a temporary variable) to get the bare minimum for a given number 1000(bin) = 8(dec) while you would reserve 2 decimal positions using this formula.
If a temporary memory usage isn't a problem, you might cheat and use (Python):
len(str(int(otherBaseStr,P)))
This will give you the number of decimals needed to convert a number in base P, cast as a string (otherBaseStr), into decimals.
Old WRONG answer:
If you have a number in P numeral system of length n
Then you can calculate the highest number that is possible in n characters:
P^(n-1)
To express this highest number in number system Q you need to use logarithms (because they are the inverse to exponentiation):
log((P^(n-1))/log(Q)
(n-1)*log(P) / log(Q)
For example
11000000 in binary is 8 characters.
To get it in Decimal you would need:
(8-1)*log(2) / log(10) = 2.1 digits (round up to 3)
Reason it was wrong:
The highest number that is possible in n characters is
(P^n) - 1
not
P^(n-1)
If you have a number that's X digits long in base B, then the maximum value that can be represented is B^X - 1. So if you want to know how many digits it might take in base C, then you have to find the number Y that C^Y - 1 is at least as big as B^X - 1. The way to do that is to take the logarithm in base C of B^X-1. And since the logarithm (log) of a number in base C is the same as the natural log (ln) of that number divided by the natural log of C, that becomes:
Y = ln((B^X)-1) / ln(C) + 1
and since ln(B^X) is X * ln(B), and that's probably faster to calculate than ln(B^X-1) and close enough to the right answer, rewrite that as
Y = X * ln(B) / ln(C) + 1
Covert that to your favourite language. Because we dropped the "-1", we might end up with one digit more than you need in some cases. But even better, you can pre-calculate ln(B)/ln(C) and just multiply it by new "X"s and the length of the number you are trying to convert changes.
Calculating the number of digit can be done using the formulas given by the other answers, however, it might actually be faster to allocate a buffer of maximum size first and then return the relevant part of that buffer instead of calculating a logarithm.
Note that the worst case for the buffer size happens when you convert to binary, which gives you a buffer size of 32 characters for 32-bit integers.
Converting a number to an arbitrary base could be done using the C# function below (The code would look very similar in other languages like C or Java):
public static string IntToString(int value, char[] baseChars)
{
// 32 is the worst cast buffer size for base 2 and int.MaxValue
int i = 32;
char[] buffer = new char[i];
int targetBase= baseChars.Length;
do
{
buffer[--i] = baseChars[value % targetBase];
value = value / targetBase;
}
while (value > 0);
char[] result = new char[32 - i];
Array.Copy(buffer, i, result, 0, 32 - i);
return new string(result);
}
The keyword here is "logarithm", here are some suggestive links:
http://www.adug.org.au/MathsCorner/MathsCornerLogs2.htm
http://staff.spd.dcu.ie/johnbcos/download/Fermat%20material/Fermat_Record_Number/HOW_MANY.html
look at the logarithms base P and base Q. Round down to nearest integer.
The logarithm base P can be computed using your favorite base (10 or e): log_P(x) = log_10(x)/log_10(P)
You need to compute the length of the fractional part separately.
For binary to decimal, there are as many decimal digits as there are bits. For example, binary 0.11001101001001 is decimal 0.80133056640625, both 14 digits after the radix point.
For decimal to binary, there are two cases. If the decimal fraction is dyadic, then there are as many bits as decimal digits (same as for binary to decimal above). If the fraction is not dyadic, then the number of bits is infinite.
(You can use my decimal/binary converter to experiment with this.)

Given numbers from 1 to 2^32-1, one is missing. How to find the missing number optimally?

You are given 2^32-2 unique numbers that range from 1 to 2^32-1. It's impossible to fit all the numbers into memory (thus sorting is not an option). You are asked to find the missing number. What would be the best approach to this problem?
Let's assume you cannot use big-integers and are confined to 32bit ints.
ints are passed in through standard in.
Major Edit: Trust me to make things much harder than they have to be.
XOR all of them.
I'm assuming here that the numbers are 1 to 232 - 1 inclusive. This should use 1 extra memory location of 32 bits.
EDIT: I thought I could get away with magic. Ah well.
Explanation:
For those who know how Hamming Codes work, it's the same idea.
Basically, for all numbers from 0 to 2n - 1, there are exactly 2(n - 1) 1s in each bit position of the number. Therefore xoring all those numbers should actually give 0. However, since one number is missing, that particular column will give one, because there's an odd number of ones in that bit position.
Note: Although I personally prefer the ** operator for exponentiation, I've changed mine to ^ because that's what the OP has used. Don't confuse ^ for xor.
Add all the numbers you are given up using your favourite big integer library, and subtract that total from the sum of all the numbers from 1 to 2^32-1 as obtained from the sum of arithmetic progression formula
Use bitwise operator XOR. Here are example in JavaScript:
var numbers = [6, 2, 4, 5, 7, 1]; //2^3 exclude one, starting from 1
var result = 0;
//xor all values in numbers
for (var i = 0, l = numbers.length; i < l; i++) {
result ^= numbers[i];
}
console.log(result); //3
numbers[0] = 3; //replace 6 with 3
//same as above in functional style
result = numbers.reduce(function (previousValue, currentValue, index, array) {return currentValue ^= previousValue;});
console.log(result); //6
The same in C#:
int[] numbers = {3, 2, 4, 5, 7, 1};
int missing = numbers.Aggregate((result, next) => result ^ next);
Console.WriteLine(missing);
Assuming you can get the Size() you can use some binary approach. Select the set of numbers n where n< 2^32 -2 / 2. then get a count. The missing side should report a lower count. Do the process iteratively then you will get the answer
If you do not have XOR, then of course you can do the same with ordinary "unchecked" sum, that is sum of 32-bit integers with "wrap around" (no "overflow checking", sometimes known as unchecked context).
This is addition modulo 232. I will consider the "unsigned" case. If you 32-bit int uses two's complement, it is just the same. (To a mathematician, two's complement is still just addition (and multiplication) modulo 232, we only pick a different canonical representative for each equivalence class modulo 232.)
If we had had all the non-zero 32-bit integers, we would have:
1 + 2 + 3 + … + 4294967295 ≡ 2147483648
One way of realizing this is to take the first and the last term together, they give zero (modulo 232). Then the second term (2) and the second-last term (4294967294) also give zero. Thus all terms cancel except the middle one (2147483648) which is then equal to the sum.
From this equality, imagine you subtract one of the numbers (call it x) on both sides of the ≡ symbol. From this, you see that you find the missing number by starting from 2147483648 and subtracting (still unchecked) from that all of the numbers you are given. Then you end up with the missing number:
missingNumber ≡ 2147483648 - x1 - x2 - x3 - … - x4294967294
Of course, this is the same as moonshadow's solution, just carried out in the ring of integers modulo 232.
The elegant XOR solution (sykora's answer) can also be written in the same way, and with that XOR functions as both + and - at the same time. That is, if we had all the non-zero 32-bit integers, then
1 XOR 2 XOR 3 XOR … XOR 4294967295 ≡ 0
and then XOR with the missing number x on both sides of the ≡ symbol to see that:
missingNumber ≡ x1 XOR x2 XOR x3 XOR … XOR x4294967294

Resources