package com.freetymekiyan.algorithms.level.easy;

/**
 * The API: int read4(char *buf) reads 4 characters at a time from a file.
 * <p>
 * The return value is the actual number of characters read. For example, it returns 3 if there is only 3 characters
 * left in the file.
 * <p>
 * By using the read4 API, implement the function int read(char *buf, int n) that reads n characters from the file.
 * <p>
 * Note:
 * The read function will only be called once for each test case.
 * <p>
 * Company Tags: Facebook
 * Tags: String
 * Similar Problems: (H) Read N Characters Given Read4 II - Call multiple times
 */
public class ReadNCharactersGivenRead4 {

    /*
     * The read4 API is defined in the parent class Reader4.
     * int read4(char[] buf);
     */
    public class Solution extends Reader4 {

        /**
         * Read with read4 to an intermediate buffer.
         * Every time check if we reach the end of the file.
         * If read4 returns size smaller than 4, it means end of file.
         * Copy characters in read4 buffer to output buffer.
         * Update readBytes.
         *
         * @param buf Destination buffer
         * @param n   Maximum number of characters to read
         * @return The number of characters read
         */
        public int read(char[] buf, int n) {
            int readBytes = 0;
            char[] buffer = new char[4]; // Intermediate buffer as a cache
            int bufPointer = 0;
            int bufCounter = 0;

            while (readBytes < n) {
                if (bufPointer == 0) {
                    bufCounter = read4(buffer);
                }
                if (bufCounter == 0) {
                    break;
                }
                while (readBytes < n && bufPointer < bufCounter) {
                    buf[readBytes++] = buffer[bufPointer++];
                }
                if (bufPointer == bufCounter) {
                    bufPointer = 0;
                }
            }
            return readBytes;
        }
    }

    /**
     * Dummy
     */
    private class Reader4 {

        int read4(char[] buf) {
            return 0;
        }
    }
}

@@ -47,16 +47,61 @@
 y;%0A%0A/**%0A
+ * 157. Read N Characters Given Read4%0A * %3Cp%3E%0A
  * The A
@@ -924,56 +924,123 @@
   * 
-Every time check if we reach the end of the file
+Copy characters in read4 buffer to output buffer while making sure don't exceed n.%0A         * Update the bytes read
 .%0A  
@@ -1123,85 +1123,56 @@
   * 
-Copy characters in read4 buffer to output buffer.%0A         * Update readBytes
+Every time check if we reach the end of the file
 .%0A  
@@ -1402,21 +1402,17 @@
     int 
-readB
+b
 ytes = 0
@@ -1481,83 +1481,27 @@
 fer 
-as a cache%0A            int bufPointer = 0;%0A            int bufCounter = 0;%0A
+to copy characters.
 %0A   
@@ -1508,37 +1508,33 @@
          while (
-readB
+b
 ytes %3C n) %7B%0A    
@@ -1550,77 +1550,100 @@
    i
-f (bufPointer == 0) %7B%0A                    bufCounter = read4(
+nt read = read4(buffer);%0A                // Copy to outside buffer from intermediate 
 buffer
-);
+.
 %0A   
@@ -1659,220 +1659,171 @@
     
-%7D%0A                if (bufCounter == 0) %7B%0A                    break;%0A                %7D%0A                while (readBytes %3C n && bufPointer %3C bufCounter) %7B%0A                    buf%5BreadBytes++%5D = buffer%5BbufPointer++%5D
+// Should not exceed n bytes.%0A                for (int i = 0; i %3C read && bytes %3C n; i++) %7B%0A                    buf%5Bbytes%5D = buffer%5Bi%5D;%0A                    bytes++
 ;%0A  
@@ -1862,35 +1862,27 @@
 if (
-bufPointer == bufCounter) %7B
+read %3C 4) %7B // EOF.
 %0A   
@@ -1903,21 +1903,12 @@
    b
-ufPointer = 0
+reak
 ;%0A  
@@ -1960,13 +1960,9 @@
 urn 
-readB
+b
 ytes
@@ -2109,9 +2109,8 @@
 %0A    %7D%0A%7D
-%0A

update 157. Read N Characters Given Read4