A stdio & stdout story — this time: for swift
My first blog was about making standard input and output tasks work for Objective-C, which does not come naturally as you would need to use some good old C functions (scanf and printf). For some reason, I did not think of trying it out with swift until I heard my classmate Joe saying: “Hey Cenker, you had this blog about using Objective-C with hackerrank.com. How do you do that with swift? Did you try it?”. I responded that I had no idea how, and i decided to work on it, do some research and make it a blog post, so here we go:
The question that we will be working on is one of the questions on the hackerrank web site. The website gives you two triplets in 2 separate lines and asks you to print two numbers on the standard output; the first one shows how many of the first three are bigger then the corresponding number of the second three and the second number shows vice versa. If the numbers are equal; no change. Here is the question from their website:
With swift, we are lucky, because print() is different than NSLog() as it writes to the standard out put (NSLog() writes to standard error). So if we calculate the numbers and call print() it should work. Which is pretty straight forward. To satisfy the requirements of the question, we will print two numbers in a formatted string with one space in between.
The tricky part is though, to figure out how to capture the input. For this, swift has a function called readLine(stripNewline:). It reads one line of user input. If you have a second one, it will read your second line after you hit enter. It returns a string optional. Its argument is a boolean and its default value is true. The argument asks you whether you want to exclude the newline character, which is the character that is being added to strings when you hit enter key. Yes, most of the time you would want to exclude it, hence the default value being true :-).
The problem with this readLine() function and the playground is that you can not test it with an XCode playground file because you cannot simulate a user input. The way to test is is through terminal. Apple has a command line tool for swift (a repl) where you can print quick strings or do some quick calculations similar to ruby or python. It seems like though, you cannot test our code with readLine (as we need to input from the command line) so we need to find another way. Below is me trying to make readLine() work with the swift repl (making mistakes along the way):
The way to check code with user input with swift is similar to other languages. You can create create a file with swift extension lets say myFile.swift. Then, you run the code by entering “swift myFile.swift” on the command line in your terminal (minus the quotes of course). Here is the code for this exercise and the output:
This way, you can simulate the inputs of the problem you are working on through your terminal and test what you are reading with the readLine() function. The reason why you would do this is that the website does not show you what your readLine() function received and what your code printed out. You cannot test that fully with a playground file as you cannot read user input.
I think the code above is pretty obvious. I tried to make it as clear as possible and did not try to make it the shortest version as my main goal to show how to test user input and output using swift. I also force unwrapped the optional strings that readLine() function returns. This is usually not recommended in a production code, you need to unwrap it by using an if let/var statement. This was done for the sake of this exercise :-)
I hope this helps someone!