Factorial using `for` loop in Kotlin - loops

With experience of java programming, I started learning Kotlin today. I am playing with the language and found me stuck to find a factorial using for loop in kotlin. I managed to do this using while loop.
import java.util.Scanner
fun main(args: Array<String>){
val reader=Scanner(System.`in`)
val x: Int = reader.nextInt()
println(factorial(x))
}
fun factorial(a: Int): Int{
var ans=1
var i: Int = a
while(i>1){
ans*=i
i--
}
return ans
}
Please help me to do this using a for loop.
Thanks

Well, the simplest one that comes to mind:
fun factorial(num: Int): Long {
var result = 1L
for (i in 2..num) result *= i
return result
}

This doesn't use a for loop, but just as an addition you can also make this shorter, more functional and Kotlin-like using reduce:
fun factorial(num: Int) = (1..num).reduce(Int::times)
Or:
fun factorial(num: Int) = (1..num).reduce { a, b -> a * b }
This is the simplest I can think of.
Edit: This is equivalent to
fun factorial(num: Int) = (2..num).fold(1, Int::times)
as reduce is practically a fold starting from the value at index 0.
We start with 2 instead, however 1 would be equivalent as multiplying by one doesn't change the result.
Edit 2: this edit is exactly what holi-java just posted.

there is another expressive one by using Range#fold and function reference expression, for example:
fun factorial(n: Int) = (2..n).fold(1L, Long::times)

If I am so bold to not do it in a for loop,
Here is a handy one liner recursive function to determine the factorial:
fun factorial(a: Int): Long = if (a == 1) a.toLong() else factorial(a - 1) * a

Factorial:
fun factorial(num : Long) : Long {
var factorial : Long = 1
for (i in 2..num) {
factorial *= i
}
println("Factorial of $num = $factorial")
}
Factorial using BigInteger variable:
fun factorial(num : Long) : Long {
var factorial = BigInteger.ONE
for (i in 2..num) {
factorial = factorial.multiply(BigInteger.valueOf(num))
}
println("Factorial of $num = $factorial")
}

Alternative using recursion:
fun factorial(number: Int): Int {
when (number) {
0 -> return 1
else -> return number * factorial(number - 1)
}
}

Other way :
fun factorial (data : Int) : Long {
var result : Long = 1
(1..data).map {
result *= it;
}
return result;
}
if you want use BigInteger :
fun factorial (data : Int) : BigInteger {
var result : BigInteger = 1.toBigInteger()
(1..data).map {
result *= it.toBigInteger();
}
return result;
}

Related

Trying to find the lowest number in a kotlin array

Kotlin newbie here, I'm trying to Write a program that finds the minimum value of N numbers.
The first line contains the number N.
The second line contains N numbers separated by spaces.
Output an integer number which is the minimum of N numbers.
So far I'm getting a null error, so I know the problem is in adding numbers to the array. Here is my code:
fun main(args: Array<String>) {
val scanner = Scanner(System.`in`)
val num1: Int = scanner.nextInt()
var nums = arrayListOf<Int>()
val smallestElement = nums.min()
repeat (num1) {
nums.add(scanner.nextInt())
}
println(smallestElement)
}
java.util.Scanner is so slow, try considering readLine it is optimal for most of the case, and using System.`in`.bufferedReader().readLine() is the fastest but increases heap by creating a buffer.
And the reason you were getting null was because you were trying to get the minimum value at of an empty array. At the time you called ArrayList.min() you did not had added any element into it.
private fun readLn() = readLine()!!
private fun readInt() = readLn().toInt()
fun main(args: Array<String>) {
val num1: Int = readInt()
var nums = IntArray(num1) { readInt() }
println(nums.min())
}
And if you don't mind, instead of storing all the numbers into array and then comparing all the element against minimum you can directly check for minimum elements without creating an array:
private fun readLn() = readLine()!!
private fun readInt() = readLn().toInt()
fun main(args: Array<String>) {
val num1: Int = readInt()
var min = Int.MAX_VALUE
repeat(num1) {
val i = readInt()
if (i < min) min = i
}
println(min)
}
Just invert the order:
fun main(args: Array<String>) {
val scanner = Scanner(System.`in`)
val num1: Int = scanner.nextInt()
var nums = arrayListOf<Int>()
repeat (num1) {
nums.add(scanner.nextInt())
}
val smallestElement = nums.min() // < ----------- here
println(smallestElement)
}

Get an element with its index counting from the end in Kotlin

Is there a simple function to get an element with its index counting from the end in a Kotlin Array, List, or String? In other words, is there a Kotlin equivalent of negative index slicing in Python?
There is no direct function for slicing, but one can write an user defined function or easily simulate using reversed function, that works with string, lists and arrays.
Strings In Python
pyString = 'Python'
sObject = slice(-1, -4, -1)
print(pyString[sObject]) # output: noh
Strings In Kotlin
val pyString = "Python"
val sObject = pyString.reversed().substring(0, 3).reversed() // index 3 excluded
println(pyString) // output: noh
List(or Arrays) in Kotlin
var py = arrayOf(1, 2, 3, 4, 5, 6, 7, 8)
var sObject = py.reversed().slice(0..2).reversed()
println(sObject)
However you can do method or function overload, using this as implicit object
For instance, you can program reverse substring, but here you cannot use negative numbers, because we need a different parameters profile regarding to the original method:
fun String.substring(a: Int, b: Int = 0, rev: Boolean): String {
if (rev == true)
if (b == 0)
return this.substring(0, this.length - a)
else
return this.substring(this.length - b, this.length - a)
else
if (b == 0)
return this.substring(a)
else
return this.substring(a, b)
}
So "whale".substring(0,2,true) is "le"
You can use similar technique to extend slice method.
I implemented a function similar to python's slicing mechanism
import kotlin.math.abs
fun String.substring(startingIndex: Int, endingIndex: Int, step: Int=1): String {
var start = startingIndex
var end = endingIndex
var string = this
if (start < 0) {
start = string.length + start
}
if (end < 0) {
end = string.length + end
}
if (step < 0) {
string = string.reversed()
}
if (start >= string.length) {
throw Exception("Index out of bounds.")
}
var outString = ""
for ((index, character) in string.withIndex()) {
if (index % abs(step) == 0) {
if (index >= start && index <= end) {
outString += character
}
}
}
return outString
}
Can be used like this:
println("This is some text.".substring(8, -6)) // some
There is but on problem with my function, it is that a negative step messes it up if you also use negative indexes.
These answers are quite complicated. If you just want to use a negative index, all you have to do is
exampleList[exampleList.lastIndex - exampleIndex] which will (basically) do the same as exampleList[-exampleindex] in python.
So for example you would do:
fun main(args: Array<String>) {
val exampleList = mutableListOf<Int>(1, 2, 3, 4, 5)
//Now we want exampleList[-1] or 4. I know in python it would be writen as exampleList[-2], but don't worry about that!
println(exampleList[exampleList.lastIndex - 1])
}
the lastIndex parameter is the key thing to remember.

Comparing both function on If and Else

Got this question just now when I’m tried comparing my program to both of my classmates (2 of them), and the results is there results came early (about 2 sec). Note that I forget to use the clock() function.
On if/else condition, is using the ternary operator
(Condition) ? (True) : (False);
slower than using this?
if (condition) {
(function if True)
}else {
(function if False)
}
There is no difference in terms of speed. Use ternary conditional only if you want to type less.
See the following example:
void f1(int i) {
int val = (i > 10) ? i * 5 : i * 10;
}
void f2(int i) {
int val;
if(i > 10){
val = i * 5;
}else{
val = i * 10;
}
}
See the compiler generated assembly for both the functions here.
There is no difference.

Take input in array with loop

developers, i am new in Kotlin I am trying to take input in Array by using loop and after that, i print the all values of array by using loop but t get only input and not show the other chunk and through the error which is shiwn on attach image
fun main(args: Array<String>) {
var arrayint = Array<Int>(5){0}
var x = 1
val abc:Int = arrayint.size
while( x <= abc)
{
arrayint[x] = readLine()!!.toInt()
x++
}
for(index in 0..4)
{
println(arrayint[index])
}
}
The following is a little more succinct
var arrayint = Array<Int>(5) { readLine()!!.toInt() }
for(x in arrayint)
println(x)
On the first line, instead of using the initializer lambda { 0 }, I use a lambda that call readLine.
On line 2, instead of having to know my range (0..4), I let the language do it for me (an Array is iterable).
Try this:
fun main (args:Array<String>){
var arrayint = Array<Int>(5){0}
var x:Int = 0
val abc:Int = arrayint.size
while( x < abc)
{
arrayint[x] = readLine()!!.toInt()
x++
}
for(index in 0..4)
{
println(arrayint[index])
}
}
You should change x <= abc to x < abc and x = 1 to x = 0. It doesn't work now because if abc = 5 and you loop 4 times then x = 5 but arrays in Kotlin (and Java) start at index 0 which means that array of size 5 has the following indexes: 0, 1, 2, 3, 4 which means that arrayint[5] doesn't exist as 5 is out of bounds (> 4)
One of the shorthand for taking n data elements of data input in an array of predefined size is as follow.
Here the user is going to input a integer
n = number of elements then then the array elements
import java.util.*
fun main(){
val read = Scanner(System.`in`)
val n = read.nextInt()
var arr = Array(n) {i-> read.nextInt()} // taking input
arr.forEach{
println(it) // this loop prints the array
}
}
Following code is taking input in array using loop
import java.util.*
fun main(args: Array<String>) {
var num = arrayOfNulls<Int>(5)
var read= Scanner(System.`in`)
println("Enter array values")
for(i in 0..4)
{
num[i] = read.nextInt()
}
println("The array is")
for(x in num){
println(x)}
}
Following code is taking input of array size and then it's elements
fun main() {
print("Enter Array size: ")
val arraySize = readLine()!!.toInt()
println("Enter Array Elements")
val arr = Array<Int>(arraySize) { readLine()!!.toInt() }
for (x in arr)
println(x)
}

Generating All Permutations of Character Combinations when # of arrays and length of each array are unknown

I'm not sure how to ask my question in a succinct way, so I'll start with examples and expand from there. I am working with VBA, but I think this problem is non language specific and would only require a bright mind that can provide a pseudo code framework. Thanks in advance for the help!
Example:
I have 3 Character Arrays Like So:
Arr_1 = [X,Y,Z]
Arr_2 = [A,B]
Arr_3 = [1,2,3,4]
I would like to generate ALL possible permutations of the character arrays like so:
XA1
XA2
XA3
XA4
XB1
XB2
XB3
XB4
YA1
YA2
.
.
.
ZB3
ZB4
This can be easily solved using 3 while loops or for loops. My question is how do I solve for this if the # of arrays is unknown and the length of each array is unknown?
So as an example with 4 character arrays:
Arr_1 = [X,Y,Z]
Arr_2 = [A,B]
Arr_3 = [1,2,3,4]
Arr_4 = [a,b]
I would need to generate:
XA1a
XA1b
XA2a
XA2b
XA3a
XA3b
XA4a
XA4b
.
.
.
ZB4a
ZB4b
So the Generalized Example would be:
Arr_1 = [...]
Arr_2 = [...]
Arr_3 = [...]
.
.
.
Arr_x = [...]
Is there a way to structure a function that will generate an unknown number of loops and loop through the length of each array to generate the permutations? Or maybe there's a better way to think about the problem?
Thanks Everyone!
Recursive solution
This is actually the easiest, most straightforward solution. The following is in Java, but it should be instructive:
public class Main {
public static void main(String[] args) {
Object[][] arrs = {
{ "X", "Y", "Z" },
{ "A", "B" },
{ "1", "2" },
};
recurse("", arrs, 0);
}
static void recurse (String s, Object[][] arrs, int k) {
if (k == arrs.length) {
System.out.println(s);
} else {
for (Object o : arrs[k]) {
recurse(s + o, arrs, k + 1);
}
}
}
}
(see full output)
Note: Java arrays are 0-based, so k goes from 0..arrs.length-1 during the recursion, until k == arrs.length when it's the end of recursion.
Non-recursive solution
It's also possible to write a non-recursive solution, but frankly this is less intuitive. This is actually very similar to base conversion, e.g. from decimal to hexadecimal; it's a generalized form where each position have their own set of values.
public class Main {
public static void main(String[] args) {
Object[][] arrs = {
{ "X", "Y", "Z" },
{ "A", "B" },
{ "1", "2" },
};
int N = 1;
for (Object[] arr : arrs) {
N = N * arr.length;
}
for (int v = 0; v < N; v++) {
System.out.println(decode(arrs, v));
}
}
static String decode(Object[][] arrs, int v) {
String s = "";
for (Object[] arr : arrs) {
int M = arr.length;
s = s + arr[v % M];
v = v / M;
}
return s;
}
}
(see full output)
This produces the tuplets in a different order. If you want to generate them in the same order as the recursive solution, then you iterate through arrs "backward" during decode as follows:
static String decode(Object[][] arrs, int v) {
String s = "";
for (int i = arrs.length - 1; i >= 0; i--) {
int Ni = arrs[i].length;
s = arrs[i][v % Ni] + s;
v = v / Ni;
}
return s;
}
(see full output)
Thanks to #polygenelubricants for the excellent solution.
Here is the Javascript equivalent:
var a=['0'];
var b=['Auto', 'Home'];
var c=['Good'];
var d=['Tommy', 'Hilfiger', '*'];
var attrs = [a, b, c, d];
function recurse (s, attrs, k) {
if(k==attrs.length) {
console.log(s);
} else {
for(var i=0; i<attrs[k].length;i++) {
recurse(s+attrs[k][i], attrs, k+1);
}
}
}
recurse('', attrs, 0);
EDIT: Here's a ruby solution. Its pretty much the same as my other solution below, but assumes your input character arrays are words: So you can type:
% perm.rb ruby is cool
~/bin/perm.rb
#!/usr/bin/env ruby
def perm(args)
peg = Hash[args.collect {|v| [v,0]}]
nperms= 1
args.each { |a| nperms *= a.length }
perms = Array.new(nperms, "")
nperms.times do |p|
args.each { |a| perms[p] += a[peg[a]] }
args.each do |a|
peg[a] += 1
break if peg[a] < a.length
peg[a] = 0
end
end
perms
end
puts perm ARGV
OLD - I have a script to do this in MEL, (Maya's Embedded Language) - I'll try to translate to something C like, but don't expect it to run without a bit of fixing;) It works in Maya though.
First - throw all the arrays together in one long array with delimiters. (I'll leave that to you - because in my system it rips the values out of a UI). So, this means the delimiters will be taking up extra slots: To use your sample data above:
string delimitedArray[] = {"X","Y","Z","|","A","B","|","1","2","3","4","|"};
Of course you can concatenate as many arrays as you like.
string[] getPerms( string delimitedArray[]) {
string result[];
string delimiter("|");
string compactArray[]; // will be the same as delimitedArray, but without the "|" delimiters
int arraySizes[]; // will hold number of vals for each array
int offsets[]; // offsets will holds the indices where each new array starts.
int counters[]; // the values that will increment in the following loops, like pegs in each array
int nPemutations = 1;
int arrSize, offset, nArrays;
// do a prepass to find some information about the structure, and to build the compact array
for (s in delimitedArray) {
if (s == delimiter) {
nPemutations *= arrSize; // arrSize will have been counting elements
arraySizes[nArrays] = arrSize;
counters[nArrays] = 0; // reset the counter
nArrays ++; // nArrays goes up every time we find a new array
offsets.append(offset - arrSize) ; //its here, at the end of an array that we store the offset of this array
arrSize=0;
} else { // its one of the elements, not a delimiter
compactArray.append(s);
arrSize++;
offset++;
}
}
// put a bail out here if you like
if( nPemutations > 256) error("too many permutations " + nPemutations+". max is 256");
// now figure out the permutations
for (p=0;p<nPemutations;p++) {
string perm ="";
// In each array at the position of that array's counter
for (i=0;i<nArrays ;i++) {
int delimitedArrayIndex = counters[i] + offsets[i] ;
// build the string
perm += (compactArray[delimitedArrayIndex]);
}
result.append(perm);
// the interesting bit
// increment the array counters, but in fact the program
// will only get to increment a counter if the previous counter
// reached the end of its array, otherwise we break
for (i = 0; i < nArrays; ++i) {
counters[i] += 1;
if (counters[i] < arraySizes[i])
break;
counters[i] = 0;
}
}
return result;
}
If I understand the question correctly, I think you could put all your arrays into another array, thereby creating a jagged array.
Then, loop through all the arrays in your jagged array creating all the permutations you need.
Does that make sense?
it sounds like you've almost got it figured out already.
What if you put in there one more array, call it, say ArrayHolder , that holds all of your unknown number of arrays of unknown length. Then, you just need another loop, no?

Resources