Jetpack Compose KeyboardType for DateTime? [duplicate] - kotlin

This question already has answers here:
How to apply a mask date (mm/dd/yyyy) in TextField with Jetpack Compose?
(5 answers)
Closed yesterday.
I managed to create a TextField for a date using KeyboardType.Number. Now I would like to create a TextField for a time but there is no KeyboardType with ":" like the TextInputType.datetime in Flutter. Is there another way to accomplish this in Jetpack Compose?

Thanks to the comment from Aleksey Sinelnikov I figured out a way:
class TimeTransformation: VisualTransformation {
override fun filter(text: AnnotatedString): TransformedText {
val trimmed = if (text.text.length >= 4) text.text.substring(0..3) else text.text
var output = ""
for (i in trimmed.indices) {
output += trimmed[i]
if (i < 3 && i % 2 == 1) output += ":"
}
val timeTranslator = object : OffsetMapping {
override fun originalToTransformed(offset: Int): Int {
// [offset [0 - 1] remain the same]
if (offset <= 1) return offset
// [2 - 3] transformed to [3 - 4] respectively
if (offset <= 3) return offset + 1
return 5
}
override fun transformedToOriginal(offset: Int): Int {
if (offset <= 1) return offset
if (offset <= 4) return offset - 1
return 4
}
}
return TransformedText(AnnotatedString(output), timeTranslator)
}
}

Related

print "X" star patterns in Kotlin

can someone help me make star patterns like this using for loop in kotlin? i already try this but i think my code is too long. can someone help me?
x Star Pattern
fun fifthPyramid(){
for(i in 1..13){
if(i==1||i==13){
print("*")
}else
print(" ")
}
println("")
for(i in 1..13){
if(i==2||i==12){
print("*")
}else
print(" ")
}
println("")
for(i in 1..13){
if(i==3||i==11){
print("*")
}else
print(" ")
}
println("")
for(i in 1..13){
if(i==4||i==10){
print("*")
}else
print(" ")
}
println("")
for(i in 1..13){
if(i==5||i==9){
print("*")
}else
print(" ")
}
}
The star pattern consists of exactly N * 2 - 1 rows and columns. So the outer and inner loop will run till towards count = N * 2 - 1
fun main() {
var starCount = 5;
val count = starCount * 2 - 1;
for(i in 1..count){
for(j in 1..count){
if(j==i || (j==count - i + 1))
{
print("*");
}
else
{
print(" ");
}
}
println("")
}
}
Identify the pattern with respect to row and column. You put a * when the row and column are the same, or the row and inverse of the column are the same.
fun printX(size: Int, char: Char) {
repeat(size) { row ->
repeat(size) { col ->
print(if (row == col || row == (size - col - 1)) char else ' ')
}
println()
}
}
fun main() {
printX(7, '*')
}
You can write a fun that takes an Int and a Char as arguments and then use a loop in order to build each line and print it.
Basically like this:
fun printX(heightWidth: Int, symbol: Char) {
// iterate the heigth in order to build up each line (top->down)
for (i in 0 until heightWidth) {
/*
build up an array of Chars (representing a line)
with the desired size (length of a line)
filled up with whitespaces by default
*/
var line = CharArray(heightWidth) { ' ' }
// then replace whitespaces at the desired indexes by the symbol
line[i] = symbol // one from left to right
line[line.size - i - 1] = symbol // and one from right to left
// and print the result
println(line)
}
}
You can throw an Exception in case of negative heightWidth values because they will cause trouble if you don't. And maybe forbid 0, 1 and 2, because although they would produce valid output, that output can hardly be regarded as X. Even the output for 3 and 4 is rather ugly ;-)
However, here's the output of printX(7, '7'):
7 7
7 7
7 7
7
7 7
7 7
7 7

kotlin product of odd or even integers

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
}

problems with index of array

I'm writing a function that allows you to remove certain numbers from an int arraylist.
My code
for (i in 1 until 4) {
divider = setDivider(i)
for(index in 0 until numbers.size){
if(index <= numbers.size){
if (numbers[index] % divider == 0 && !isDone) {
numbers.removeAt(index)
}
}else{
isDone = true
}
}
if(isDone)
break
}
the function to set the divider
fun setDivider(divider: Int): Int {
when (divider) {
1 -> return 2
2 -> return 3
3 -> return 5
4 -> return 7
}
return 8
}
I do not know why the ide is giving me the error Index 9 out of bounds for length 9.
Author explained in the comments that the goal is to remove all numbers that are divisible by 2, 3, 5 and 7.
It can be achieved much easier by utilizing ready to use functions from stdlib:
val dividers = listOf(2, 3, 5, 7)
numbers.removeAll { num ->
dividers.any { num % it == 0 }
}
It removes elements that satisfy the provided condition (is divisible) for any of provided dividers.
Also, it is often cleaner to not modify a collection in-place, but to create an entirely new collection:
val numbers2 = numbers.filterNot { num ->
dividers.any { num % it == 0 }
}

How to get columns of two dimesional array using functional style in kotlin

For example I have such a simple task: count all raws and columns which have all zeros in 2D array.
So for
0 0 0
0 0 0
1 0 1
answer is 2 raws and 1 column.
I can make it just like that for raws: var cntRaws = a.count { it.all { el -> el == 0 } }, but how to solve it for columns in same way?
val x = Array<IntArray>(3) { IntArray(3) { 0 } }
x[2][0] = 1
x[2][2] = 1
val raws = x.count { it.sum() == 0 }
val columns = (x.indices)
.map { columnIndex -> x.map { it[columnIndex] } }
.count { it.sum() == 0 }
println("total raws:$raws")
println("total col:$columns")
I couldn't think of any idomatic / functional style to do this, but I came up with an idea just create a lazily evaluated swapping function that swaps the columns with rows when it wants to pull without creating a new list.
fun <T> List<List<T>>.swapped() = sequence {
var index = 0
while (index < size) {
yield(map { it[index] })
index++
}
}
fun main() {
val list = listOf(
listOf(0, 0, 0),
listOf(0, 0, 0),
listOf(1, 0, 1)
)
val cntRows = list.count { it.all { el -> el == 0 } }
val cntCols = list.swapped().count { it.all { el -> el == 0 } }
println("cntRows: $cntRows")
println("cntCols: $cntCols")
}
I tried my best to optimize it and do it in same O(n*m) steps as done with the regular row counting, since Sequences are lazily evaluated.
This is a functional way of doing it that works if all rows are the same size:
fun <T>List<List<T>>.rowToColumn() = (0 until first().size).map{row -> (0 until size).map {col-> this[col][row] }}

Kotlin decomposing numbers into powers of 2

Hi I am writing an app in kotlin and need to decompose a number into powers of 2.
I have already done this in c#, PHP and swift but kotlin works differently somehow.
having researched this I believe it is something to do with the numbers in my code going negative somewhere and that the solution lies in declaring one or more of the variable as "Long" to prevent this from happening but i have not been able to figure out how to do this.
here is my code:
var salads = StringBuilder()
var value = 127
var j=0
while (j < 256) {
var mask = 1 shl j
if(value != 0 && mask != 0) {
salads.append(mask)
salads.append(",")
}
j += 1
}
// salads = (salads.dropLast()) // removes the final ","
println("Salads = $salads")
This shoud output the following:
1,2,4,8,16,32,64
What I actually get is:
1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,
Any ideas?
This works for the one input that you specified, at the very least:
fun powersOfTwo(value :Long): String {
val result = ArrayList<String>()
var i = 0
var lastMask = 0
while (lastMask < value) {
val mask = 1 shl i
if (value != 0.toLong() && mask < value) {
result.add(mask.toString())
}
lastMask = mask
i += 1
}
return result.joinToString(",")
}
Ran it in a unit test:
#Test
fun addition_isCorrect() {
val result = powersOfTwo(127)
assertEquals("1,2,4,8,16,32,64", result)
}
Test passed.
You can get a list of all powers of two that fit in Int and test each of them for whether the value contains it with the infix function and:
val value = 126
val powersOfTwo = (0 until Int.SIZE_BITS).map { n -> 1 shl n }
println(powersOfTwo.filter { p -> value and p != 0}.joinToString(","))
// prints: 2,4,8,16,32,64
See the entire code in Kotlin playground: https://pl.kotl.in/f4CZtmCyI
Hi I finally managed to get this working properly:
fun decomposeByTwo(value :Int): String {
val result = ArrayList<String>()
var value = value
var j = 0
while (j < 256) {
var mask = 1 shl j
if ((value and mask) != 0) {
value -= mask
result.add(mask.toString())
}
j += 1
}
return result.toString()
}
I hope this helps someone trying to get a handle on bitwise options!
Somehow you want to do the "bitwise AND" of "value" and "mask" to determine if the j-th bit of "value" is set. I think you just forgot that test in your kotlin implementation.