How to solve this Multiple Branching question - leap-year

Create function is_leap_year(y) in which y is a year number. the function will return True if the year is a leap year, otherwise, it will return False.
A leap year's number is an integer multiple of 4 (except for years evenly divisible by 100, which are not leap years unless evenly divisible by 400)

That's a fairly succint (pseudo-code):
define is_leap_year(y):
if y is divisible by 400:
return true
if y is divisible by 100:
return false
if y is divisible by 4:
return true
return false
That's probably the easiest solution as doing it in that order allows you to avoid complicated (and totally unnecessary) if/else "ladder" code:
define is_leap_year(y):
if y is divisible by 4:
if y is divisible by 100:
if y is divisible by 400:
return true
else:
return false
else:
return true
else:
return false
Now just translate that (the first one, above) to your language of choice.

Leap year: Happens every 4 years, except for end-of-century years, which must be divisible by 400.
end-of-century years (ending with 00) like 1000, 1100, 1200, ....,
2000, 2100, 2200, ...
divisible by 100 means century year and
divisible by 400 (leap year)
not divisible by 100 means not century year and divisible by 4 (leap year)
neither divisible by 400 and 4 (not leap year)
Code Snippet
def is_leap_year(y):
if (y % 400 == 0) and (y % 100 == 0): return True
elif (y % 4 == 0) and (y % 100 != 0): return True
else: return False

Related

Function that will return the biggest number of consecutive 0's

For a homework problem, in python we are asked to define in a recursive way a function that will return the biggest number of consecutive 0's in binary for any the number n. We need to use "&" and ">>".
For example, the function should return 2 for n = 44 because its binary representation is 101100.
I do not know where to go from here. Any help would be appreciated!
def max_consecutive_zero_iterative(n):
res = 0
streak = 0
while n > 0:
if n & 1:
streak = 0
else:
streak += 1
n = n >> 1
res = max(res, streak)
return res
def max_consecutive_zero_recursive(n):
if n == 0: # end of recursion
return 0
value = max_consecutive_zero_recursive(n >> 1) # call to recursive
current_streak = value & 0xff # current streak is stored in the lowest 8 bits
longest_streak = value >> 8 # longest streak is stored in the upper bits
if n & 1: # if we have a bit set
return max(longest_streak, current_streak) << 8 # we just return the max value between current_streak and longest_streak, stored in upper bits
# else if the bit is not set
current_streak += 1 # we increase our current streak by 1
# and return the max between the longest_streak and current_streak in the upper bits...
return max(longest_streak, current_streak) << 8 | current_streak
# ... but this time we keep information (we don't reset) about the current_streak stored in the lowest 8 bits.
def main():
print(max_consecutive_zero_recursive(0b1000101111000110000000100110) >> 8)
if __name__ == "__main__":
main()

Number of action per year. Combinatorics question

I'm writing a diploma about vaccines. There is a region, its population and 12 month. There is an array of 12 values from 0 to 1 with step 0.01. It means which part of population should we vaccinate in every month.
For example if we have array = [0.1,0,0,0,0,0,0,0,0,0,0,0]. That means that we should vaccinate 0.1 of region population only in first month.
Another array = [0, 0.23,0,0,0,0,0,0, 0.02,0,0,0]. It means that we should vaccinate 0.23 of region population in second month and 0.02 of region population in 9th month.
So the question is: how to generate (using 3 loops) 12(months) * 12(times of vaccinating) * 100 (number of steps from 0 to 1) = 14_400 number of arrays that will contain every version of these combinations.
For now I have this code:
for(int month = 0;month<12;month++){
for (double step = 0;step<=1;step+=0.01){
double[] arr = new double[12];
arr[month] = step;
}
}
I need to add 3d loop that will vary number of vaccinating per year.
Have no idea how to write it.
Idk if it is understandable.
Hope u get it otherwise ask me, please.
You have 101 variants for the first month 0.00, 0.01..1.00
And 101 variants for the second month - same values.
And 101*101 possible combinations for two months.
Continuing - for all 12 months you have 101^12 variants ~ 10^24
It is not possible to generate and store so many combinations (at least in the current decade)
If step is larger than 0.01, then combination count might be reliable. General formula is P=N^M where N is number of variants per month, M is number of months
You can traverse all combinations representing all integers in range 0..P-1 in N-ric numeral system. Or make digit counter:
fill array D[12] with zeros
repeat
increment element at the last index by step value
if it reaches the limit, make it zero
and increment element at the next index
until the first element reaches the limit
It is similar to counting 08, 09, here we cannot increment 9, so make 10 and so on
s = 1
m = 3
mx = 3
l = [0]*m
i = 0
while i < m:
print([x/3 for x in l])
i = 0
l[i] += s
while (i < m) and l[i] > mx:
l[i] = 0
i += 1
if i < m:
l[i] += s
Python code prints 64 ((mx/s+1)^m=4^3) variants like [0.3333, 0.6666, 0.0]

Knapsack variation

So I have an array of coupons, each with a price and the quantity of items that can be bought from it. I can only buy the given item quantity from a coupon, no more, no less. How to find the minimum cost to get the required number of items with coupons (and return -1 if not possible)?
For example, on having 4 coupons: "Buy 3 at 10 dollars", "Buy 2 at 4 dollars", "Buy 2 at 4 dollars" and "Buy 1 at 3 dollars", and 4 items to buy, the minimum cost is 8 dollars.
Knapsack works on finding maximums, but for minimum it'll just keep on not considering any coupon and come up with an answer of 0.
Here's my code:
int minimumCost(coupon_t coupons[], int numCoupons, int units) {
if (units <= 0 || numCoupons <= 0)
return 0;
if (coupons[numCoupons-1].quantity > units)
return minimumCost(coupons, numCoupons-1, units);
coupon_t coupon = coupons[numCoupons-1];
return min(coupon.price + minimumCost(coupons, numCoupons-1, units-coupon.quantity),
minimumCost(coupons, numCoupons-1, units));
}
Had a little more think about this. The key, as you say, is handling of 0. In typical knapsack code, 0 has two meanings: both "not buying" and "can't buy". Splitting those seems to work:
def minimum_cost(coupons, units, coupon_no=0):
if units < 0 or coupon_no == len(coupons):
# special value for "impossible"
return None
if units == 0:
# no more space, so we're not buying anything else
return 0
quantity, price = coupons[coupon_no]
next_coupon = coupon_no + 1
if quantity > units:
return minimum_cost(coupons, units, next_coupon)
pre_purchase_value_when_used = minimum_cost(coupons, units - quantity, next_coupon)
value_when_unused = minimum_cost(coupons, units, next_coupon)
# return whichever is not impossible, or cheaper of two possibilities:
if pre_purchase_value_when_used is None:
return value_when_unused
elif value_when_unused is None:
return pre_purchase_value_when_used + price
else:
return min(pre_purchase_value_when_used + price, value_when_unused)
coupons = [[3, 10], [2, 4], [2, 4], [1, 3]]
units = 4
cost = minimum_cost(coupons, units)
print(cost)
# => 8
(Note that recursion is not dynamic-programming, unless you cache the function results, although it shouldn't be too hard to make it use a table. The key insight about dynamic programming is to use storage to avoid recalculating things we already calculated.)

How to quickly tell if an "unknown" number is divisible by 3?

I'm trying to tackle down a problem where the time limit is very low (1 second) and the number of cases is supposedly high.
You need to tell if a number is divisible by 3, but the problem is that you don't get the direct number, you get a number k, and then need to check if the concatenation of numbers from 1 to k (123...k) is divisible by 3.
Example input:
4 // The number of cases
2
6
15
130000000
Output:
YES // Because 12 is divisible by 3
YES // Because 123456 is divisible by 3
YES // Because 123456789101112131415 is divisible by 3
NO
I've found some topics about quickly checking the divisibility, but what most time takes I think is to build the number. There are cases where the initial number is as high as 130000000 (so the final is 1234...130000000) which I thinks overflows any numeric data type.
So, what am I missing here? Is there any way to know if something is divisible by 3 without concatenating the number? Any ideas?
PD: Someone also posted the triangular numbers formula which also is a correct solution and then deleted the answer, it was:
if ((1 + num) * num / 2) % 3 == 0 ? "YES" : "NO"
Every third number is divisible by three.
Every number divisible by three has a digit sum divisible by 3.
Every third number has a digit sum divisible by 3.
In between these, every third number has a digit sum congruent to 1 and then 2 mod 3.
Take a look:
n digit sum mod 3
0 0
1 1
2 2
3 0
4 1
5 2
6 0
...
10 1
11 2
12 0
...
19 1
20 2
21 0
...
Say we have a string of digits constructed as you describe, and the number we just added was divisible mod 3. When we append the next number's digits, we are appending digits whose sum is congruent to 1 mod 3, and when added to those in our number, we will get a combined digit sum congruent to 1 mod 3, so our answer for the next one will be "no". The next one will add a number with digit sum congruent to 2 mod 3, and this causes the total to become congruent to 0 again, so the answer here is "yes". Finally, adding the next number which must be divisible by 3 keeps the digit sum congruent to 0.
The takeaway?
if n is congruent to 0 modulo 3, then the answer is "yes"
if n is congruent to 1 modulo 3, then the answer is "no"
if n is congruent to 2 modulo 3, then the answer is "yes"
In particular, your example for n=15 is wrong; the digit string obtained represents a number that should be divisible by 3, and indeed it is (try it on a big enough calculator to verify).
All that is left is to find an implementation that is fast enough and handles all the required cases. If n is guaranteed to be under ~2 billion, then you are probably safe with something like
return (n % 3) != 1;
If n can be an arbitrarily large number, never fear; you can check whether the digit sum is congruent to 0 modulo 3 by adding up the digits in linear time. If not, you can add 1 from the number by coding addition like you do it by hand on paper and then check the result of that for divisibility by 3, again in linear time. So something like:
if (digit_sum_mod_3(n) == 0) return true;
else if (digit_sum_mod_3(add_one(n)) == 0) return false;
else return true;
Then you would have something like
digit_sum_mod_3(n[1...m])
sum = 0
for k = 1 to m do
sum = sum + n[k]
// keep sum from getting too big
if sum >= 18 then
sum = sum - 18
return sum % 3
add_one(n[1...m])
// work from right to left, assume big-endian
for k = m to 1 do
if n[k] < 9 then // don't need to carry
n[k] = n[k] + 1
break
else then // need to carry
n[k] = 0
if n[1] = 0 then // carried all the way to the front
n[1] = 1
n[m+1] = 0
return n
Any three consecutive numbers sum up to 0 == a + a + 1 + a + 2 mod 3.
The answer reduces to k%3 == 0, or 2k-1 % 3 == 0. The latter is equivalent to k%3 == 2, which leaves out k%3==1 which then simplifies further to k%3 != 1.
It is a known trick in mathematics that a number is divisible by three if the sum of its individual decimal digits is divisible by three.
Example:
2271
2+2+7+1 = 12
12 is divisible by 3, therefore so is 2271
Additionally, the sum of any three consecutive integers must be divisible by three. This is because:
((n)+(n+1)+(n+2))/3 = (3n+3)/3 = n+1 = integer
Therefore:
If k mod 3 == 0, then concatenation of 1 to k is divisible by three.
If k mod 3 == 1, then concatenation of 1 to k is not divisible by three.
If k mod 3 == 2, then it is a bit trickier. In this case, concatenation of 1 to k is divisible by three if the sum of k and the number before k (which evaluates to (k)+(k-1), which is 2k-1) is divisible by three.
Therefore, the final condition is:
(k mod 3 == 0) || ((k mod 3 == 2) && (2k-1 mod 3 == 0))
However, this can be even further simplified.
It turns out that k mod 3 can only equal 2 whenever 2k-1 mod 3 equals 0 and vice versa.
See simple graph below that shows cyclic pattern of this behavior.
Therefore, the formula can be further simplified just to:
(k mod 3 == 0) || (k mod 3 == 2)
Or, even more simply:
(k mod 3 != 1)
I realize answerer already provided this answer so I don't expect this to be the accepted answer, just giving a more thorough mathematical explanation.
A number is divisible by three if the sum of its digits is divisible by three (see here). Therefore, there is no need to "construct" your number, you need simply add the digits of the individual numbers. Thus for your 15 case, you do not need to "construct" 123456789101112131415, you just need to sum all of the digits in [1, 2, 3, 4, ... 14, 15].
This is simpler than it sounds because the problem only needs to check numbers of a very specific format: 12345789101112131415…k. You can use Gauss's method to quickly get the sum of the numbers 1 to k and then check if that sum is divisible by three using the usual methods. The code for that is:
'NO' if (k*(k+1)/2)%3 else 'YES'
If you look at the pattern that occurs as k increases (NO, YES, YES, NO, YES, YES, ...), you don't even need the multiplication or division. In short, all you need is:
'YES' if (k-1)%3 else 'NO'
Here is Python code which reads integers from a file and, if it wouldn't take too long also checks the answer the hard way so you can see that it is right. (Python numbers can be infinitely long, so you don't need to worry about overflow):
#!/usr/bin/python3
# Read integers from stdin, convert each int to a triangular number
# and output YES (or NO) if it is divisible by 3.
def sumgauss(x):
'''Return the sum from 1 to x using Gauss's shortcut'''
return (x*(x+1)/2)
def triangle(n):
'''Given an integer n, return a string with all the integers
from 1 to n concatenated. E.g., 15 -> 123456789101112131415'''
result=""
for t in range(1, k+1):
result+=str(t)
return result
import sys
for k in sys.stdin.readlines():
k=int(k)
print ( 'YES' if (k-1)%3 else 'NO', end='')
# If it wouldn't take too long, double check by trying it the hard way
if k<100000:
kstr=triangle(k)
print("\t// %s modulo 3 is %d" % (kstr, int(kstr)%3))
else:
print('\t// 123456789101112131415...%d%d%d modulo 3 is %d' %
tuple([k-2, k-1, k, sumgauss(k)%3]))
Speaking of Gauss's shortcut for summation, this problem seems a lot like a homework assignment. (Gauss invented it as a student when a teacher was trying to get the class out of his hair for a while by making them add up the numbers from 1 to 100.) If this is indeed a class assignment, please make sure the teacher knows to give the A to me and stackoverflow. Thanks!
Sample output:
$ cat data
2
6
15
130000000
130000001
$ ./k3.py < data
YES // 12 modulo 3 is 0
YES // 123456 modulo 3 is 0
YES // 123456789101112131415 modulo 3 is 0
NO // 123456789101112131415...129999998129999999130000000 modulo 3 is 1
YES // 123456789101112131415...129999999130000000130000001 modulo 3 is 0
The first 32 triangular numbers:
$ seq 32 | ./k3.py
NO // 1 modulo 3 is 1
YES // 12 modulo 3 is 0
YES // 123 modulo 3 is 0
NO // 1234 modulo 3 is 1
YES // 12345 modulo 3 is 0
YES // 123456 modulo 3 is 0
NO // 1234567 modulo 3 is 1
YES // 12345678 modulo 3 is 0
YES // 123456789 modulo 3 is 0
NO // 12345678910 modulo 3 is 1
YES // 1234567891011 modulo 3 is 0
YES // 123456789101112 modulo 3 is 0
NO // 12345678910111213 modulo 3 is 1
YES // 1234567891011121314 modulo 3 is 0
YES // 123456789101112131415 modulo 3 is 0
NO // 12345678910111213141516 modulo 3 is 1
YES // 1234567891011121314151617 modulo 3 is 0
YES // 123456789101112131415161718 modulo 3 is 0
NO // 12345678910111213141516171819 modulo 3 is 1
YES // 1234567891011121314151617181920 modulo 3 is 0
YES // 123456789101112131415161718192021 modulo 3 is 0
NO // 12345678910111213141516171819202122 modulo 3 is 1
YES // 1234567891011121314151617181920212223 modulo 3 is 0
YES // 123456789101112131415161718192021222324 modulo 3 is 0
NO // 12345678910111213141516171819202122232425 modulo 3 is 1
YES // 1234567891011121314151617181920212223242526 modulo 3 is 0
YES // 123456789101112131415161718192021222324252627 modulo 3 is 0
NO // 12345678910111213141516171819202122232425262728 modulo 3 is 1
YES // 1234567891011121314151617181920212223242526272829 modulo 3 is 0
YES // 123456789101112131415161718192021222324252627282930 modulo 3 is 0
NO // 12345678910111213141516171819202122232425262728293031 modulo 3 is 1
YES // 1234567891011121314151617181920212223242526272829303132 modulo 3 is 0
Actually the answer is pretty straight forward, if the sum of the digits divisible by three then the number is also divisible by 3.
string ans=(((1 + num) * num) / 2) % 3 == 0 ? "YES" : "NO";
according to the problem sum of digit can be considered as sum of numbers from 1 to n, sum=(n*(n+1))/2
*Make sure you divide the whole thing by 2
Another approach:
string ans=n % 3 !=1 ? "YES" : "NO";
You can prove that if n or n-2 is divisible by 3, then the sum up to n is divisible by 3 (e.g., in your case sum(1...8), sum(1..9), sum(1..11), etc.).

Find all numbers only divisible by 3, 5 and 7

I was asked on an interview to find all numbers only divisible by 3, 5 and 7. I purposed we can make check like
if (num%3==0 || num%5==0 || num%7==0)
return true
else
return false.
But in this case if we have 6 it will pass the test but its also divisible by 2 so this doesn't work. Can you purpose something?
I am using java. Find mean to check if some number is divisible only to this number
I would approach this by removing all of the factors of 3, 5, and 7 from the original number, and seeing what's left.
while(num % 3 == 0)
{
num = num / 3;
}
while(num % 5 == 0)
{
num = num / 5;
}
while(num % 7 == 0)
{
num = num / 7;
}
return (num == 1);
I won't give you a Java algorithm, as it should be fairly easy to implement.
You can just:
1. check if (n%3 == 0)
2. if it is, set n /= 3 and repeat step 1.
3. do the same for the number 5 and 7
4. now if n != 1, return false, else return true
In a Java algorithm:
// n is some random natural number
if (n == 1 || n == 0)
return false
while (!n%3)
{
n /= 3;
}
while (!n%5)
{
n /= 5;
}
while (!n%7)
{
n /= 7;
}
if (n == 1)
{
return true;
}
else
{
return false;
}
It's not the best syntax, I'm just giving an straight-forward implementation of the algorithm presented above.
We first note that 1 is a member of the set. Although it is not divisible by 3, 5 or 7, neither is it divisible by any number other than 3, 5 or 7, so we will say that 1 is in the set. This conforms to the mathematical definition of the set { x = 3i · 5j · 7k | i, j, k ≥ 0 }.
One method is to count from 1, adding 2 at each step, and checking if the number is divisible only by 3, 5 and 7. That's slow because it does a lot of work that immediately gets discarded, since there are many fewer numbers divisible only by 3, 5 and 7 than there are odd numbers.
A better approach is to generate the desired numbers directly, by induction. The number 1 is in the set, and for any x in the set, so are 3 x, 5 x and 7 x. So the algorithm to generate all numbers divisible only by 3, 5 and 7, in order, is:
1. Initialize a priority queue with the number 1.
2. Pop the smallest number in the priority queue, call it x.
3. Add 3x, 5x and 7x to the priority queue.
4. Output x as the next integer in the set.
5. If you want more output, go to Step 2.
6. Halt.
I implemented both algorithms; you can see them at http://ideone.com/YwnAQ8. The brute-force method takes a little over ten seconds to find the 203 members of the 3,5,7 set less than a million; the priority queue does the same calculation in a hundredth of a second, a thousand times faster. The priority queue implementation used there is explained at my blog. You can also see the set of 3,5,7 numbers at OEIS.

Resources