Implement the read4 method [reviewed]

Problem

Implement read using read4
class ArbitraryIO {
private:
    // returns bytes read or 0, sizeof(buf) >= 4
    // reads up to 4 bytes at a time into caller allocated buf
    int read4(char* buf);

public:
  // IMPLEMENT:toRead > 4 or < 4 or = 4, buf allocated by caller, return number of bytes read
  int read(char* buf, size_t toRead) {

  }
};

Your method should pass the following test cases:

------ test case  ---
// assume reader is reading over ->  a b c d e f g h i j
ArbitraryIO r;
char buf[1024];
int x;

x = r.read(buf, 2);
EXPECT(x == 2);
EXPECT(buf[0] == 'a');
EXPECT(buf[1] == 'b');

x = r.read(buf, 5);
EXPECT(x == 5);
EXPECT(buf[0] == 'c');
EXPECT(buf[1] == 'd');
EXPECT(buf[2] == 'e');
EXPECT(buf[3] == 'f');
EXPECT(buf[4] == 'g');

x = r.read(buf, 1024);
EXPECT(x == 3);
EXPECT(buf[0] == 'h');
EXPECT(buf[1] == 'i');
EXPECT(buf[2] == 'j');

Moving window approach with internal temporary buffer


This question will stay as "Difficult" because I could not solve this problem within 30 mins.

Here are two thing you need to understand this problem.

1. read4() continue to read upto 4 bytes each time until the end of underlying data is reached.

2. read() is called multiple time by the caller with toRead value and should return the value from lastly read position toRead bytes or what's left in underlying data.


There are several cases we need to think about when solving this problem.

Case 1: exact 4 bytes was requested and 4 bytes is returned from read4()

This is happiest case. Just call read4() and return the result.

Case 2: less than 4 bytes was requested and 4 bytes is returned for the first time.

In this case, we call read4() and 4 bytes is returned. Say 2 bytes was requested. After returning 2 bytes, what will do with another 4 bytes?

If next read() is called, will we call read4() directly? If so, what about prior 2 bytes that hadn't been returned?

We need so somehow keep this 2 bytes somewhere and use this 2 bytes first before calling another read4() method. Otherwise we will skip these 2 bytes !!

Case 3: more than 4 bytes was requested after requesting less than 4 bytes in prior call.

This case is what I was worrying about in Case 2. In this call, we need to check if there was any residual bytes from prior call and use them first then call read4() to read additional 4 bytes.


Here is the complete code in C++



Practice statistics:

12:04: to come up with the algorithm and write the partial code
21:44: to write up the algorithm (had major logical flaws)
1h: to debug the logical flaws. (had to run the execution several time. What a shame...)


UPDATE(2019-08-04): Solved this problem in python. I came up with the algorithm but it took too long (27 mins). Writing the correct code also took 35 minutes.

After writing the code, I realized that passing the buffer as parameter does not work for python. So, I modified the code to let the method return length and buffer to simulate what C++ code can do. 

This is quite C-style low-level code that I don't do anymore. (I did what I was writing kernel level code in C). My low level coding skill is little rusty I guess.

Overall, it took 71 minutes to write the working code.

Here is the solution in python.


Practice statistics

26:13: to come up with algorithm
35:20: to write up the complete code and test code (passing the buffer as parameter was wrong)
09:27: to debug the issue and change the signature and code to let the read() and read4() not use buffer as parameter.


Comments

Popular posts from this blog

Planting flowers with no adjacent flower plots

Find the maximum number of bomb that can be detonated