Photo by Max Chen on Unsplash

How to use Readline in Node to read test cases.

Slim Hmidi
Apr 15, 2019 · 3 min read

Sometimes when we solve a coding problem on an online challenge platform, we need to test our algorithm with different test cases or many files of test cases.

In this article, I tried to write a Binary Search algorithm which allows to find the index of an element in a sorted array and I test it using some test cases form stdin and a text file.

So let’s start our example by writing the binary search algorithm;

First, we check our array if it is empty or not and returns -1 to say that the element does not exist.

// verify if the array is not null and contains elements  
if (!array || !array.length) {
return -1;
}

Then, we declare two variables start and end and we initialize them by the first and the last index of the array.

let start = 0;    
let end = array.length - 1;

After that we iterate our array until the condition start < end is not valid;

while (start < end) {        
const middle = parseInt((start + end) / 2, 10);
if (array[middle] === element) {
return middle;
} else if (array[middle] < element) {
start = middle + 1;
} else {
end = middle;
}
}

Finally, we check the last case when the start = end

// end condition: start === end    
if (start !== array.length && array[start] === element) return start

When the element does not exist in the array, in this case we return -1.

After implementing our base algorithm, let’s move now to the main part;

To read the test cases, we use the module readline, which provides an interface for reading data from a Readable stream (such as process.stdin) one line at a time.
So we have to create an instance from the readline.Interfaceclass using createInterface() method.

// create an interface
const rl = readline.createInterface({
input: process.stdin, // readable Stream: stdin
});

After that, the interface should listen to the lineevent which is emitted whenever the input stream receives an end-of-line input (\n, \r, or \r\n). This usually occurs when the user presses the <Enter>, or <Return>keys.

In our example the test case has this format: 1≤ T ≤ 100; 1≤ N ≤ 1000

T
N target
e1 e2 e3 ...... eN

We set our interface and we created a listener to get the line’s value when a new one exists;

rl.on('line', (line) => {   
// Extract the first line value = T
if (!T) {
T = line
return
}
count++
// Get the value of N and the element to fetch in the array
if (count % 2) {
[ N, element ] = line.split(' ').map(e => Number(e));
}
if (!(count % 2)) {
// extract the array element from the line

const array = line.split(' ').map(e => Number(e));
// fetch the element's index in the array

const fetchedIndex = binarySearch(array, element);

console.log(`Case #${parseInt(count / 2, 10)}:`, fetchedIndex) }
// close the interface when the number or lines exceeds 2 * T
if (count >= 2 * T){
rl.close();
}
})

When we read values from a file the only difference is the initialization of the input property ;

// Creation of readline instanceconst 
rl = createInterface({
input: fs.createReadStream(filePath), // readable Stream: file crlfDelay: Infinity});

Summary

In this article, we have encountered a simple example where we use readline in order to read data from stdin or a file.

In case of typo or code errors feel free to leave me a comment.

Code:

JavaScript in Plain English

Learn the web's most important programming language.

Slim Hmidi

Written by

Fullstack javascript developer

JavaScript in Plain English

Learn the web's most important programming language.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade