Adobe: 2021: US: C++ Software Developer: take home test
Anonymous User
1048

Hi all,
I got a take home test but Adobe did not move forward with my application.

About the test:

  • Implement the classes manually(see below) and return the .cpp file.

My solution

  • The first part was relatively trivial
  • For the second part, the set operation, was correct i.e verified by unit tests I added to verify content of runs_ vector(see below)
  • However, I used sort which takes O(n log (n)) and this might be the reason Adobe rejected me.

Follow ups

  • In case, someone can come up with a O(n) solution for set, please share.
  • Basically, for me, the goal is to be able to improve for future interviews, hence the Q.
  • Specifically, is there a bug-free way of inserting in middle of a std::vector(we have to use vector)?
  • Asking because I used std::vector with insert method but it was not bug free.
  • Any suggestions/tips appreciated. Thanks!

Test content:

The solutions for both problems described below should be implemented in solutions.cpp provided alongside this file. Please reach out to us for any clarifications or questions.

Problem 1
---------
Let's write a new class called int_map which:

 - is a map of int -> int
 - has a size specified at construction, and all mappings from 0 to size-1 initialized to the same specified value
 - supports get/set of individual mappings
 
Let's keep the interface simple:

	class int_map
	{
		// ... member variables ...

	public:

		int_map(int num_values, int initial_val);

		int get(int index) const;

		void set(int index, int value);
	};
 
Please implement this class using a std::vector<int> as the underlying data structure.  

Notes:
 - You may assert for out-of-range values.
 - You may assume that the map, once initialized, does not change size.

Problem 2
---------
This is a continuation of the previous problem. Let's write a new class called rle_int_map which again:

 - is a map of int -> int
 - has a size specified at construction, and all mappings from 0 to size-1 initialized to the same specified value
 - supports get/set of individual mappings
 - has a size() method which returns the size specified at construction, i.e., the total number of mappings (which does not change for the lifetime of the object)
 
Let's suppose we expect the mapping to contain long spans of identical values (e.g. the values for consecutive keys will be the same), and that run-length encoding the map will yield good storage gains:

	class rle_int_map
	{
		struct run
		{
			int stop_;
			int value_;
		};
	 
		// The first run implicitly starts at 0; all subsequent runs start at the previous run's stop_
		std::vector<run> runs_;	

	public:
		rle_int_map(int num_keys, int initial_val)
		{
			runs_.push_back({ num_keys, initial_val });
		}

		int get(int index) const
		{
			// It is illegal to pass in an invalid index, for the purposes of this exercise we can
			// just assert()
			assert(0 <= index && index < runs_.back().stop_);

			for (auto const& r : runs_)
			{
				if (r.stop_ > index)
					return r.value_;
			}
			assert(false); // Shouldn't get here
		}

		void set(int index, int value)
		{
			// TODO: Implement this.
		}
	
		int size() const
		{
			// TODO: Implement this. This returns the number of key-value mappings stored in the map.
		}
	};
	
To obtain a full score on the problem, the map should manage storage optimally. Non-optimal solutions will still get partial credit.
Specifically, runs_ (private member) should avoid the following:

 - adjacent runs that map to the same value
 - zero-length runs
 - a first run with stop_ <= 0 evaluating to true
 
Notes:

 - You may assert for out-of-range values.
 - You may assume that the map, once initialized, does not change size.

Example output:

 int main()
 {
	rle_int_map m(5, 23);
	m.set(3, 42);
	m.set(1, 100);
	m.set(3, 37);
	for (auto i = 0; i < 5; ++i)
		std::cout << i << ": " << m.get(i) << '\n';
 }

should produce:

 1: 100
 2: 23
 3: 37
 4: 23
 5: 23 
 
 //Correction:  OP: Adobe Engineer confimed that output should be:
  0: 23
 1: 100
 2: 23
 3: 37
 4: 23
Comments (3)