Google Interview Question for Software Engineer / Developers


Country: United States
Interview Type: In-Person




Comment hidden because of low score. Click to expand.
1
of 5 vote

The first 10 numbers contain 9 numbers without 4.
The first 100 numbers contain (9*9) numbers without 4.
The first 1000 numbers contain (9*9*9) numbers without 4... and so on.
Store the number of numbers without 4 against each power of 10. Maybe in an array.

Split N into its powers of 10 like:
a*10^x + b*10^(x-1) + c*10^(x-2)+... and so on

Use the above array to calculate the total number, but beware of any 4s in a, b, c, etc.

So the total becomes:
a*(number of 4less numbers in first 10^x) + b*(number of 4less numbers in first 10^(x-1)) + ... and so on.

- Anonymous January 30, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I am finding it hard to understand the solution. Please explain.
If N = 96:
a = 9, b = 6 ===> 9 * 10 + 6
So total = a * 9 + b * 0 = 9 * 9 + 0 = 81 (incorrect?)

- Anon February 05, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

it is not 9 * 9 + 0, it is a*9^1 + b*9^0 and so it is (9-1)*9+ (6-1)*1 = 72 + 5 = 77

- Swathi February 06, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

there is a flaw in the algorithm.
if N = 40:
(4-1) * 9 + 0 * 1 = 27, which is not the correct answer...

- arthur February 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
1
of 3 vote

import java.util.*;

public class CountFours
{
    public CountFours()
    {
    }

    /**
     * Recursively count how many numbers below n don't have a 4 in decimal
     * representation.
     */
    public int count(int n)
    {
        // base case when we have single digit
        if (n < 4) {
            return n;
        }
        
        if (n >= 4 && n <=9) {
            return n - 1;
        }

        // otherwise for multi digit numbers, compute the order of magnitude
        int orderPower = (int) Math.floor(Math.log10(n));
        // actual number order 
        int order = (int) Math.pow(10, orderPower);

        // the first digit of the number n
        int d = (int) n / order;

        // the rest of the number when first digit is removed
        int remainder = n % order;

        // if the number starts with 4, then all of the remainder should not
        // be counted. Therefore, the count value is the same as number that
        // starts with d-1 as first digit and all the rest of digits are 9
        if (d == 4) {
            // remainder is all 9s
            remainder = (int) Math.pow(10, orderPower) - 1;
        }

        // compute the power of 9
        int ninePower = (int) Math.pow(9, orderPower);

        if (d < 4) {
            return d * ninePower + count(remainder);
        } else {
            return (d - 1) * ninePower + count(remainder);
        }
    }

    /**
     * Count number of times 4 appers in any number less than equal to
     * n by converting the numbers to string and comparing digits as chars.
     */
    public int naiveCount(int n)
    {
        int withoutFourCount = 0;

        for (int i = 1; i <= n; i++) {
            if (!containsFour(i)) {
                withoutFourCount++;
            }
        }

        return withoutFourCount;
    }

    /**
     * Check if the number contains 4 by converting the number to string,
     * walking through the string and looking for char '4'
     */
    public boolean containsFour(int n)
    {
        String value = String.valueOf(n);

        if (value.indexOf('4') != -1) {
            return true;
        }

        return false;
    }

    /**
     * Test recursive algorithm against naive algorithms for all numbers
     * up to n
     */
    public void test(int n) 
    {
        for (int i = 0; i <= n; i++) {
            if (naiveCount(i) != count(i)) {
                System.out.println("Recursive algorithm is wrong for n = "
                        + i);
                return;
            }
        }

        System.out.println("Passed for all numbers up to " + n);
    }

    /**
     * Print how many numbers below n do not contain 4
     */
    public void testCount(int n) 
    {
        System.out.println("For n = " + n + " there are " + count(n) 
                + " numbers that don't contain 4");
    }

    public static final void main(String args[])
    {
        CountFours app = new CountFours();
        app.test(10000);
        app.testCount(1000);
        app.testCount(Integer.MAX_VALUE);
    }
}

- Anonymous February 01, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Could you please explain how your decimal representation method works? I don't quite follow it.

- Guy February 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 votes

Sure, take a look at first 100 numbers and notice is that in each "decade" except the one that starts with 4 (i.e 40-49), has exactly 9 numbers that don't contain 4. Therefore, there are 9*9 numbers that don't contain 4 (9 decades, since the 40-49 do contain 4). Similarly, for hundreds from 100 - 1000. Each one except, 400-499 has 9*9 numbers without 4 in them and there are 9 of these hundreds. So the number of numbers without 4 below 1000 is 9*9*9 etc.

So, now we know how to calculate for orders of magnitude. 10, 100, 1000, 10 000 etc. But what if the number falls in between? In that case we have to look at most significant digit of the number n. There are 3 cases. If first digit is less than 4, then the count of numbers that don't contain 4 is most significant digit * 9^(order of magnitude of n) + the count for the remainder of the number (computed recursively).

If the number starts with 4, then it should not be counted, therefore the count is the same as the number 399...9 where there are order of magnitude of n - 1 digits 9.

And if the number starts with a digit d > 4 then the count is (d - 1) * 9 ^ (order of magnitude of n) + the count of the remainder of the number (again computed recursively). It is (d-1) because we don't include the 4xxxx towards the count since all those numbers contain 4.

- Super Mario February 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Super Mario: very good explanation.Keep it up.

- aka February 05, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 2 vote

I have found more efficient algorithm of this problem, it uses recursion。

#include<iostream>
using namespace std;

#define count(x, y) ((x) <= 4 && (y) >= 4 ? (y) - (x) : (y) - (x) + 1)

int calculate_num(int N)
{
    int m, r;
    int result;

    m = N / 10;
    if (m == 0) {
        return count(0, N);
    }
    result = 0;
    r = N % 10;
    if (r > 0) {
        result += count(0, r - 1) * calculate_num(m);
    }
    result += count(r, 9) * calculate_num(m - 1);
    return result;
}

int main(int argc, char **argv)
{
    int n;

    cin >> n;
    cout << calculate_num(n) - 1 << endl;
    return 0;
}

- ctang January 30, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

not sure if this is correct. I compared it to the brute force method and my own method and they do not agree.

- quoc.honza January 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Recursion works, but applied in a different way. The recursive approach deals with removing Most Significant Digits(MSD) one at a time in each recursive step and counting the number of numbers that don't include 4.

Suppose the given integer N has k digits - d1,d2,...,dk. There are 2 cases: d1 < 4 and d1>=4 and the recursion yields itself as:

1. For d1 < 4
f(d1,d2,...,dk) = d1 * (k-1)^9 + f(d2,d3,..,dk)

2. For d1 >= 4
f(d1,d2,...,dk) = (d1-1) * (k-1)^9 + f(d2,d3,..,dk)

Both can as well be combined to:
f(d1,d2,...,dk) = [(d1 - floor((d1)/4) - floor((d1)/8)) * (k-1)^9] + f(d2,d3,..,dk)

The base cases are:
f(d) = d, for d<4. [It could have been d+1, had the question not been asking for numbers *lesser* than the given number]

f(d) = d - 1, for d>=4 [It could have been d, had the question not been asking for numbers *lesser* than the given number]

- Murali Mohan January 31, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

A more optimized approach using recursion can be used:
C(k) : number of numbers of k digits that do not contain 4
N[k] : kth digit in the number N
f(k) : for a given digit k return the number of digits possible for that place (unit, tens, hunderds) e.g if k = 3 then we have 4 options 0,1,2,3 and if k = 5 then we have 5 options 0,1,2,3,5
The recursion equation will be
C(k+1) = (f(N[k]) -1)*(9^k) + C(k)
Base case
C(1) = f(N[1])

Note: This solution includes 0 as a number in its answer

- kr.neerav January 30, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Runs in constant time. Uses recursion and written in C++

int countExclude4(int n) {
	return (n - countContain4(n-1));
}

int countContain4(int n) {

	int factor = -1;
	int k = n;

	// Reached the unit digit
	if (k < 4) return 0;
	else if (k < 10) return 1;

	// Find the highest factor of n
	while (k > 0) {
		factor++;
		k /= 10;
	}

	// Find the number of numbers containing 4 in n/10
	int prevMax = 0;
	for (int i = 0; i < factor; ++i)
		prevMax = (prevMax * 9) + (int)pow(10, i);

	int quotient = n / (int)pow(10,factor);
	int remainder = n % (int)pow(10,factor);

	int sum = 0;

	// e.g 4 in 45623
	if (quotient == 4)
		sum = quotient * prevMax + (remainder + 1);
	// e.g 1 in 10000
	else if (quotient == 1 && remainder == 0)
		sum = prevMax;
	// e.g 2 in 273
	else if (quotient < 4)
		sum = quotient * prevMax + countContain4(remainder);
	// e.g 7 in 720324
	else
		sum = (quotient-1) * prevMax + (int)pow(10, factor) + countContain4(remainder);

	return sum;

}

- quoc.honza January 30, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

class Googleque
def initialize(val)
@n=val
@array= Array.new
@i=0
@count=0
if @n <= 0 then
puts " No Positive numbers present"
else
logic
end
end

def logic
for i in 0..@n
calculation(i)    # Applying calculation logic for every number until 'N'
i=i+1
end
puts "Total no of positive integers which does not contain '4' it are.\n"
puts "#{@n-@count}"
end

def calculation(i)
@i= 0

until i==0
@array[@i]= i%10
i=i/10
@i=@i+1
end
if @array.include?(4) then
@count = @count+1
end

end

end

puts "Enter your number"
val= gets.to_i
ob= Googleque.new(val)

- Rahul sambari January 31, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

This can be solved by a recursive approach that works by removing Most Significant Digits(MSD) one at a time in each recursive step and counting the number of numbers that don't include 4.

Suppose the given integer N has k digits - d1,d2,...,dk. There are 2 cases: d1 < 4 and d1>=4 and the recursion yields itself as:

1. For d1 < 4
f(d1,d2,...,dk) = d1 * (k-1)^9 + f(d2,d3,..,dk)

2. For d1 >= 4
f(d1,d2,...,dk) = (d1-1) * (k-1)^9 + f(d2,d3,..,dk)

Both can as well be combined to:
f(d1,d2,...,dk) = [(d1 - floor((d1)/4) - floor((d1)/8)) * (k-1)^9] + f(d2,d3,..,dk)

The base cases are:
f(d) = d, for d<4. [It could have been d+1, had the question not been asking for numbers *lesser* than the given number]

f(d) = d - 1, for d>=4 [It could have been d, had the question not been asking for numbers *lesser* than the given number]

- Murali Mohan January 31, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

(k-1)^9 and 9^(k-1) are not the same thing. You want 9^(k-1).

Also, your algorithm does not work correctly for numbers starting with 4 i.e. when d1 = 4.

E.g. for n between 40 and 49, the correct answer is 35, but your algorithm gives:

40 -> 27
41 -> 28
42 -> 29
43 -> 30
44 -> 30
45 -> 31
46 -> 32
47 -> 33
48 -> 34
49 -> 35 (this is actually correct).

So, basically you need a special case for when d1=4.

- Super Mario February 01, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

The special case when d1 = 4 needs to be handled differently is a brilliant catch @Super Mario. Cheers! Admit that I have missed it and needs to be handled differently. It should also rather have been 9^(k-1) than (k-1)^9 - sorry for the lack of attention on my part while typing the answer. Thanks for the corrections!

- Murali Mohan February 01, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes
The corrected equations are: {{{ 1. For d1 < 4 f(d1,d2,...,dk) = d1 * 9^(k-1) + f(d2,d3,..,dk) 2. For d1 >= 4 f(d1,d2,...,dk) = ceil(abs((4-d1)/5)) * (d1-1) * 9^(k-1) + f(d2,d3,..,dk) The above 2 equations combined: f(d1,d2,...,dk) = ceil(abs((4-d1)/5)) * (d1 - floor(d1/4) - floor(d1/8)) * 9^(k-1) + f(d2,d3,..,dk) - Murali Mohan February 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

The corrected equations are:

1. For d1 < 4 f(d1,d2,...,dk) = d1 * 9^(k-1) + f(d2,d3,..,dk) 

2. For d1 >= 4 f(d1,d2,...,dk) = ceil(abs((4-d1)/5)) * (d1-1) * 9^(k-1) + f(d2,d3,..,dk) 

The above 2 equations combined: 
f(d1,d2,...,dk) = ceil(abs((4-d1)/5)) * (d1 - floor(d1/4) - floor(d1/8)) * 9^(k-1) + f(d2,d3,..,dk)

- Murali Mohan February 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Time complexity of my solution is O(k) and it's space complexity is O(k) too (for using system stack in recursion), where k = log_base_10(N).

- Murali Mohan February 02, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

def nine_based_numeral_system(max)
    sw  = count = 0
    pos = max.to_s.length

    max.to_s.scan(/./).each do |number|
      number = number.to_i
      if number == @filter && sw == 0
        number -= 1                     # As will be the same result 4xx than 399
        sw      = 1
      elsif sw == 1
        number = 9                      # As it has a previous 4 so this is the same as 3xxx
      elsif number > @filter
        number -= 1
      end
      pos   -= 1
      count += number * 9 ** pos
    end
    count -= 1
  end
end

}

- Adrià Cidre January 31, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Written in C#

int N = int.Parse(Console.ReadLine());
            string[] dizi = new string[N];
            int counter = 0;
            for (int i = 0; i < N; i++)
            {
                bool isContainFour = false;
                dizi[i] = i.ToString();
                for (int j = 0; j < dizi[i].Length; j++)
                {
                    if (dizi[i][j] == '4')
                    {
                        isContainFour = true;
                    }
                }
                if (isContainFour == false)
                {
                    counter++;
                    //possible to write those numbers
                    //Console.WriteLine(dizi[i]);
                }
            }
            Console.WriteLine(counter);
            Console.ReadLine();

- Anonymous January 31, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

void countNot4(unsigned int N)
{
	int count =0;
	
	for(int i=1;i<N;i++)
	{
		bool isFour = false;
		int k=0;
		char a[25];
		itoa(i,a,10);
		while(a[k]!='\0')
		{
			if(a[k]=='4')
			{
				isFour = true;
				break;
			}
			k++;
		}
		if(!isFour)
			count++;
	}
	cout << "\n Count is .." << count;
}

- Anonymous February 01, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class NonFour {        
    public long getNonFourCount(long N) {
        int numberOfDigits = (int)Math.floor(Math.log10(N)) + 1;
        int fisrtDigit = (int)(N / (long)Math.pow(10, numberOfDigits-1));
        
        long count =0;
        if(N<10) {
            for(int j = 0; j<=N; j++) {
                if(j!=4)
                    count++;
            }
            return count;
        }
        
        long pow = (long)Math.pow(9, numberOfDigits-1);
        count = pow;
        
        for(int i =1; i< fisrtDigit; i++) {
            if(i != 4) {
                count += pow;
            }
        }
        
        N = N % (long)Math.pow(10, numberOfDigits-1);
        return count + (N==0? 1 : getNonFourCount(N));
    }
    
}

- Neeraj February 01, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Sorry, in my last solution didn't take care of numbers starting with 4. This is not brute-force:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package javatest;

/**
*
* @author neerajks
*/
public class NonFour {
public long getNonFourCount(long N) {
int numberOfDigits = (int)Math.floor(Math.log10(N)) + 1;
int fisrtDigit = (int)(N / (long)Math.pow(10, numberOfDigits-1));

long count =0;
if(N<10) {
for(int j = 0; j<=N; j++) {
if(j!=4)
count++;
}
return count;
}

long pow = (long)Math.pow(9, numberOfDigits-1);
count = pow;

for(int i =1; i< fisrtDigit; i++) {
if(i != 4) {
count += pow;
}
}

N = N % (long)Math.pow(10, numberOfDigits-1);
return fisrtDigit !=4 ? count + (N==0? 1 : getNonFourCount(N)) : count;
}

}

- Neeraj February 02, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

import java.util.Scanner;

/**
 *
 * @author uğur
 */
public class CountNumber {
    
    public static void main (String args[]) {
        
        Scanner scanner = new Scanner(System.in);
        
        int n = scanner.nextInt();
        
        int count = 0;
        
        for (int i = 0 ; i < n ; i++ ) {
            if ( !containFour(i)) {
                count++;
            }
        }
        
        System.out.println(count);
        
    }
    
    public static boolean containFour(int i) {
        
        return String.valueOf(i).contains("4");
                
    }
    
}

- ugurdonmez87 February 04, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

What about this :P

public int integerCount(int N)

{

int count = 0;

for(int i =0 ; i < N; i++)

{

if(!Integer.toString(i).contains("4"))

{

count++;

}

}

return count;
}

- Dude4goog February 07, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

int pow = 0;
        int sum = 0;
        int digit = 0;
        while (number > 0) {
            digit = number % 10;
            sum += (digit > 4)? ((digit-1) * power (9,pow)) :
                           ((digit) * power (9,pow));
            number /= 10;
            pow++;
        }

- Sachin Kulkarni February 10, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Edit: Small mistake in the above code:

public static void main(String []args){
        int origNumber = 145;
        int number = origNumber;
        int pow = 0;
        int sum = 0;
        int digit = 0;
        while (number > 0) {
            digit = number % 10;
            
            if (digit > 4) {
                sum += ((digit-1) * power (9,pow));           
            } else if (digit == 4) {
                sum = ((digit) * power (9,pow));
            }
            
            else {
                sum += ((digit) * power (9,pow));
            }                       
            number /= 10;
            pow++;
        }          
        System.out.println("Number of numbers less than " + origNumber + " is " + sum);
     }

- Sachin Kulkarni February 10, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

If you want to exclude 0 then minus 1.

- Sachin Kulkarni February 10, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include <stdio.h>
#include <string.h>

main()
{

int N = 40;

int rem = 0;
int mul = 1;
int temp = N;
int noOftimes = 0;


while(temp){

rem = temp % 10;

if(rem == 0){
rem = 10;
}
noOftimes += (rem-1)*mul;
mul = mul*9;
temp = temp/10;


}

printf(" Number of times 4 is not present in %d is %d",N, noOftimes);




}

- kuch July 03, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

If you are reading this, then hats off to you.

Here is my take on the solution.

public static int countNos(int N) {
        if (N < 0) {
            throw new IllegalArgumentException("Input cannot be less than zero");
        }

        int[] digits = getDigits(N);
        int sum = 0;

        for (int i = 0; i < digits.length; i++) {
            if(digits[i] == 4) {
                digits[i] = 3;
            }
            
            int x = digits[i] > 4 ? digits[i] - 1 : digits[i];
            x = (int) (x * Math.pow(9, digits.length - (i + 1)));
            sum += x;
        }
        
        return sum;
    }

    private static int[] getDigits(int num) {
        if (num == 0)
            return new int[1];

        int size = (int) Math.log10(num) + 1;
        int[] digits = new int[size];

        int n = num;
        for (int i = size - 1; i >= 0; i--) {
            digits[i] = n % 10;
            n = (n - digits[i]) / 10;
        }

        return digits;
    }

- nik September 15, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public static void main(String[] args) throws Exception{
       int N;
       Scanner in = new Scanner(System.in);
       System.out.println("Enter an integer: ");
       N= in.nextInt();
       int count = 0;
       System.out.println("Integer entered by user: "+N);  
       for(int i =1; i<N ; i++) {
           StringBuilder sb = new StringBuilder();
           sb.append("");
           sb.append(i);
           String strI = sb.toString();
           if(!strI.contains("4")) {
               count += 1;
           }           
       }
        System.out.println("Number of positive integers less than "+N+" that do not contain 4 are: "+count);         
    }

- Coder September 24, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

int _count(int num, int dec_n, int *inc_sum) {
    if (num == 0) {
        *inc_sum = 1;
        return 0;
    }

    int sum = _count(num/10, dec_n+1, inc_sum);

    int s, q = (num %10);

    /* 
     * If any of the msd has a 4 then no need to calculate the count
     */
    if (*inc_sum) {
        if (q == 4){
            s = (q * power(9, dec_n)) -1;
            (*inc_sum) = 0; // for lsd

        } else {
            q = (q < 4) ? q : q-1;
            s = q * power(9, dec_n);
            (*inc_sum) = 1;
        }

        sum += s;
    }

    return sum;
}

int count (int num) {
    int inc_sum;
    return _count(num, 0, &inc_sum);
}

- geek July 17, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

//Brute Force
public int count(int N){
		int sum = 0, i = 0;
		String s;
		while (i++ < N){
			s = Integer.toString(i);
			if (s.indexOf("4") == -1) sum++;
		}
		return sum;
	}

- Mo January 30, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

/*
* Pouya Karimi - This code is written in C
*/
#include <iostream>
int main(int argc, char const *argv[])
{
int a, counter = 0, b;
std::cout << "Enter a number: ";
std::cin >> a;
for(int i=1;i<=a;i++){
b = i;
while ( b != 0 ){
if(b % 10 == 4){
counter ++;
}
b = b/10;
}
}

std::cout << "The number is: " << a-counter << "\n" ;
return 0;
}

- Pouya Karimi January 30, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Missing a "break" after you increment counter

- hotelCA January 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

void getCountForNumber(int num)
{
    int count = 0;
    for (int i = 1; i< num; i++)
    {
        int temp = i;
        while ( temp )
        {
            if ( temp % 10 == 4 )
            {
                //Digit 4 found.
                break;
            }
            temp /= 10;
        }

        if ( temp == 0)
        {
            ++count;
        }
    }
    std::cout<<"\nNumbers found : "<<count;
}

- Ricky January 30, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

I think it is not the most efficient way to calculate.

- ctang January 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Agree, it;s not optimized one.
Will get back if found more optimal approach.

- Ricky January 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Got another optimized way.
Algo:
1. Check at which position 4 is found i.e. one, tens, hundred, thousand etc.
2. Skip that much of elements
a. If 4 is found at one position then we can't skip checking of any element
b. For others starting from tens position we can skip elements as 9, 99 , 999 ,9999 so on.

I created both the function optimized and non optimized to check the result, and calculate the performance on the basis of checking being done. I am able to achieve upto 46% of less comparison in optimize method.

int getCountForNumberOptimized(int num)
{
    int count = 0;
    int numDigits = 1;
    int posFoundAt = 0;
    int checkDone = 0;
    for (int i = 1; i< num; i++)
    {
        ++checkDone;
        numDigits = 1;
        posFoundAt = 0;
        int temp = i;
        while ( temp )
        {
            if ( temp % 10 == 4 )
           {
               //Digit 4 found. Dont' stop we need to fing the position for top most occurence of 4
               posFoundAt = numDigits;
            }
            temp /= 10;
            ++numDigits;
        }

        if ( posFoundAt == 0)
        {
            ++count;
        }

        if ( posFoundAt >= 2)
        {
            // Digit 4 exists in the number for sure.
            // Check the position if it exists from tens position ownwards we can skip the checking for that number range.
            int getSkippedNumber = 1;
            while(posFoundAt > 1)
            {
                getSkippedNumber *= 10;
                --posFoundAt;
            }
            getSkippedNumber -= 1;
            i += getSkippedNumber;
        }
    }
    std::cout<<"\nNumbers found in Optimize way: "<<count;
    std::cout<<"\nChecks Done in Optimize way : "<<checkDone;
    return checkDone;
}

int getCountForNumber(int num)
{
    std::cout<<"\n\n\t****Range upto "<<num<<"****"<<std::endl;
    int count = 0;
    int checkDone = 0;
    for (int i = 1; i< num; i++)
    {
        ++checkDone;
        int temp = i;
        while ( temp )
        {
            if ( temp % 10 == 4 )
           { 
                //Digit 4 found.
                break;
            }
            temp /= 10;
        }

        if ( temp == 0)
        {
            ++count;
        }
    }
    std::cout<<"\nNumbers found in normal way : "<<count;
    std::cout<<"\nChecks Done in normal way : "<<checkDone;
    return checkDone;
}

void compareBothMethod(int num)
{
    int normalChecks, optimizeChecks;
    normalChecks = getCountForNumber(num);
    optimizeChecks = getCountForNumberOptimized(num);
    if ( normalChecks > optimizeChecks )
        std::cout<<"\nPerformance Achieved : "<<( ( (normalChecks - optimizeChecks) / (normalChecks * 1.0) ) * 100.0)<<"%";
}

int main()
{
    int num = 10;
    for ( int i =0; i < 7;i++)
    {
        compareBothMethod(num);
        num *= 10;
    }
    std::cout<<std::endl;
}

- Ricky January 30, 2014 | Flag


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More