Skip to content

Instantly share code, notes, and snippets.

@xphoniex
Created January 6, 2019 19:48
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save xphoniex/ec81075f42367c98e97e74726191fd8c to your computer and use it in GitHub Desktop.
Save xphoniex/ec81075f42367c98e97e74726191fd8c to your computer and use it in GitHub Desktop.
think-cell
/*
Task Description
interval_map<K,V> is a data structure that efficiently associates intervals of keys of type K with values of type V. Your task is to implement the assign member function of this data structure, which is outlined below.
interval_map<K, V> is implemented on top of std::map. In case you are not entirely sure which functions std::map provides, what they do and which guarantees they provide, we provide an excerpt of the C++ standard here:
Each key-value-pair (k,v) in the std::map means that the value v is associated with the interval from k (including) to the next key (excluding) in the std::map.
Example: the std::map (0,'A'), (3,'B'), (5,'A') represents the mapping
0 -> 'A'
1 -> 'A'
2 -> 'A'
3 -> 'B'
4 -> 'B'
5 -> 'A'
6 -> 'A'
7 -> 'A'
... all the way to numeric_limits<int>::max()
The representation in the std::map must be canonical, that is, consecutive map entries must not have the same value: ..., (0,'A'), (3,'A'), ... is not allowed. Initially, the whole range of K is associated with a given initial value, passed to the constructor of the interval_map<K,V> data structure.
Key type K
besides being copyable and assignable, is less-than comparable via operator<
is bounded below, with the lowest value being std::numeric_limits<K>::lowest()
does not implement any other operations, in particular no equality comparison or arithmetic operators
Value type V
besides being copyable and assignable, is equality-comparable via operator==
does not implement any other operations
*/
#include <map>
#include <limits>
#include <ctime>
template<typename K, typename V>
class interval_map {
std::map<K,V> m_map;
public:
// constructor associates whole range of K with val by inserting (K_min, val)
// into the map
interval_map( V const& val) {
m_map.insert(m_map.end(),std::make_pair(std::numeric_limits<K>::lowest(),val));
}
// Assign value val to interval [keyBegin, keyEnd).
// Overwrite previous values in this interval.
// Conforming to the C++ Standard Library conventions, the interval
// includes keyBegin, but excludes keyEnd.
// If !( keyBegin < keyEnd ), this designates an empty interval,
// and assign must do nothing.
void assign( K const& keyBegin, K const& keyEnd, V const& val ) {
if (!(keyBegin < keyEnd)) return;
std::pair<K,V> beginExtra;
std::pair<K,V> endExtra;
bool beginHasExtra = false;
bool endHasExtra = false;
typename std::map<K,V>::const_iterator itBegin;
itBegin = m_map.lower_bound(keyBegin);
if ( itBegin!=m_map.end() && keyBegin < itBegin->first ) {
if (itBegin != m_map.begin()) {
beginHasExtra = true;
--itBegin;
beginExtra = std::make_pair(itBegin->first, itBegin->second);
}
// openRange for erase is prevIterator
// insert (prevIterator->first, prevIterator->second) as well!
}
typename std::map<K,V>::const_iterator itEnd;
itEnd = m_map.lower_bound(keyEnd);
if ( itEnd!=m_map.end() && keyEnd < itEnd->first ) {
endHasExtra = true;
typename std::map<K,V>::const_iterator extraIt = itEnd;
--extraIt;
endExtra = std::make_pair(keyEnd, extraIt->second);
// closeRange for erase is this iterator
// insert (keyEnd, prevIterator->second) as well!
}
// 4 canonical conflicts:
// beginExtra w/ mid
// before-mid w/ mid (beginHasExtra==false)
// mid w/ endExtra
// mid w/ after-mid (endHasExtra==false)
bool insertMid = true;
if (beginHasExtra) {
if (beginExtra.second == val)
insertMid = false;
} else {
if (itBegin != m_map.begin()) {
typename std::map<K,V>::const_iterator beforeMid = itBegin;
--beforeMid;
if (beforeMid->second == val)
insertMid = false;
}
}
if (endHasExtra) {
if ( (insertMid && endExtra.second == val) || (!insertMid && endExtra.second == beginExtra.second) )
endHasExtra = false;
} else {
if ( (insertMid && itEnd!=m_map.end() && itEnd->second == val) || (!insertMid && itEnd!=m_map.end() && itEnd->second == beginExtra.second) )
itEnd = m_map.erase(itEnd);
}
itBegin = m_map.erase(itBegin, itEnd);
if (beginHasExtra)
itBegin = m_map.insert(itBegin, beginExtra);
if (insertMid)
itBegin = m_map.insert(itBegin, std::make_pair(keyBegin, val));
if (endHasExtra)
m_map.insert(itBegin, endExtra);
// INSERT YOUR SOLUTION HERE
}
// look-up of the value associated with key
V const& operator[]( K const& key ) const {
return ( --m_map.upper_bound(key) )->second;
}
};
@Obaid51
Copy link

Obaid51 commented Sep 5, 2023

Check out my solution @ https://github.com/minhdv82/kengolib/blob/main/range.h I've also implemented a public test() [for canonicity] method, which is called in test_range.cpp. PS: I renamed the dumb m_valBegin to ob_value_ [out of bound value].

Did it worked?

@minhdv82
Copy link

minhdv82 commented Sep 5, 2023

Yes, it works. You can try running test_range.cpp yourself; it'd generate millions of random assigns, then test against canonicity.

@heatblazer
Copy link

First time I am seeing that ADT in an usage. Is it only for trolling candidates or it actually has some practical usage. On first sight it looks not so complex to implement, so I guess it's just a time waster?

@minhdv82
Copy link

minhdv82 commented Sep 5, 2023

Actually, it's quite tricky to get it right, let alone efficient. I guess this ADT may be useful when one has / wants the real line as key-space.

@FailedAtTheLimitThinkCell
Copy link

I failed at the limit because of big O complexity.
m_map.insert_or_assign(key,value) is not good enough for them, even m_map.insert(std::pair<K,V>(key,value)) may not work ....
They want us to use an iterator to insert the value so you don't take the O(logN) time for looking up the key but if you erase the unwanted range before inserting you don't have iterators for this range. I guess you need to replace the unwanted iterators keys and values ? and remove the truly unnecessary ones ?
Here is my current code if someone wants it :

if(!(keyBegin < keyEnd))
	return;

if(m_map.empty())
{
	if(val == m_valBegin)
		return;

	m_map.insert(std::pair<K,V>(keyBegin, val));
	m_map.insert(std::pair<K,V>(keyEnd, m_valBegin));

	return;
}

auto itLowerBound = m_map.upper_bound(keyBegin);
auto itLowerBoundExactSame = itLowerBound;
if(itLowerBoundExactSame != m_map.begin())
{
	itLowerBoundExactSame = std::prev(itLowerBoundExactSame);
	if(!(itLowerBoundExactSame->first < keyBegin))
		itLowerBound = itLowerBoundExactSame;
}

auto itHigherBound = m_map.upper_bound(keyEnd);

if(itLowerBound == m_map.end()
|| itHigherBound == m_map.begin())
{
	if(val == m_valBegin)
		return;

	m_map.insert(std::pair<K,V>(keyBegin, val));
	m_map.insert(std::pair<K,V>(keyEnd, m_valBegin));

	return;
}

auto itFindBeginValue = itLowerBound;

V beginValue(m_valBegin);
if(itFindBeginValue != m_map.begin())
	beginValue = std::prev(itFindBeginValue)->second;

auto itFindEndValue = itHigherBound;

V endValue(m_valBegin);
if(itFindEndValue != m_map.end())
	endValue = std::prev(itFindEndValue)->second;

if(itLowerBound != m_map.end() && itHigherBound != m_map.end())
{
	if(std::distance(itLowerBound, itHigherBound) == 0)
	{
		if(val == beginValue)
			return;

		m_map.insert(std::pair<K,V>(keyBegin, val));
		m_map.insert(std::pair<K,V>(keyEnd, beginValue));

		return;
	}
}
m_map.erase(itLowerBound, itHigherBound);

if(m_map.empty())
{
	if(val == m_valBegin)
		return;

	m_map.insert(std::pair<K,V>(keyBegin, val));
	m_map.insert(std::pair<K,V>(keyEnd, m_valBegin));

	return;
}

if(!(beginValue == val))
	m_map.insert(std::pair<K,V>(keyBegin, val));

if(!(endValue == val))
	m_map.insert(std::pair<K,V>(keyEnd, endValue));

return;

But fuck it : if they don't accept people that have not done the best big O complexity they don't deserve me and they don't deserve you !

@ShoaibShama
Copy link

Yes, it works. You can try running test_range.cpp yourself; it'd generate millions of random assigns, then test against canonicity.

I have summitted your solution. It says: Type requirements are met: You must adhere to the specification of the key and value type given above.

can you like post the corrected solution, I am planning to give the test today ,

@alexismailov2
Copy link

Yes, it works. You can try running test_range.cpp yourself; it'd generate millions of random assigns, then test against canonicity.

I have summitted your solution. It says: Type requirements are met: You must adhere to the specification of the key and value type given above.

can you like post the corrected solution, I am planning to give the test today ,

If you could not do that test ownself without solution you will not pass the interview. You should understand that their interview very difficult. And the problem not in the interview the problem in the tasks which they expect you will need to be able to do!!!

@alexismailov2
Copy link

I also failed the test. Always quite frustrating to fail the test but I think that it's still an interesting exercise.

I suspect that the trick happens at the erase step. I suspect that the optimal solution uses the function extract. Indeed, if I imagine the std::map as a binary tree (be careful with that because std::map might not be implemented as a binary tree), then, if we want to erase all the nodes that have a key inferior to a certain value Ksup and superior to a certain value Kinf, instead of finding each individual node and erasing them one by one, it's possible to eliminate whole groups of nodes altogether via the function extract and insert.

Let's imagine a simple binary tree 1 2 - 20 3 8 - (30 50) 4 7 10 15 - ([33 35 52 54](tel:33 35 52 54)) 5 6 8 9 13 14 16 17 - (....)

Let's say that you want to remove all nodes with key > 22 if you try to remove all nodes one by one, I think that you can do something like for( it = map.begin(); it != map.end()) if(it.first > 22) it = map.erase(it) else it++;

It will end up performing a lot of erase, with each erase possibly involving rebalancing, reassignment, deletion and insertion.

On the contrary, instead of deleting each node one by one, because std::map is a sorted container, if we find a node A with key > 22, I suspect it's possible to extract this node instead of erase it and so, delete the whole group of nodes below A all at once, possibly avoiding unnecessary operations.

Looks like you completely did not still understand very easy thing: THERE ARE A LOT OF COMPANIES WHICH DON’T PRESS THEIR CANDIDATES…

@Mekhak
Copy link

Mekhak commented Nov 11, 2023

Not a great interview task, you need to be super careful and detail oriented while implementing this. I think even if you pass this one, the next steps will be much worse )

@TaherLkdw
Copy link

This is my solution with some of the test cases:

void assign( K const& keyBegin, K const& keyEnd, V const& val ) {

    if (!(keyBegin < keyEnd)) return;

    //---------------Initialise the map --------------------
    if (m_map.empty()) {
        if (!(val == m_valBegin)) {
            m_map.insert(m_map.end(),std::make_pair(keyBegin, val));
            m_map.insert(m_map.end(),std::make_pair(keyEnd, m_valBegin));
        }
        return;
    }

    //--------------- Find a place to add keyBegin --------------------
    auto begin_it = m_map.lower_bound(keyBegin);
    bool insert_keyBegin_before_begin = false;

    if (begin_it == m_map.begin() && val == m_valBegin) {
        return; //beginning of the key is not allowed to have value equals to m_valBegin.
    }

    //Take previous element if the keyBegin is after the end or
    //between the two existing keys or
    //existing key is found but previous to that key's value is equal to val.
    if ((begin_it == m_map.end()) || (begin_it != m_map.begin() && (keyBegin < begin_it->first || std::prev(begin_it)->second == val))) {
        --begin_it;
    } else if (begin_it == m_map.begin() && keyBegin < begin_it->first) {
        insert_keyBegin_before_begin = true; //If the keyBegin is before the beginning of the map.
    }

    //--------------- Find a place to add keyEnd --------------------
    auto end_it = m_map.lower_bound(keyEnd);
    bool insert_keyEnd_before_begin = false;

    auto temp_it = end_it;

    if (end_it == m_map.end() || (keyEnd < end_it->first && end_it != m_map.begin())) {
        //If the keyEnd is after the end or between the two existing keys,
        //then need to save previous elements value to assign it to end key.
        --temp_it;
    } else if (end_it == m_map.begin() && keyEnd < end_it->first) {
        insert_keyEnd_before_begin = true; //If the keyEnd is before the beginning of the map.
    }
    auto end_elem_pair =  std::pair<K,V>(keyEnd, (insert_keyEnd_before_begin ? m_valBegin : temp_it->second));

    //--------------- Insert or assign keyBegin --------------------
    if (insert_keyBegin_before_begin || !(begin_it->second == val)) {
        begin_it = m_map.insert_or_assign(begin_it, keyBegin, val);
    }

    //--------------- Erase elements between keyBegin and keyEnd --------------------
    temp_it = begin_it;
    if (begin_it != m_map.end()) {
        ++temp_it;
    }

    //Delete elements between inserted begin key and end key position.
    //Condition checks if keyEnd is greater than next element of begin_it which confirms,
    //there are elements between keyBegin and keyEnd to be deleted.
    if (temp_it != m_map.end() && !(keyEnd < temp_it->first)) {
        m_map.erase(temp_it, end_it);
    }

    //--------------- Insert or assign keyEnd --------------------
    if (!(begin_it->second == end_elem_pair.second)) {
        end_it = m_map.insert_or_assign(end_it, end_elem_pair.first, end_elem_pair.second);
    }

    //Delete end element as well if end element value is same as begin element value
    if (end_it != m_map.end() && begin_it->second == end_it->second) {
        m_map.erase(end_it);
    }
    //-------------------------------------------------------------------------
}

assign<int,int>(0,3,2);
// assign<int,int>(0,5,3);
// assign<int,int>(1,5,2);
// assign<int,int>(1,4,2);
// assign<int,int>(1,4,3);
// assign<int,int>(1,5,3);
// assign<int,int>(1,5,1);
// assign<int,int>(8,10,3);
// assign<int,int>(4,8,3);
// assign<int,int>(1,8,3);
// assign<int,int>(1,8,2);
// assign<int,int>(1,2,2);
// assign<int,int>(-10,4,2);
// assign<int,int>(-10,-2,2);
// assign<int,int>(-10,-2,3);
// assign<int,int>(-10,-2,0);
// assign<int,int>(-10,0,2);
// assign<int,int>(-10,3,2);
// assign<int,int>(-10,3,1);
// assign<int,int>(-10,1,2);
// assign<int,int>(-10,4,2);
// assign<int,int>(-10,8,2);
// assign<int,int>(-10,3,0);
// assign<int,int>(0,5,0);
// assign<int,int>(1,5,0);
// assign<int,int>(1,8,0);
// assign<int,int>(3,4,0);
// assign<int,int>(3,4,1);
// assign<int,int>(3,5,1);
// assign<int,int>(3,5,2);
// assign<int,int>(5,8,2);

could not pass the correctness test:

Correctness: Your program should produce a working interval_map with the behavior described above. In particular, pay attention to the validity of iterators. It is illegal to dereference end iterators. Consider using a checking STL implementation such as the one shipped with Visual C++ or GCC. Many solutions we receive do not create the data structure that was asked for, e.g., some interval ends up being associated with the wrong value. Others contain a code path that will eventually dereference an invalid or end iterator.

@raidtest
Copy link

A possible "DAU" trap pool. Spend many hours. They maybe same as Crossover. Just making joke with programmer, sucker.

@HeNeos
Copy link

HeNeos commented Dec 20, 2023

I failed at the limit because of big O complexity. m_map.insert_or_assign(key,value) is not good enough for them, even m_map.insert(std::pair<K,V>(key,value)) may not work .... They want us to use an iterator to insert the value so you don't take the O(logN) time for looking up the key but if you erase the unwanted range before inserting you don't have iterators for this range. I guess you need to replace the unwanted iterators keys and values ? and remove the truly unnecessary ones ? Here is my current code if someone wants it :

if(!(keyBegin < keyEnd))
	return;

if(m_map.empty())
{
	if(val == m_valBegin)
		return;

	m_map.insert(std::pair<K,V>(keyBegin, val));
	m_map.insert(std::pair<K,V>(keyEnd, m_valBegin));

	return;
}

auto itLowerBound = m_map.upper_bound(keyBegin);
auto itLowerBoundExactSame = itLowerBound;
if(itLowerBoundExactSame != m_map.begin())
{
	itLowerBoundExactSame = std::prev(itLowerBoundExactSame);
	if(!(itLowerBoundExactSame->first < keyBegin))
		itLowerBound = itLowerBoundExactSame;
}

auto itHigherBound = m_map.upper_bound(keyEnd);

if(itLowerBound == m_map.end()
|| itHigherBound == m_map.begin())
{
	if(val == m_valBegin)
		return;

	m_map.insert(std::pair<K,V>(keyBegin, val));
	m_map.insert(std::pair<K,V>(keyEnd, m_valBegin));

	return;
}

auto itFindBeginValue = itLowerBound;

V beginValue(m_valBegin);
if(itFindBeginValue != m_map.begin())
	beginValue = std::prev(itFindBeginValue)->second;

auto itFindEndValue = itHigherBound;

V endValue(m_valBegin);
if(itFindEndValue != m_map.end())
	endValue = std::prev(itFindEndValue)->second;

if(itLowerBound != m_map.end() && itHigherBound != m_map.end())
{
	if(std::distance(itLowerBound, itHigherBound) == 0)
	{
		if(val == beginValue)
			return;

		m_map.insert(std::pair<K,V>(keyBegin, val));
		m_map.insert(std::pair<K,V>(keyEnd, beginValue));

		return;
	}
}
m_map.erase(itLowerBound, itHigherBound);

if(m_map.empty())
{
	if(val == m_valBegin)
		return;

	m_map.insert(std::pair<K,V>(keyBegin, val));
	m_map.insert(std::pair<K,V>(keyEnd, m_valBegin));

	return;
}

if(!(beginValue == val))
	m_map.insert(std::pair<K,V>(keyBegin, val));

if(!(endValue == val))
	m_map.insert(std::pair<K,V>(keyEnd, endValue));

return;

But fuck it : if they don't accept people that have not done the best big O complexity they don't deserve me and they don't deserve you !

You can achieve it with a Dynamic Segment Tree to make the updates in ranges in just O(log(n))

@juniper0383
Copy link

You can achieve it with a Dynamic Segment Tree to make the updates in ranges in just O(log(n))

How is it possible that you can implement your custom data structure while being restricted to only modify the assign function?

@danielyoshizawa
Copy link

Not sure if people still read this, but one thing that was not clear at all to me is, the last node will be the value up to the limit of the the map, or it goes from keyBegin to keyEnd and after that it returns to m_valBegin?

In the example

Example: the std::map (0,'A'), (3,'B'), (5,'C') represents the mapping

so let's say that the last call was like

i_map.assign(5,10, 'C');

If I call, i_map[11] , what is the expected return value? should be 'C' or 'A', considering m_valBegin == 'A'

@juniper0383
Copy link

@danielyoshizawa

if state is m_valBegin = 'A'; map = (0,'A'), (3,'B'); last call assign(5,10, 'C');
then it becomes (0,'A'), (3,'B'), (5,'C'), (10'A')
so query map[11] => A

in your example m_valBegin = (0,'A'), (3,'B'), (5,'C'); m_valBegin == 'A'
then query map[11] => C

@MaMadDl
Copy link

MaMadDl commented Jan 5, 2024

Here's my try.

void assign(K const& keyBegin, K const& keyEnd, V const& val)
    {
        if (keyEnd < keyBegin) {
            return;
        }

        auto it_begin = m_map.lower_bound(keyBegin);
        auto it_Ubegin = m_map.upper_bound(keyBegin);

        auto it_end = m_map.upper_bound(keyEnd);

        if (m_map.size() == 0) {
            if (val == m_valBegin)
                return;
        }

        if (it_end != m_map.end()) {
            if (val == it_end->second) {
                return;
            }
        }
        if (it_begin != m_map.begin()) {
            if (val == std::prev(it_begin)->second) {
                return;
            }
        }

        if (it_begin == m_map.end()) {

            if (it_end != m_map.end() && it_Ubegin->first < it_end->first) {
                m_map.insert({keyEnd, it_Ubegin->second});
            }
            m_map.erase(it_Ubegin, it_end);
            m_map.insert({keyBegin, val});

        } else {
            if (it_end != m_map.end()) {
                m_map.insert({keyEnd, it_end->second});
            }
            m_map.erase(it_begin, it_end);
            m_map.insert({keyBegin, val});
        }
    }

with the test function:

void runIntervalMapTest() {

    std::srand(time(0));

    // Number of random test cases
    const int numTestCases = 1000;
    // Generate random test cases
    for (int i = 0; i < numTestCases; ++i) {

        interval_map<int,char> iMap('F');
        std::map<int, char> referenceMap;

        // Randomly generate startKey, endKey, and value
        int startKey = std::rand() % numTestCases;
        int endKey = startKey + std::rand() % 50;
        char value = static_cast<char>('A' + std::rand() % 26);

        // Perform the assignment in both the inter_map and referenceMap
        iMap.assign(startKey, endKey, value);
        for (int key = startKey; key <= endKey; ++key) {
            referenceMap[key] = value;
        }

        // Compare the results of inter_map with the referenceMap
        // and print an error message if they differ
        for (const auto& entry : referenceMap) {
            int key = entry.first;
            char expectedValue = entry.second;
            char actualValue = iMap[key]; // You may need a getValue() function in your inter_map class
            if (actualValue != expectedValue) {
                std::cout << "Test "<<i <<" failed: Key " << key << ", Expected " << expectedValue << ", Actual " << actualValue << std::endl;
            }
        }

    }
    std::cout << "Randomized test completed." << std::endl;
}

@MikeO89
Copy link

MikeO89 commented Jan 22, 2024

I attempted this test - they claimed to have liked my implementation, but are limiting feedback so the test can be re-used. I explain in greater detail here.

@maybesravan
Copy link

This version did not pass the running time test:

 void assign(K const& keyBegin, K const& keyEnd, V const& val)
    {
        if (!(keyBegin < keyEnd))
        {
            return;
        }

        auto endIt = m_map.lower_bound(keyEnd);
        if ((endIt == m_map.end()) || (keyEnd < endIt->first))
        {
            const auto& valEnd =
                (endIt == m_map.begin()) ? m_valBegin : std::next(endIt, -1)->second;
            if (!(valEnd == val))
            {
                endIt = m_map.emplace_hint(endIt, keyEnd, valEnd);
            }
        } else if (endIt->second == val)
        {
            ++endIt;
        }

        auto startIt = m_map.lower_bound(keyBegin);
        if ((startIt == m_map.begin()) && (val == m_valBegin))
        {
            if (startIt != endIt)
            {
                m_map.erase(startIt, endIt);
            }
            return;
        } else if ((startIt != m_map.begin()) && (val == std::next(startIt, -1)->second))
        {
            --startIt;
        } else
        {
            if (keyBegin < startIt->first)
            {
                startIt = m_map.emplace_hint(startIt, keyBegin, val);
            } else
            {
                startIt->second = val;
            }
        }

        if (++startIt != endIt)
        {
            m_map.erase(startIt, endIt);
        }
    }

Only way i've found to possibly improve it:

...
       auto endIt = m_map.lower_bound(keyEnd);
       if ((endIt == m_map.end()) ||
           (keyEnd < endIt->first))
       {
           if ((endIt == m_map.begin()))
           {
               if (!(val == m_valBegin))
               {
                   endIt = m_map.emplace_hint(endIt, keyEnd, m_valBegin);
               }
           } else if (!(val == std::next(endIt, -1)->second))
           {
               auto node  = m_map.extract(std::next(endIt, -1));
               node.key() = keyEnd;
               endIt      = m_map.insert(endIt, std::move(node));
           }
       } else if (endIt->second == val)
       {
           ++endIt;
       }
...

Cannot test since there are only two attempts

did u sucess in the test? share the solution

@netmonitoring
Copy link

I have two solutions for this task. First one passed successfully, due to that i had no chance to check if second solution is also correct. If somebody have a link to online test and wants to check my second solution write me a pm.

@sakib-shekh
Copy link

I have two solutions for this task. First one passed successfully, due to that i had no chance to check if second solution is also correct. If somebody have a link to online test and wants to check my second solution write me a pm.

i have test link

@netmonitoring
Copy link

I have two solutions for this task. First one passed successfully, due to that i had no chance to check if second solution is also correct. If somebody have a link to online test and wants to check my second solution write me a pm.

i have test link

Send me your direct contacts

@sakib-shekh
Copy link

sakib-shekh commented Mar 25, 2024

I have two solutions for this task. First one passed successfully, due to that i had no chance to check if second solution is also correct. If somebody have a link to online test and wants to check my second solution write me a pm.

i have test link

Send me your direct contacts
hey buddy i also have implemented something but i am unclear about some case what to do can you explain your code and possibilities through gmeet my email sakibshekhabd@gmail.com

reply fast just 2 hours left

@triptisingla
Copy link

I have two solutions for this task. First one passed successfully, due to that i had no chance to check if second solution is also correct. If somebody have a link to online test and wants to check my second solution write me a pm.

Can you please give the 1st solution?

@RutulPatel007
Copy link

I have two solutions for this task. First one passed successfully, due to that i had no chance to check if second solution is also correct. If somebody have a link to online test and wants to check my second solution write me a pm.

Can you give your 1st solution

@alexismailov2
Copy link

I have two solutions for this task. First one passed successfully, due to that i had no chance to check if second solution is also correct. If somebody have a link to online test and wants to check my second solution write me a pm.

Finally ThinkCells will be able to interview someone for this 10 years🤣🤣🤣

@RutulPatel007
Copy link

Can you give your solution @netmonitoring

@RutulPatel007
Copy link

I have two solutions for this task. First one passed successfully, due to that i had no chance to check if second solution is also correct. If somebody have a link to online test and wants to check my second solution write me a pm.

i have test link

Send me your direct contacts

I have test link
email: githubrp@gmail.com

@netmonitoring
Copy link

Can you give your solution @netmonitoring

I will provide the solution to the test link directly. Will not allow modify my solution. So if you are not ready to provide your link, do not share your contacts.

Also i will ask you not share my solution anywhere.

@alexismailov2
Copy link

@netmonitoring what means test link?

@alexismailov2
Copy link

@RutulPatel007 @netmonitoring @triptisingla @sakib-shekh
Just remember this cartoon 🤣🤣🤣
IMG_2186

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment