blob: 4be0687b31484edd600669cd7837f539f66607b2 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
package scalevalapokalypsi.utils
import java.io.InputStream
import java.nio.charset.StandardCharsets
import scala.util.Try
import scalevalapokalypsi.constants.*
import scala.io.StdIn.readLine
import scala.math.{min,abs}
/** Converts this string to an array of bytes (probably for transmission).
*
* @param str the string to convert
* @return an array of bytes representing the string in UTF8.
*/
def stringToByteArray(str: String): Array[Byte] =
str.getBytes(StandardCharsets.UTF_8)
/** Converts the given byte array to a string if possible*.
* (* Doesn't convert strings with control sequences in them)
*
* @param bytes the byte array to convert
* @return the matching string, if possible*.
*/
def byteArrayToString(bytes: Array[Byte]): Option[String] =
Try(String(bytes, StandardCharsets.UTF_8))
.toOption
/** Incredibly LÖRS string metric algorithm.
* LÖRSiness explained by there being 6 hours left to the DL
*/
def hammingDistance(s1: String, s2: String): Float =
s1.zip(s2).map(p => p(0) != p(1)).filter((b: Boolean) => b).length
/** Reads n characters from the given InputStream blockingly.
*
* @param input the InputStream to read from
* @param n the number of bytes to read
* @return The read result, or None in case of failure
*/
def getNCharsFromSocket(input: InputStream, n: Int): Option[String] =
val buffer: Array[Byte] = Array.ofDim(n)
var i = 0
var failed = false
while i < n && !failed do
val res = input.read(buffer, i, n - i)
if res < 0 then failed = true
i += res
if failed then None else byteArrayToString(buffer)
def isPrintable(s: String): Boolean =
FORBIDDEN_CHARACTERS.forall((c: Char) => !(s contains c))
/** Gets input from STDIN until the line entered is appoved
* by a validator function.
*
* @param message A query to represent the user with when requesting input
* @param validator A validator function. Should return Right[A] when the
* input is valid and Left[String] when the input is invalid,
* where the string will be printed to the user to notify
* their input was invalid.
* @return The first encountered valid string, see `validator`.
*/
def getValidInput[A](
message: String,
validator: String => Either[String, A]
): A =
LazyList.continually(readLine(s"$message\n> "))
.flatMap(input =>
validator(input) match
case Left(s) =>
println(s)
None
case Right(a) =>
Some(a)
).head
|