Codility K-Sparse Test **Spoilers** - aptitude

Have you tried the latest Codility test?
I felt like there was an error in the definition of what a K-Sparse number is that left me confused and I wasn't sure what the right way to proceed was. So it starts out by defining a K-Sparse Number:
In the binary number "100100010000" there are at least two 0s between
any two consecutive 1s. In the binary number "100010000100010" there
are at least three 0s between any two consecutive 1s. A positive
integer N is called K-sparse if there are at least K 0s between any
two consecutive 1s in its binary representation. (My emphasis)
So the first number you see, 100100010000 is 2-sparse and the second one, 100010000100010, is 3-sparse. Pretty simple, but then it gets down into the algorithm:
Write a function:
class Solution { public int sparse_binary_count(String S,String T,int K); }
that, given:
string S containing a binary representation of some positive integer A,
string T containing a binary representation of some positive integer B,
a positive integer K.
returns the number of K-sparse integers within the range [A..B] (both
ends included)
and then states this test case:
For example, given S = "101" (A = 5), T = "1111" (B=15) and K=2, the
function should return 2, because there are just two 2-sparse integers
in the range [5..15], namely "1000" (i.e. 8) and "1001" (i.e. 9).
Basically it is saying that 8, or 1000 in base 2, is a 2-sparse number, even though it does not have two consecutive ones in its binary representation. What gives? Am I missing something here?

Tried solving that one. The assumption that the problem makes about binary representations of "power of two" numbers being K sparse by default is somewhat confusing and contrary.
What I understood was 8-->1000 is 2 power 3 so 8 is 3 sparse. 16-->10000 2 power 4 , and hence 4 sparse.
Even we assume it as true , and if you are interested in below is my solution code(C) for this problem. Doesn't handle some cases correctly, where there are powers of two numbers involved in between the two input numbers, trying to see if i can fix that:
int sparse_binary_count (const string &S,const string &T,int K)
{
char buf[50];
char *str1,*tptr,*Sstr,*Tstr;
int i,len1,len2,cnt=0;
long int num1,num2;
char *pend,*ch;
Sstr = (char *)S.c_str();
Tstr = (char *)T.c_str();
str1 = (char *)malloc(300001);
tptr = str1;
num1 = strtol(Sstr,&pend,2);
num2 = strtol(Tstr,&pend,2);
for(i=0;i<K;i++)
{
buf[i] = '0';
}
buf[i] = '\0';
for(i=num1;i<=num2;i++)
{
str1 = tptr;
if( (i & (i-1))==0)
{
if(i >= (pow((float)2,(float)K)))
{
cnt++;
continue;
}
}
str1 = myitoa(i,str1,2);
ch = strstr(str1,buf);
if(ch == NULL)
continue;
else
{
if((i % 2) != 0)
cnt++;
}
}
return cnt;
}
char* myitoa(int val, char *buf, int base){
int i = 299999;
int cnt=0;
for(; val && i ; --i, val /= base)
{
buf[i] = "0123456789abcdef"[val % base];
cnt++;
}
buf[i+cnt+1] = '\0';
return &buf[i+1];
}

There was an information within the test details, showing this specific case. According to this information, any power of 2 is considered K-sparse for any K.
You can solve this simply by binary operations on integers. You are even able to tell, that you will find no K-sparse integers bigger than some specific integer and lower than (or equal to) integer represented by T.
As far as I can see, you must pay also a lot of attention to the performance, as there are sometimes hundreds of milions of integers to be checked.
My own solution, written in Python, working very efficiently even on large ranges of integers and being successfully tested for many inputs, has failed. The results were not very descriptive, saying it does not work as required within question (although it meets all the requirements in my opinion).

/////////////////////////////////////
solutions with bitwise operators:
no of bits per int = 32 on 32 bit system,check for pattern (for K=2,
like 1001, 1000) in each shift and increment the count, repeat this
for all numbers in range.
///////////////////////////////////////////////////////
int KsparseNumbers(int a, int b, int s) {
int nbits = sizeof(int)*8;
int slen = 0;
int lslen = pow(2, s);
int scount = 0;
int i = 0;
for (; i < s; ++i) {
slen += pow(2, i);
}
printf("\n slen = %d\n", slen);
for(; a <= b; ++a) {
int num = a;
for(i = 0 ; i < nbits-2; ++i) {
if ( (num & slen) == 0 && (num & lslen) ) {
scount++;
printf("\n Scount = %d\n", scount);
break;
}
num >>=1;
}
}
return scount;
}
int main() {
printf("\n No of 2-sparse numbers between 5 and 15 = %d\n", KsparseNumbers(5, 15, 2));
}

Related

Counting the number

I have got a code that generates all possible correct strings of balanced brackets. So if the input is n = 4 there should be 4 brackets in the string and thus the answers the code will give are: {}{} and
{{}}.
Now, what I would like to do is print the number of possible strings. For example, for n = 4 the outcome would be 2.
Given my code, is this possible and how would I make that happen?
Just introduce a counter.
// Change prototype to return the counter
int findBalanced(int p,int n,int o,int c)
{
static char str[100];
// The counter
static int count = 0;
if (c == n) {
// Increment it on every printout
count ++;
printf("%s\n", str);
// Just return zero. This is not used anyway and will give
// Correct result for n=0
return 0;
} else {
if (o > c) {
str[p] = ')';
findBalanced(p + 1, n, o, c + 1);
}
if (o < n) {
str[p] = '(';
findBalanced(p + 1, n, o + 1, c);
}
}
// Return it
return count;
}
What you're looking for is the n-th Catalan number. You'll need to implement binomial coefficient to calculate it, but that's pretty much it.

Negative Number, Positive Numbers, pointers, and characters

I'm trying to figure out this program; it is an averaging program and it requires user input of:
p 4 p 7 p 2 n 1 e sum 12 average: 4
The user enters whether he was a positive number or negative.
We are asked to use int real_number(int* value) and make value a pointer to where the input value will be stored.
So far I have:
#include <stdio.h>
int real_number(int* value);
int real_number(int* value)
{
char *n = "negative";
char *p = "positive";
char *e = "end";
int *sum = 0;
int *avg = 0;
while(sum = 0)
{
printf(" \n");
scanf("%d", &sum);
}
}
int main()
{
}
I know it is not much, but I'm lost; any ideas?
Firstly you have to read characters while your character is different "e". Secondly you have an infinite cicle. In while loop modify the condition with == .
You need to have a counter to count how many numbers you entered. While you read numbers you must add these numbers to sum and count one.
Finally, in the output you write sum/counter

What is the most efficient way to calculate the least common multiple of two integers?

What is the most efficient way to calculate the least common multiple of two integers?
I just came up with this, but it definitely leaves something to be desired.
int n=7, m=4, n1=n, m1=m;
while( m1 != n1 ){
if( m1 > n1 )
n1 += n;
else
m1 += m;
}
System.out.println( "lcm is " + m1 );
The least common multiple (lcm) of a and b is their product divided by their greatest common divisor (gcd) ( i.e. lcm(a, b) = ab/gcd(a,b)).
So, the question becomes, how to find the gcd? The Euclidean algorithm is generally how the gcd is computed. The direct implementation of the classic algorithm is efficient, but there are variations that take advantage of binary arithmetic to do a little better. See Knuth's "The Art of Computer Programming" Volume 2, "Seminumerical Algorithms" § 4.5.2.
Remember
The least common multiple is the least whole number that is a multiple of each of two or more numbers.
If you are trying to figure out the LCM of three integers, follow these steps:
**Find the LCM of 19, 21, and 42.**
Write the prime factorization for each number. 19 is a prime number. You do not need to factor 19.
21 = 3 × 7
42 = 2 × 3 × 7
19
Repeat each prime factor the greatest number of times it appears in any of the prime factorizations above.
2 × 3 × 7 × 19 = 798
The least common multiple of 21, 42, and 19 is 798.
I think that the approach of "reduction by the greatest common divider" should be faster. Start by calculating the GCD (e.g. using Euclid's algorithm), then divide the product of the two numbers by the GCD.
Best solution in C++ below without overflowing
#include <iostream>
using namespace std;
long long gcd(long long int a, long long int b){
if(b==0)
return a;
return gcd(b,a%b);
}
long long lcm(long long a,long long b){
if(a>b)
return (a/gcd(a,b))*b;
else
return (b/gcd(a,b))*a;
}
int main()
{
long long int a ,b ;
cin>>a>>b;
cout<<lcm(a,b)<<endl;
return 0;
}
First of all, you have to find the greatest common divisor
for(int i=1; i<=a && i<=b; i++) {
if (i % a == 0 && i % b == 0)
{
gcd = i;
}
}
After that, using the GCD you can easily find the least common multiple like this
lcm = a / gcd * b;
I don't know whether it is optimized or not, but probably the easiest one:
public void lcm(int a, int b)
{
if (a > b)
{
min = b;
max = a;
}
else
{
min = a;
max = b;
}
for (i = 1; i < max; i++)
{
if ((min*i)%max == 0)
{
res = min*i;
break;
}
}
Console.Write("{0}", res);
}
Here is a highly efficient approach to find the LCM of two numbers in python.
def gcd(a, b):
if min(a, b) == 0:
return max(a, b)
a_1 = max(a, b) % min(a, b)
return gcd(a_1, min(a, b))
def lcm(a, b):
return (a * b) // gcd(a, b)
Using Euclidean algorithm to find gcd and then calculating the lcm dividing a by the product of gcd and b worked for me.
int euclidgcd(int a, int b){
if(b==0)
return a;
int a_rem = a % b;
return euclidgcd(b, a_rem);
}
long long lcm(int a, int b) {
int gcd=euclidgcd(a, b);
return (a/gcd*b);
}
int main() {
int a, b;
std::cin >> a >> b;
std::cout << lcm(a, b) << std::endl;
return 0;
}
Take successive multiples of the larger of the two numbers until the result is a multiple of the smaller.
this might work..
public int LCM(int x, int y)
{
int larger = x>y? x: y,
smaller = x>y? y: x,
candidate = larger ;
while (candidate % smaller != 0) candidate += larger ;
return candidate;
}
C++ template. Compile time
#include <iostream>
const int lhs = 8, rhs = 12;
template<int n, int mod_lhs=n % lhs, int mod_rhs=n % rhs> struct calc {
calc() { }
};
template<int n> struct calc<n, 0, 0> {
calc() { std::cout << n << std::endl; }
};
template<int n, int mod_rhs> struct calc<n, 0, mod_rhs> {
calc() { }
};
template<int n, int mod_lhs> struct calc <n, mod_lhs, 0> {
calc() { }
};
template<int n> struct lcm {
lcm() {
lcm<n-1>();
calc<n>();
}
};
template<> struct lcm<0> {
lcm() {}
};
int main() {
lcm<lhs * rhs>();
}
Euclidean GCD code snippet
int findGCD(int a, int b) {
if(a < 0 || b < 0)
return -1;
if (a == 0)
return b;
else if (b == 0)
return a;
else
return findGCD(b, a % b);
}
Product of 2 numbers is equal to LCM * GCD or HCF. So best way to find LCM is to find GCD and divide the product with GCD. That is, LCM(a,b) = (a*b)/GCD(a,b).
There is no way more efficient than using a built-in function!
As of Python 3.8 lcm() function has been added in math library. And can be called with folowing signature:
math.lcm(*integers)
Returns the least common multiple of the specified integer arguments. If all arguments are nonzero, then the returned value is the smallest positive integer that is a multiple of all arguments. If any of the arguments is zero, then the returned value is 0. lcm() without arguments returns 1.
Extending #John D. Cook answer that is also marked answer for this question. ( https://stackoverflow.com/a/3154503/13272795), I am sharing algorithm to find LCM of n numbers, it maybe LCM of 2 numbers or any numbers. Source for this code is this
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
// Returns LCM of array elements
ll findlcm(int arr[], int n)
{
// Initialize result
ll ans = arr[0];
// ans contains LCM of arr[0], ..arr[i]
// after i'th iteration,
for (int i = 1; i < n; i++)
ans = arr[i] * ans/gcd(arr[i], ans);
return ans;
}
Since we know the mathematic property which states that "product of LCM and HCF of any two numbers is equal to the product of the two numbers".
lets say X and Y are two integers,
then
X * Y = HCF(X, Y) * LCM(X, Y)
Now we can find LCM by knowing the HCF, which we can find through Euclidean Algorithm.
LCM(X, Y) = (X * Y) / HCF(X, Y)
Hope this will be efficient.
import java.util.*;
public class Hello {
public static int HCF(int X, int Y){
if(X == 0)return Y;
return HCF(Y%X, X);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int X = scanner.nextInt(), Y = scanner.nextInt();
System.out.print((X * Y) / HCF(X, Y));
}
}
Yes, there are numerous way to calculate LCM such as using GCD (HCF).
You can apply prime decomposition such as (optimized/naive) Sieve Eratosthenes or find factor of prime number to compute GCD, which is way more faster than calculate LCM directly. Then as all said above, LCM(X, Y) = (X * Y) / GCD(X, Y)
I googled the same question, and found this Stackoverflow page,
however I come up with another simple solution using python
def find_lcm(numbers):
h = max(numbers)
lcm = h
def check(l, numbers):
remainders = [ l%n==0 for n in numbers]
return all(remainders)
while (check(lcm, numbers) == False):
lcm = lcm + h
return lcm
for
numbers = [120,150,135,225]
it will return 5400
numbers = [120,150,135,225]
print(find_lcm(numbers)) # will print 5400

Mathematically Find Max Value without Conditional Comparison

----------Updated ------------
codymanix and moonshadow have been a big help thus far. I was able to solve my problem using the equations and instead of using right shift I divided by 29. Because with 32bits signed 2^31 = overflows to 29. Which works!
Prototype in PHP
$r = $x - (($x - $y) & (($x - $y) / (29)));
Actual code for LEADS (you can only do one math function PER LINE!!! AHHHH!!!)
DERIVDE1 = IMAGE1 - IMAGE2;
DERIVED2 = DERIVED1 / 29;
DERIVED3 = DERIVED1 AND DERIVED2;
MAX = IMAGE1 - DERIVED3;
----------Original Question-----------
I don't think this is quite possible with my application's limitations but I figured it's worth a shot to ask.
I'll try to make this simple. I need to find the max values between two numbers without being able to use a IF or any conditional statement.
In order to find the the MAX values I can only perform the following functions
Divide, Multiply, Subtract, Add, NOT, AND ,OR
Let's say I have two numbers
A = 60;
B = 50;
Now if A is always greater than B it would be simple to find the max value
MAX = (A - B) + B;
ex.
10 = (60 - 50)
10 + 50 = 60 = MAX
Problem is A is not always greater than B. I cannot perform ABS, MAX, MIN or conditional checks with the scripting applicaiton I am using.
Is there any way possible using the limited operation above to find a value VERY close to the max?
finding the maximum of 2 variables:
max = a-((a-b)&((a-b)>>31))
where >> is bitwise right-shift (also called SHR or ASR depeding on signedness).
Instead of 31 you use the number of bits your numbers have minus one.
I guess this one would be the most simplest if we manage to find difference between two numbers (only the magnitude not sign)
max = ((a+b)+|a-b|)/2;
where |a-b| is a magnitude of difference between a and b.
If you can't trust your environment to generate the appropriate branchless operations when they are available, see this page for how to proceed. Note the restriction on input range; use a larger integer type for the operation if you cannot guarantee your inputs will fit.
Solution without conditionals. Cast to uint then back to int to get abs.
int abs (a) { return (int)((unsigned int)a); }
int max (a, b) { return (a + b + abs(a - b)) / 2; }
int max3 (a, b, c) { return (max(max(a,b),c); }
Using logical operations only, short circuit evaluation and assuming the C convention of rounding towards zero, it is possible to express this as:
int lt0(int x) {
return x && (!!((x-1)/x));
}
int mymax(int a, int b) {
return lt0(a-b)*b+lt0(b-a)*a;
}
The basic idea is to implement a comparison operator that will return 0 or 1. It's possible to do a similar trick if your scripting language follows the convention of rounding toward the floor value like python does.
function Min(x,y:integer):integer;
Var
d:integer;
abs:integer;
begin
d:=x-y;
abs:=d*(1-2*((3*d) div (3*d+1)));
Result:=(x+y-abs) div 2;
end;
Hmmm. I assume NOT, AND, and OR are bitwise? If so, there's going to be a bitwise expression to solve this. Note that A | B will give a number >= A and >= B. Perhaps there's a pruning method for selecting the number with the most bits.
To extend, we need the following to determine whether A (0) or B (1) is greater.
truth table:
0|0 = 0
0|1 = 1
1|0 = 0
1|1 = 0
!A and B
therefore, will give the index of the greater bit. Ergo, compare each bit in both numbers, and when they are different, use the above expression (Not A And B) to determine which number was greater. Start from the most significant bit and proceed down both bytes. If you have no looping construct, manually compare each bit.
Implementing "when they are different":
(A != B) AND (my logic here)
try this, (but be aware for overflows)
(Code in C#)
public static Int32 Maximum(params Int32[] values)
{
Int32 retVal = Int32.MinValue;
foreach (Int32 i in values)
retVal += (((i - retVal) >> 31) & (i - retVal));
return retVal;
}
You can express this as a series of arithmetic and bitwise operations, e.g.:
int myabs(const int& in) {
const int tmp = in >> ((sizeof(int) * CHAR_BIT) - 1);
return tmp - (in ^ tmp(;
}
int mymax(int a, int b) {
return ((a+b) + myabs(b-a)) / 2;
}
//Assuming 32 bit integers
int is_diff_positive(int num)
{
((num & 0x80000000) >> 31) ^ 1; // if diff positive ret 1 else 0
}
int sign(int x)
{
return ((num & 0x80000000) >> 31);
}
int flip(int x)
{
return x ^ 1;
}
int max(int a, int b)
{
int diff = a - b;
int is_pos_a = sign(a);
int is_pos_b = sign(b);
int is_diff_positive = diff_positive(diff);
int is_diff_neg = flip(is_diff_positive);
// diff (a - b) will overflow / underflow if signs are opposite
// ex: a = INT_MAX , b = -3 then a - b => INT_MAX - (-3) => INT_MAX + 3
int can_overflow = is_pos_a ^ is_pos_b;
int cannot_overflow = flip(can_overflow);
int res = (cannot_overflow * ( (a * is_diff_positive) + (b *
is_diff_negative)) + (can_overflow * ( (a * is_pos_a) + (b *
is_pos_b)));
return res;
}
This is my implementation using only +, -, *, %, / operators
using static System.Console;
int Max(int a, int b) => (a + b + Abs(a - b)) / 2;
int Abs(int x) => x * ((2 * x + 1) % 2);
WriteLine(Max(-100, -2) == -2); // true
WriteLine(Max(2, -100) == 2); // true
I just came up with an expression:
(( (a-b)-|a-b| ) / (2(a-b)) )*b + (( (b-a)-|b-a| )/(2(b-a)) )*a
which is equal to a if a>b and is equal to b if b>a
when a>b:
a-b>0, a-b = |a-b|, (a-b)-|a-b| = 0 so the coeficcient for b is 0
b-a<0, b-a = -|b-a|, (b-a)-|b-a| = 2(b-a)
so the coeficcient for a is 2(b-a)/2(b-a) which is 1
so it would ultimately return 0*b+1*a if a is bigger and vice versa
Find MAX between n & m
MAX = ( (n/2) + (m/2) + ( ((n/2) - (m/2)) * ( (2*((n/2) - (m/2)) + 1) % 2) ) )
Using #define in c:
#define MAX(n, m) ( (n/2) + (m/2) + ( ((n/2) - (m/2)) * ( (2*((n/2) - (m/2)) + 1) % 2) ) )
or
#define ABS(n) ( n * ( (2*n + 1) % 2) ) // Calculates abs value of n
#define MAX(n, m) ( (n/2) + (m/2) + ABS((n/2) - (m/2)) ) // Finds max between n & m
#define MIN(n, m) ( (n/2) + (m/2) - ABS((n/2) - (m/2)) ) // Finds min between n & m
please look at this program.. this might be the best answer till date on this page...
#include <stdio.h>
int main()
{
int a,b;
a=3;
b=5;
printf("%d %d\n",a,b);
b = (a+b)-(a=b); // this line is doing the reversal
printf("%d %d\n",a,b);
return 0;
}
If A is always greater than B .. [ we can use] .. MAX = (A - B) + B;
No need. Just use: int maxA(int A, int B){ return A;}
(1) If conditionals are allowed you do max = a>b ? a : b.
(2) Any other method either use a defined set of numbers or rely on the implicit conditional checks.
(2a) max = a-((a-b)&((a-b)>>31)) this is neat, but it only works if you use 32 bit numbers. You can expand it arbitrary large number N, but the method will fail if you try to find max(N-1, N+1). This algorithm works for finite state automata, but not a Turing machine.
(2b) Magnitude |a-b| is a condition |a-b| = a-b>0 a-b : b-a
What about:
Square root is also a condition. Whenever c>0 and c^2 = d we have second solution -c, because (-c)^2 = (-1)^2*c^2 = 1*c^2 = d. Square root returns the greatest in the pair. I comes with a build in int max(int c1, int c2){return max(c1, c2);}
Without comparison operator math is very symmetric as well as limited in power. Positive and negative numbers cannot be distinguished without if of some sort.
It depends which language you're using, but the Ternary Operator might be useful.
But then, if you can't perform conditional checks in your 'scripting application', you probably don't have the ternary operator.
using System;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
float a = 101, b = 15;
float max = (a + b) / 2 + ((a > b) ? a - b : b - a) / 2;
}
}
}
#region GetMaximumNumber
/// <summary>
/// Provides method to get maximum values.
/// </summary>
/// <param name="values">Integer array for getting maximum values.</param>
/// <returns>Maximum number from an array.</returns>
private int GetMaximumNumber(params int[] values)
{
// Declare to store the maximum number.
int maximumNumber = 0;
try
{
// Check that array is not null and array has an elements.
if (values != null &&
values.Length > 0)
{
// Sort the array in ascending order for getting maximum value.
Array.Sort(values);
// Get the last value from an array which is always maximum.
maximumNumber = values[values.Length - 1];
}
}
catch (Exception ex)
{
throw ex;
}
return maximumNumber;
}
#endregion

Binary math

If I know the number number y and know that 2^x=y, how do I compute x?
Base 2 logarithm function:
log2(y)
which is equivalent to:
log(y) / log(2)
for arbitrary base.
And in case you don't have a log function handy, you can always see how many times you must divide y by 2 before it becomes 1. (This assumes x is positive and an integer.)
If you are sure that it is a power of 2, then you can write a loop and right shift the number until you get a 1. The number of times the loop ran will be the value of x.
Example code:
int power(int num)
{
if(0 == num)
{
return 0;
}
int count = 0;
do
{
++count;
num = num >> 1;
}while(! (num & 1) && num > 0);
return count;
}
If x is a positive integer, then, following code will be more efficient..
unsigned int y; // You know the number y for which you require x..
unsigned int x = 0;
while (y >>= 1)
{
x++;
}
x is the answer!

Resources