How to get an integer as user input in SML - smlnj

I'm trying to get a number from a user. That number is then used to
call another function randomList(n) which takes the given number and
uses it. I keep getting the error exception option. I've read that
adding SOME to the variable declaration or valOf can fix this issue,
but it is not working for me. What do I need to change?
fun getNumber() =
print "Please enter the number of integers: ";
let
val str = valOf (TextIO.inputLine TextIO.stdIn)
val i : int = valOf (Int.fromString str)
in
randomList(i)
end;
getNumber();

The issue here is that fun getNumber() only encompasses the print statement on the following line. You need to enclose the print and the let within parenthesis if you want them to both be a part of getNumber().
For example, the following code compiles and echos the input integer that is passed in via stdin:
fun getNumber() = (
print "Please enter the number of integers: ";
let
val str = valOf (TextIO.inputLine TextIO.stdIn)
val i : int = valOf (Int.fromString str)
in
print(Int.toString(i))
end
);
getNumber();

Related

Is there any way in flutter for converting String to a new Function?

I have a text field and this text field gives me a String and I want to convert this String to a Function. for example >>>
"{
print("a")
}"
this is the String and I want this String to be a function like this>>>
{
print("a")
}
There is a way in my mind.
using textField with text controller to get data after user type
to use that string to make sure that string which user typed will meet two different regex patterns which shown on the pictures.
and then using if..else to invoke print().
RegExp regExp1 = new RegExp("your algorium"); <- to find print
RegExp regExp2 = new RegExp("your algorium"); <- to find "xxxx"
var a = regExp1.hasMatch("{print("a")}")
var b = regExp2.hasMatch("{print("a")}")
if ( a && b)
{
String test = regExp2.stringMatch("{print("a")}").toString()
print(test);
}

Replace a substring in a string in liquidsoap

Liquidsoap provides the string.replace function. But how should I use it? It seems to expect a function as the second argument that does the replacing.
I'd like to do something like this:
str = "Hello world."
str = string.replace(pattern="w", "W", str)
# str == "Hello World."
string.replace indeed expects a function for the first unlabeled parameter. The return value of that function will be used as a replacement.
Example:
str = "Hello world."
str = string.replace(pattern="w", (fun(_) -> "W"), str)
# str == "Hello World."
The inline arrow function fun(_) -> "W" is a function that will always return "W".

Simple Scala Function Not Removing Double Spaces

For some reason when I input a string with double spaces such as " ", the function does not remove them from the string, nor does it remove them when they are generated by two WUB's in a row
For example:
songDecoder("WUBCATWUBWUBBALLWUB") outputs "CAT_ _BALL" (underscores represent spaces)
I could fix this by other means, but since I have no idea why my current code isn't working I figured I should ask to patch my understanding.
def songDecoder(song:String):String = {
val l = song.indexOf("WUB")
if (song.contains(" ")) {
val e = song.indexOf(" ")
songDecoder(song.patch(e,Nil,1))
}
if (l==0) {
val c = song.patch(l,Nil,3)
songDecoder(c)
}
if (l== -1)
song.trim
else {
val c = song.patch(l,Nil,2)
val b = c.patch(l," ",1)
songDecoder(b)
}
}
The reason it doesn't work is because when you call a recursive method it eventually returns with its result. The code that clears out the double-whitespace doesn't save that result.
if (song.contains(" ")) {
val e = song.indexOf(" ")
songDecoder(song.patch(e,Nil,1)) //send patched song to decoder
} //don't save returned string
//continue with unpatched song
The 2nd if block also recurses without saving the result.
if (l==0) {
val c = song.patch(l,Nil,3)
songDecoder(c) //send patched song to decoder
} //don't save returned string
//continue with unpatched song
You can remove both of those if blocks and you'll get the same results from your method. The only code that effects the output is the final if/else and that's because it is at the end of the method's code block. So whatever the if/else produces that's what the method returns.
if (l== -1)
song.trim //return the final result string
else {
val c = song.patch(l,Nil,2) //remove one WUB
val b = c.patch(l," ",1) //replace with space
songDecoder(b) //return whatever the next recursion returns
}
Just as an FYI, here's a different approach.
def songDecoder(song:String):String =
"(WUB)+".r.replaceAllIn(song, " ").trim
How about something like:
song.split(“(WUB)+”).mkString(“ “).trim

How to call two functions in a let..in.. in SML/NJ

I'm trying to call two separate functions within a function. One
function generates and presents a random List to a user and the other
function uses the random list and sorts it.
fun getNumber() = (
print "Please enter the number of integers: ";
let
val str = valOf (TextIO.inputLine TextIO.stdIn)
val i : int = valOf (Int.fromString str)
in(
randomList(i);
mergeSortDriver(randomList(i)))
end
);
The above code only executes the mergeSortDriver. I've tried
multiple ways such as removing the parentheses, trying nested in
statements, and other methods but they do not work or they either give
me an error. So how can I call both of these functions and have both
present their data?
fun getNumber() = (
print "Please enter the number of integers: ";
let
val str = valOf (TextIO.inputLine TextIO.stdIn)
val i : int = valOf (Int.fromString str)
in(
randomList(i),
mergeSortDriver(randomList(i)))
end
);
I needed to change the ; to a , within the in statement

How to get multiple lines of stdin Swift HackerRank?

I just tried out a HackerRank challenge, and if a question gives you x lines of input, putting x lines of let someVariable = readLine() simply doesn't cut it, because there are lot's of test cases that shoot way more input to the code we write, so hard coded readLine() for each line of input won't fly.
Is there some way to get multiple lines of input into one variable?
For anyone else out there who's trying a HackerRank challenge for the first time, you might need to know a couple of things that you may have never come across. I only recently learned about this piece of magic called the readLine() command, which is a native function in Swift.
When the HackerRank system executes your code, it passes your code lines of input and this is a way of retrieving that input.
let line1 = readLine()
let line2 = readLine()
let line3 = readLine()
line1 is now given the value of the first line of input mentioned in the question (or delivered to your code by one of the test cases), with line2 being the second and so on.
Your code may work just great but may fail on a bunch of other test cases. These test cases don't send your code the same number of lines of input. Here's food for thought:
var string = ""
while let thing = readLine() {
string += thing + " "
}
print(string)
Now the string variable contains all the input there was to receive (as a String, in this case).
Hope that helps someone
:)
Definitely you shouldn't do this:
while let readString = readLine() {
s += readString
}
This because Swift will expect an input string (from readLine) forever and will never terminate, causing your application die by timeout.
Instead you should think in a for loop assuming you know how many lines you need to read, which is usually this way in HackerRank ;)
Try something like this:
let n = Int(readLine()!)! // Number of test cases
for _ in 1 ... n { // Loop from 1 to n
let line = readLine()! // Read a single line
// do something with input
}
If you know that each line is an integer, you can use this:
let line = Int(readLine()!)!
Or if you know each line is an array of integers, use this:
let line = readLine()!.characters.split(" ").map{ Int(String($0))! }
Or if each line is an array of strings:
let line = readLine()!.characters.split(" ").map{ String($0) }
I hope this helps.
For new version, to get an array of numbers separated by space
let numbers = readLine()!.components(separatedBy: [" "]).map { Int($0)! }
Using readLine() and AnyGenerator to construct a String array of the std input lines
readLine() will read from standard input line-by-line until EOF is hit, whereafter it returns nil.
Returns Characters read from standard input through the end of the
current line or until EOF is reached, or nil if EOF has already been
reached.
This is quite neat, as it makes readLine() a perfect candidate for generating a sequence using the AnyGenerator initializer init(body:) which recursively (as next()) invokes body, terminating in case body equals nil.
AnyGenerator
init(body: () -> Element?)
Create a GeneratorType instance whose next method invokes body
and returns the result.
With this, there's no need to actually supply the amount of lines we expect from standard input, and hence, we can catch all input from standard input e.g. into a String array, where each element corresponds to an input line:
let allLines = AnyGenerator { readLine() }.map{ $0 }
// type: Array<String>
After which we can work with the String array to apply whatever operations needed to solve a given task (/HackerRank task).
// example standard input
4 3
<tag1 value = "HelloWorld">
<tag2 name = "Name1">
</tag2>
</tag1>
tag1.tag2~name
tag1~name
tag1~value
/* resulting allLines array:
["4 3", "<tag1 value = \"HelloWorld\">",
"<tag2 name = \"Name1\">",
"</tag2>",
"</tag1>",
"tag1.tag2~name",
"tag1~name",
"tag1~value"] */
I recently discovered a neat trick to get a certain amount of lines. I'm gonna assume the first line gives you the amount of lines you get:
guard let count = readLine().flatMap({ Int($0) }) else { fatalError("No count") }
let lines = AnyGenerator{ readLine() }.prefix(count)
for line in lines {
}
I usually use this form.
if let line = readLine(), let cnt = Int(line) {
for _ in 1...cnt {
if let line = readLine() {
// your code for a line
}
}
}
Following the answer from dfrib, for Swift 3+, AnyIterator can be used instead of AnyGenerator, in the same way:
let allLines = AnyIterator { readLine() }.map{ $0 }
// type: Array<String>