Why I'm getting 'return' expression required in a function with a block body error in Kotlin? - kotlin

open class Test1 {
fun name(a: Int, b: Int): Int {
if (a % 2 == 0 && b % 2 == 0) return (a * b)
if (a % 2 == 1 && b % 2 == 1) return (a + b)
if ((a % 2 == 0).xor(b % 2 == 0)) return if (a > b) (a - b) else (b - a)
}
}
class Test2 : Test1() {
}
val obj1 = Test2()
print(obj1.name(7 , 8))
I'm trying to learn inheritance in Kotlin, but when I call name function from father class and try to print the result I get error below.
error: a return expression required in a function with a block body ('{...}') }

If the first and the second condition is false, the third one must be true so you can remove the last condition. The compiler does not seem to be able to draw this conclusion, so it suspects a case where there is no return.
fun name(a: Int, b: Int): Int {
if (a % 2 == 0 && b % 2 == 0) return (a * b)
if (a % 2 == 1 && b % 2 == 1) return (a + b)
return if (a > b) (a - b) else (b - a)
}
You can also simplify this method as follows
fun name(a: Int, b: Int): Int {
if (a % 2 != b % 2) return if (a > b) (a - b) else (b - a);
return if (a % 2 == 0) (a * b) else (a + b)
}

Your last line of the function
if ((a % 2 == 0).xor(b % 2 == 0)) return if (a > b) (a - b) else (b - a)
if you add brackets for clarity, it would look like:
if ((a % 2 == 0).xor(b % 2 == 0)) {
return if (a > b) (a - b) else (b - a)
}
So if the if test is false, the code won't run, which means you've reached the end of the function and still haven't returned something. You have to return an Int.

As already answered, in order for your code to compile your function must return an int from all execution paths, your function doesn't satisfy that condition. what happens if all the if conditions eveluate to false?
And second thing is that in kotlin return is an expression, so you can lift it out like so
fun name(a: Int, b: Int): Int {
return if (a % 2 == 0 && b % 2 == 0) { (a * b) }
else if (a % 2 == 1 && b % 2 == 1) { (a + b) }
else if ((a % 2 == 0).xor(b % 2 == 0)) { if (a > b) (a - b) else (b - a) }
else SOME_DEFAULT_INT
}

Related

Fizz-Buzz solution is not working properly in kotlin

In the Fizz-Buzz problem, we replace a number multiple of 3 with the word fizz and a number divisible by 5 with the word buzz. If a number is divisible by both three and five, we replace it with the word"FizzBuzz." in a counting incremental loop.
But my code is not working properly. Please take a look and let me know what I am doing wrong.
for (i in 1..100){
if ( i%5 == 0 || i%3 == 0) {
println("FizzBuzz")}
else if(i%5 == 0) {
println("Buzz")}
else if(i%3 == 0){
println("Fizz")}
else {
println(i)
}
}
You are using || instead of &&.
Replace:
if (i%5 == 0 || i%3 == 0) {
println("FizzBuzz")
}
With:
if (i%5 == 0 && i%3 == 0) {
println("FizzBuzz")
}
Or with:
if (i%15 == 0) {
println("FizzBuzz")
}
The more elegant solution is:
fun fizzBuzz(currentNumber: Int) = when {
currentNumber % 15 == 0 -> "FizzBuzz"
currentNumber % 3 == 0 -> "Fizz"
currentNumber % 5 == 0 -> "Buzz"
else -> "$currentNumber"
}
for (currentNumber in 1..100) {
print(fizzBuzz(currentNumber))
}

Can not assert the value from Dafny method

This is the code for Bulls and Cows game, simply it just we have 2 array a[] and b[] with the same length, if a[i] == b[i] then Bulls += 1, if a[i] in b && a[i] != b[i] then Cows += 1.
I have written the Bulls and Cows function, but the method BullCows have some problem when calculate it, it make my assert fail.
`
function bullspec(s:seq<nat>, u:seq<nat>): nat
requires |s| > 0
requires |u| > 0
requires |s| == |u|
{
var index:=0;
if |s| == 1 then (
if s[0]==u[0]
then 1 else 0
) else (
if s[index] != u[index]
then bullspec(s[index+1..],u[index+1..])
else 1+bullspec(s[index+1..],u[index+1..])
)
}
function cowspec(s:seq<nat>, u:seq<nat>): nat
requires |s| > 0
requires |u| > 0
requires |s| <= |u|
{
var extra:= |u|-|s|;
var index:=0;
if |s| == 1 then (
if s[0] in u
then 1 else 0
) else(
if s[index] in u && s[index]!=u[extra]
then (1+ cowspec(s[index+1..],u))
else cowspec(s[index+1..],u)
)
}
method BullsCows (s:seq<nat>, u:seq<nat>) returns (b:nat, c:nat)
requires |s|>0 && |u|>0 &&|s|==|u|
// No duplicates in array
requires forall i, j | 0 <= i < |s| && 0 <= j < |s| && i != j :: s[i] != s[j]
requires forall i, j | 0 <= i < |u| && 0 <= j < |u| && i != j :: u[i] != u[j]
ensures forall k :: 0 <= k < |s| && s[k] !in u ==> b == c == 0
ensures forall k :: 0 <= k < |s| && s[k] in u ==> (c + b) > 0
{
var index := 0;
b := 0;
c := 0;
while(index<|s|)
invariant index <= |s|
invariant forall k :: 0 <= k < index && s[k] in u ==> (b + c) > 0
{
if s[index] in u {
if s[index] == u[index]{
b:=b+1;
} else {
c:=c+1;
}
}
index:=index + 1;
}
}
method NotMain()
{
var sys:seq<nat> := [4,2,9,3,1];
var usr:seq<nat> := [1,2,3,4,5];
assert bullspec(sys, usr) == 1; //True
assert cowspec(sys, usr) == 3; //True
var b:nat, c:nat := BullsCows(sys, usr);
assert b == 1; //Not true
assert c == 3; //Not true
}
`
The method NotMain said that assert b == 1; and assert c==3; are not true, this is Dafny language, please could someone help me with this logical, I'm banging my head.
I try put on many ensures in the BullsCows method but there's nothing happen
The problem is that the postcondition on BullsCows() is not strong enough to prove the final two assertions. In particular, there is no connection between the operation of BullsCows() and the specifications bullspec() and cowspec(). You need to connect these things together.
To illustrate I'm going to use a simpler example which is easier to follow. As for your example above, the final assertion fails in the following:
function sumspec(xs: seq<nat>, i: nat) : nat
requires i <= |xs| {
if |xs| == 0 || i == 0 then 0
else sumspec(xs,i-1) + xs[i-1]
}
method sum(s:seq<nat>) returns (r:nat) {
r := 0;
for i := 0 to |s| {
r := r + s[i];
}
return r;
}
method main() {
assert sumspec([1,2,3],3) == 6;
var r := sum([1,2,3]);
assert r == 6;
}
Whilst sumspec() is a valid specification for sum() we have not connected these two things. As such, Dafny assumes that sum() can return any value for r!
To connect the specification (sumspec) with its implementation (sum) we need a stronger postcondition:
method sum(s:seq<nat>) returns (r:nat)
ensures r == sumspec(s,|s|) {
r := 0;
for i := 0 to |s|
invariant r == sumspec(s,i) {
r := r + s[i];
}
return r;
}
Here, r == sumspec(s,|s|) connects the specification with the result of our implementation. We also added a loop invariant to help Dafny show this postcondition holds.

IntelliJ gives incorrect "Condition is always false" warning

I am learning Kotlin by doing exercises on exercism.com. I am currently working on triangles. Part of my solution is like this:
class Triangle<out T : Number>(a: T, b: T, c: T) {
init {
require (a != 0 && b != 0 && c != 0)
}
}
On the line with require(), IntelliJ gives the warning:
Condition 'a != 0 && b != 0' is always false
Condition 'a != 0 && b != 0 && c != 0' is always false
I have the following tests:
class TriangleTest {
#Test
fun `equilateral - all sides are equal`() {
assertTrue(Triangle(2, 2, 2).isEquilateral)
}
#Test(expected = IllegalArgumentException::class)
fun `equilateral - all zero sides is not a triangle`() {
assertFalse(Triangle(0, 0, 0).isEquilateral)
}
}
Both of these pass. If IntelliJ's warning were correct, then one of these would fail. Why does IntelliJ give this incorrect warning?

how can i use return# with if expression in kotlin?

What should I use instead of the whats_there parameter so the value of x will be 0?
val x =
if (true) {
for (i in 1..5)
if (i == 4)
return#whats_there 0
1
}
else 2
val x = if (ok) run {
for (i in 1..5) {
if (i == someValue)
return#run 10
}
5
} else 2
or
val x = if (ok) {
if (someValue in 1..5) 10 else 5
} else 2
Using a return like that is hard to read and prone to error.  This example is probably too simplified to show your real problem, but it looks like you could use any(), e.g.:
val x =
if (true) {
if ((1..5).any{ it == 4 })
0
else
1
} else
2
That probably expresses your intent better than a loop would.
You might find it even clearer to re-order the cases, so you can use a when:
val x = when {
!true -> 2
(1..5).any{ it == 4 } -> 0
else -> 1
}
in order to solve my problem i used #IR42 first solution, but i had to use it a bit differently:
val x = run {
if (ok){
for (i in 1..5)
if (i == someValue)
return#run 10
5
}
else 2
}

How do you count the variable changing in iteration of 1's

"value" can only either be 0, 60, 120, 180, 240 or 300.
When I try to count each change that "value" has using iterations I'm not getting values of +1. It gives values which are stepping by 10000. Also I do not wish to iterate when a value is reached, I only wish to iterate when it has changed one of the 6 values.
#include <stdio.h>
int angles;
int counter[6] = {0, 60, 120, 180, 240, 300};
if (a == 1 && b == 1 && c == 0)
{
value = 0;
}
if (a == 1 && b == 0 && c == 0)
{
value = 60;
}
if (a == 1 && b == 0 && c == 1)
{
value = 120;
}
if (a == 0 && b == 0 && c == 1)
{
value = 180;
}
if (a== 0 && b == 1 && c == 1)
{
value= 240;
}
if (a == 0 && b == 1 && c == 0)
{
value = 300;
}
2**3 == 8
You are missing conditions for some of the possible combinations of values.
I would put the conditions into a function and return the desired value as soon as it has been determined because that allows to sort out the conditions. Doing that, you will inevitably notice that you do not know what to return in some cases.
Other than that, it´s not clear to me what you are trying to achieve.
Something like this:
#define ERROR -1
int get_value(int a, int b, int c)
{
if(a)
{
if(b)
{
return c ? ERROR : 0;
}
else
{
return c ? 60 : 120;
}
}
else
{
if(b)
{
return c ? 240 : 300;
}
else
{
return c ? 180 : ERROR;
}
}
return ERROR;
}
I would probably avoid all this, consider each of the three values as one bit and use bit operators to get to the desired value.