I wanted to create a program that displays all valid arrangements for n couple of parentheses. The output should be an array sorted in ascending order of ASCII values. The following is the function that needs to be used.
fun solution(n: Array<String>): Array<String> {
}
I tried it using this, but cannot make it fit the above function,
fun balancedBracket(result: String,
size: Int,
open: Int,
close: Int): Unit
{
if (close == size)
{
// When get the result of parentheses in given size
println(result);
return;
}
if (open < size)
{
// Add open parentheses
this.balancedBracket(result + "(",
size, open + 1, close);
}
if (open > close)
{
// Add close parentheses
this.balancedBracket(result + ")",
size, open, close + 1);
}
}
Input: n = 3
Output: ["((()))","(()())","(())()","()(())","()()()"]
Please help.
fun printParentheses(size: Int) {
fun inner(chars: String, size: Int, open: Int, close: Int) {
if (close == size) {
println(chars)
return
}
if (open < size) {
inner("$chars(", size, open + 1, close)
}
if (open > close) {
inner("$chars)", size, open, close + 1)
}
}
if (size > 0) {
inner("", size, 0, 0)
}
}
printParentheses(3)
Related
The problem I'm working on accepts a number string and will output the product of the odd or even numbers in the string. While the product of purely number string is working fine, my code should also accept strings that is alphanumeric (ex: 67shdg8092) and output the product. I'm quite confused on how I should code the alphanumeric strings, because the code I have done uses toInt().
Here's my code:
fun myProd(Odd: Boolean, vararg data: Char): Int {
var bool = isOdd
var EvenProd = 1
var OddProd = 1
for (a in data)
{
val intVal = a.toString().toInt()
if (intVal == 0)
{
continue
}
if (intVal % 2 == 0)
{
EvenProd *= intVal
}
else
{
OddProd *= intVal
}
}
if(bool == true) return OddProd
else return EvenProd
}
Use toIntOrNull instead of toInt. It only converts numeric string
val intVal = a.toString().toIntOrNull()
if (intVal == null || intVal == 0) {
continue
}
Starting from Kotlin 1.6 you can also use a.digitToIntOrNull().
P.S. Your method could be also rewritten in functional style
fun myProd(isOdd: Boolean, input: String): Int {
return input.asSequence()
.mapNotNull { it.toString().toIntOrNull() } // parse to numeric, ignore non-numeric
.filter { it > 0 } // avoid multiplying by zero
.filter { if (isOdd) it % 2 != 0 else it % 2 == 0 } // pick either odd or even numbers
.fold(1) { prod, i -> prod * i } // accumulate with initial 1
}
I've been spending way too much time trying to solve this problem. So the code that I posted below does work in terms of downloading a file, but the problem is, the flow has a very unexpected behaviour. The response.content.readAvailable() method call seems to block until it's completely done downloading the whole file at which point the emit progress happens, so you end up waiting a long time for the file to download, and then in a split second you get all of the progress updates. So I'm wondering if there is a way to do this where I read in a certain number of bytes at a time and then emit a progress and then repeat until the file is done downloading? Or maybe a way to hook into the readAvailable() method and update the progress that way? Any help with this would be greatly appreciated.
Here's the code I found and modified, but still does not work right:
suspend fun HttpClient.downloadFile(
output: File,
downloadUrl: String,
md5Hash: String,
) = flow {
try {
val response = get<HttpResponse> { url(downloadUrl) }
val data = ByteArray(response.contentLength()?.toInt() ?: 0)
val contentLn = response.contentLength()?.toInt() ?: 0
var offset = 0
var bytesRemaining = contentLn
do {
val chunkSize = min(maxChunkSize, bytesRemaining)
logger?.d { "Read Available:" }
val result = response.content.readAvailable(data, offset, length = chunkSize)
val progress = ((offset / contentLn.toDouble()) * 100).toInt()
emit(DownloadResult.Progress(progress))
logger?.d { "logged progress: $progress" }
// delay(6000L) this was to test my assumption that the readAvalible was blocking.
offset += chunkSize
bytesRemaining -= chunkSize
} while (result != -1)
if (response.status.isSuccess()) {
if (data.md5().hex == md5Hash) {
output.write(data)
emit(DownloadResult.Success)
} else {
emit(DownloadResult.ErrorCorruptFile)
}
} else {
emit(DownloadResult.ErrorBadResponseCode(response.status.value))
}
} catch (e: TimeoutCancellationException) {
emit(DownloadResult.ErrorRequestTimeout("Connection timed out", e))
}
}
Finally after a stupid amount of time I solved this. What you need to use is this. That gives you access to the byte channel as it is downloading.
and a very crude implementation (that I'm not yet done with) is this:
get<HttpStatement>(url = downloadUrl).execute {
var offset = 0
val byteBufferSize = 1024 * 100
val channel = it.receive<ByteReadChannel>()
val contentLen = it.contentLength()?.toInt() ?: 0
val data = ByteArray(contentLen)
do {
val currentRead = channel.readAvailable(data, offset, byteBufferSize)
val progress = if(contentLen == 0) 0 else ( offset / contentLen.toDouble() ) * 100
logger?.d { "progress: $progress" }
offset += currentRead
} while (currentRead >= 0)
}
two things to not with this solution. 1.) I'm in the context of HttpClient, so that's how I have access to get(). 2.) I'm creating a byte buffer size of 1024 * 100 in order to not let the readAvailable method block for too long, though this might not be necessary... the one nice thing about it is that it determines how frequently you will be publishing your progress updates.
fun main () {
var integers = mutableListOf(0)
for (x in 1..9) {
integers.add(x)
}
//for or while could be used in this instance
var lowerCase = listOf("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")
var upperCase = listOf('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z')
println(integers)
println(lowerCase)
println(upperCase)
//Note that for the actual program, it is also vital that I use potential punctuation
val passwordGeneratorKey1 = Math.random()*999
val passwordGeneratorKey2 = passwordGeneratorKey1.toInt()
var passwordGeneratorL1 = lowerCase[(Math.random()*lowerCase.size).toInt()]
var passwordGeneratorL2 = lowerCase[(Math.random()*lowerCase.size).toInt()]
var passwordGeneratorL3 = lowerCase[(Math.random()*lowerCase.size).toInt()]
var passwordGeneratorU1 = upperCase[(Math.random()*upperCase.size).toInt()]
var passwordGeneratorU2 = upperCase[(Math.random()*upperCase.size).toInt()]
var passwordGeneratorU3 = upperCase[(Math.random()*upperCase.size).toInt()]
val password = passwordGeneratorKey2.toString()+passwordGeneratorL1+passwordGeneratorL2+passwordGeneratorL3+passwordGeneratorU1+passwordGeneratorU2+passwordGeneratorU3
println(password)
//No, this isn't random, but it's pretty close to it
//How do I now run through every possible combination of the lists //lowerCase, integers, and upperCase?
}
How do I run through every possible permutation to eventually solve for the randomly generated password? This is in Kotlin.
I think you should append all the lists together and then draw from it by random index, this way you ensure that position of numbers, lower cases and uppercases is random too. Also you don't need to write all the characters, you can use Range which generates them for you.
fun main() {
val allChars = mutableListOf<Any>().apply {
addAll(0..9) // creates range from 0 to 9 and adds it to a list
addAll('a'..'z') // creates range from a to z and adds it to a list
addAll('A'..'Z') // creates range from A to Z and adds it to a list
}
val passwordLength = 9
val password = StringBuilder().apply {
for (i in 0 until passwordLength) {
val randomCharIndex =
Random.nextInt(allChars.lastIndex) // generate random index from 0 to lastIndex of list
val randomChar = allChars[randomCharIndex] // select character from list
append(randomChar) // append char to password string builder
}
}.toString()
println(password)
}
Even shorter solution can be achieved using list methods
fun main() {
val password = mutableListOf<Any>()
.apply {
addAll(0..9) // creates range from 0 to 9 and adds it to a list
addAll('a'..'z') // creates range from a to z and adds it to a list
addAll('A'..'Z') // creates range from A to Z and adds it to a list
}
.shuffled() // shuffle the list
.take(9) // take first 9 elements from list
.joinToString("") // join them to string
println(password)
}
As others pointed out there are less painful ways to generate the initial password in the format of: 1 to 3 digits followed by 3 lowercase characters followed by 3 uppercase characters.
To brute force this password, you will need to consider all 3-permutations of "a..z" and all 3-permitations of "A..Z". In both cases the number of such 3-permutations is 15600 = 26! / (26-3)!. In worst case you will have to examine 1000 * 15600 * 15600 combination, half of this on the average.
Probably doable in a few hours with the code below:
import kotlin.random.Random
import kotlin.system.exitProcess
val lowercaseList = ('a'..'z').toList()
val uppercaseList = ('A'..'Z').toList()
val lowercase = lowercaseList.joinToString(separator = "")
val uppercase = uppercaseList.joinToString(separator = "")
fun genPassword(): String {
val lowercase = lowercaseList.shuffled().take(3)
val uppercase = uppercaseList.shuffled().take(3)
return (listOf(Random.nextInt(0, 1000)) + lowercase + uppercase).joinToString(separator = "")
}
/**
* Generate all K-sized permutations of str of length N. The number of such permutations is:
* N! / (N-K)!
*
* For example: perm(2, "abc") = [ab, ac, ba, bc, ca, cb]
*/
fun perm(k: Int, str: String): List<String> {
val nk = str.length - k
fun perm(str: String, accumulate: String): List<String> {
return when (str.length == nk) {
true -> listOf(accumulate)
false -> {
str.flatMapIndexed { i, c ->
perm(str.removeRange(i, i + 1), accumulate + c)
}
}
}
}
return perm(str, "")
}
fun main() {
val password = genPassword().also { println(it) }
val all3LowercasePermutations = perm(3, lowercase).also { println(it) }.also { println(it.size) }
val all3UppercasePermutations = perm(3, uppercase).also { println(it) }.also { println(it.size) }
for (i in 0..999) {
println("trying $i")
for (l in all3LowercasePermutations) {
for (u in all3UppercasePermutations) {
if ("$i$l$u" == password) {
println("found: $i$l$u")
exitProcess(0)
}
}
}
}
}
Need to create a function that implements the attached algorithm, to which all words are passed in the function arguments.
For example:
f ("dfd" dd "ddd");
My code:
fun main() {
var s = readLine();
var w = Array(128){0} //To mark characters from a word 1
var g = Array(128){0}//When we encounter a space, we add units from the first array to the corresponding elements of the second, zeroing them in the first.
if(s!=null)
{
for(c in s)
{
if(c.toInt() > 127 || c.toInt()<0) {
println("Input error, try again");
return;
}
//Checking for space.
if(c.toInt() != 32) w[c.toInt()] = 1;
else
for(k in 0..127)
{
if(w[k] == 1)
{
g[k] += 1;
w[k] = 0;
}
}
}
//For the last word, if there was no space after it.
for(k in 0..127)
{
if(w[k] == 1)
{
g[k] += 1;
w[k] = 0;
}
}
}
//Displaying matched characters to the screen
for(k in 0..127)
{
if(g[k]>1)
{
println(k.toChar());
}
}
}
This program searches for characters that match at least two words in a string
Example
input: hello world
output: lo
There's already utilities for these in Kotlin, I highly recommend you to read the docs before asking these type of questions.
The groupingBy should do what you want:
readLine()?.let { input ->
input.groupingBy { it }.eachCount()
.forEach { if (it.value > 1 && it.key != ' ') println(it.key) }
}
The below code will look for "=" and then split them. If there's no "=", filter them away first
myPairStr.asSequence()
.filter { it.contains("=") }
.map { it.split("=") }
However seeing that we have both
.filter { it.contains("=") }
.map { it.split("=") }
Wonder if there's a single operation that could combine the operation instead of doing it separately?
You can use mapNotNull instead of map.
myPairStr.asSequence().mapNotNull { it.split("=").takeIf { it.size >= 2 } }
The takeIf function will return null if the size of the list returned by split method is 1 i.e. if = is not present in the string. And mapNotNull will take only non null values and put them in the list(which is finally returned).
In your case, this solution will work. In other scenarios, the implementation(to merge filter & map) may be different.
I see your point and under the hood split is also doing an indexOf-check to get the appropriate parts.
I do not know of any such function supporting both operations in a single one, even though such a function would basically just be similar to what we have already for the private fun split-implementation.
So if you really want both in one step (and require that functionality more often), you may want to implement your own splitOrNull-function, basically copying the current (private) split-implementation and adapting mainly 3 parts of it (the return type List<String>?, a condition if indexOf delivers a -1, we just return null; and some default values to make it easily usable (ignoreCase=false, limit=0); marked the changes with // added or // changed):
fun CharSequence.splitOrNull(delimiter: String, ignoreCase: Boolean = false, limit: Int = 0): List<String>? { // changed
require(limit >= 0, { "Limit must be non-negative, but was $limit." })
var currentOffset = 0
var nextIndex = indexOf(delimiter, currentOffset, ignoreCase)
if (nextIndex == -1 || limit == 1) {
if (currentOffset == 0 && nextIndex == -1) // added
return null // added
return listOf(this.toString())
}
val isLimited = limit > 0
val result = ArrayList<String>(if (isLimited) limit.coerceAtMost(10) else 10)
do {
result.add(substring(currentOffset, nextIndex))
currentOffset = nextIndex + delimiter.length
// Do not search for next occurrence if we're reaching limit
if (isLimited && result.size == limit - 1) break
nextIndex = indexOf(delimiter, currentOffset, ignoreCase)
} while (nextIndex != -1)
result.add(substring(currentOffset, length))
return result
}
Having such a function in place you can then summarize both, the contains/indexOf and the split, into one call:
myPairStr.asSequence()
.mapNotNull {
it.splitOrNull("=") // or: it.splitOrNull("=", limit = 2)
}
Otherwise your current approach is already good enough. A variation of it would just be to check the size of the split after splitting it (basically removing the need to write contains('=') and just checking the expected size, e.g.:
myPairStr.asSequence()
.map { it.split('=') }
.filter { it.size > 1 }
If you want to split a $key=$value-formats, where value actually could contain additional =, you may want to use the following instead:
myPairStr.asSequence()
.map { it.split('=', limit = 2) }
.filter { it.size > 1 }
// .associate { (key, value) -> key to value }