I am attempting to compare Triples while disregarding certain values of the Triple. The value I wish to disregard below is signified by _. Note the below code is for example purposes and does not compile because _ is an Unresolved reference.
val coordinates = Triple(3, 2, 5)
when (coordinates) {
Triple(0, 0, 0) -> println("Origin")
Triple(_, 0, 0)-> println("On the x-axis.")
Triple(0, _, 0)-> println("On the y-axis.")
Triple(0, 0, _)-> println("On the z-axis.")
else-> println("Somewhere in space")
}
I know you can use _ when destructuring if you would like to ignore a value but that doesn't seem to help me with the above issue:
val (x4, y4, _) = coordinates
println(x4)
println(y4)
Any ideas how I can achieve this?
Thank you!
Underscore for unused variables was introduced in Kotlin 1.1 and it is designed to be used when some variables are not needed in the destructuring declaration.
In the branch conditions of your when expression, Triple(0, 0, 0) is creating an new instance but not destructuring. So, using underscore is not permitted here.
Currently, destructuring in the branch conditions of when expression is not possible in Kotlin. One of the solutions for your case is to compare each of the component verbosely in each branch condition:
val (x, y, z) = Triple(3, 2, 5)
when {
x == 0 && y == 0 && z == 0 -> println("Origin")
y == 0 && z == 0 -> println("On the x-axis.")
x == 0 && z == 0 -> println("On the y-axis.")
x == 0 && y == 0 -> println("On the z-axis.")
else -> println("Somewhere in space")
}
Here is a discussion on destructuring in when expression.
Related
Using Z3Py, once a model has been checked for an optimization problem, is there a way to convert ArithRef expressions into values?
Such as
y = If(x > 5, 0, 0.5 * x)
Once values have been found for x, can I get the evaluated value for y, without having to calculate again based on the given values for x?
Many thanks.
You need to evaluate, but it can be done by the model for you automatically:
from z3 import *
x = Real('x')
y = If(x > 5, 0, 0.5 * x)
s = Solver()
r = s.check()
if r == sat:
m = s.model();
print("x =", m.eval(x, model_completion=True))
print("y =", m.eval(y, model_completion=True))
else:
print("Solver said:", r)
This prints:
x = 0
y = 0
Note that we used the parameter model_completion=True since there are no constraints to force x (and consequently y) to any value in this model. If you have sufficient constraints added, you wouldn't need that parameter. (Of course, having it does not hurt.)
Assuming the post-condition, how can I compute the weakest pre-condition of a program containing two statements?
For example :
a=x;
y = 0
{x = y + a}
Another example:
y = x;
y = x + x + y
{y = 3x ^ z> 0}
I tried to solve them but both questions resulted in pre-conditions or post-condition that are identical to the statement and I don't know if this is valid.
for example, the precondition of the last statement is "y=x" , thus it is the post condition of the preceding statement which is " y=x" as well
You can apply the rules of Hoare Logic here. Specifically, for the examples you have, you only need the rule for assignment:
{ P[E/x] } x = E { P }
Here, P[E/x] means take P and substitute (i.e. replace) all occurrences of x with E. For example, if P is x == 0 then P[0/x] gives 0 == 0.
To calculate the weakest precondition, you start from the end and work backwards. For your first example, we start with the last statement:
{ ??? } y = 0 { x == y + a }
The goal is to determine something suitable for ???. Applying our rule for assignment above, we can see that this is a solution:
{ x == 0 + a } y = 0 { x == y + a }
We can further simplify this to { x == a }. Then, we move on to address the statement before y = 0, and so on.
I'd like to sum up consecutive numbers in a Kotlin list.
If the list has a 0 then it should start summing up the numbers after 0. The result would be a list of sums. Basically sum up until the first 0 then until the next 0 and so forth.
For example:
val arr = arrayOf(1, 2, 0, 2, 1, 3, 0, 4)
// list of sums = [3, 6, 4]
At the moment I got it working with fold:
val sums: List<Int> = arr.fold(listOf(0)) { sums: List<Int>, n: Int ->
if (n == 0)
sums + n
else
sums.dropLast(1) + (sums.last() + n)
}
but I wonder if there is a simpler or more efficient way of doing this.
I would personally have written it this way:
val sums = mutableListOf(0).also { acc ->
arr.forEach { if (it == 0) acc.add(0) else acc[acc.lastIndex] += it }
}
Using a mutable list, you avoid having to do any drop / concatenation. The code is also easier to follow.
You can still convert it to an immutable list using .toList() if you need to.
I would like to generate random floats for Quickcheck that are limited to a certain range such as 0.0 to 1.0 for testing functions working on probabilities. I would like to be able to do something where this would be successful:
quickcheck! {
fn prop(x: f64, y: f64) -> bool {
assert!(x <= 1.0);
assert!(y <= 1.0);
(x * y < x) && (x * y < y)
}
}
Create a new type that represents your desired range, then implement quickcheck::Arbitrary for it:
#[macro_use]
extern crate quickcheck;
#[derive(Debug, Copy, Clone)]
struct Probability(f64);
impl quickcheck::Arbitrary for Probability {
fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> Self {
Probability(g.gen_range(0.0, 1.0))
}
}
quickcheck! {
fn prop(x: Probability, y: Probability) -> bool {
let x = x.0;
let y = y.0;
assert!(x <= 1.0);
assert!(y <= 1.0);
(x * y < x) && (x * y < y)
}
}
Arbitrary is passed a type that implements quickcheck::Gen, which is a light wrapper on top of rand::Rng.
Note that Rng::gen_range has an exclusive upper bound, so this example isn't exactly what you want, but it shows the process.
Implementing Arbitrary for a new type is still probably the best way to do this, but gen_range() is now a private method, so you can't use that. As pointed out by the crate's author, you can use the modulus to restrict values to a range.
You can even do this without creating a new type (note that I'm using newer Rust syntax and the quickcheck_macros crate):
#[quickcheck]
fn prop(x: f64, y: f64) -> bool {
let x = x.abs() % 1.0;
let y = y.abs() % 1.0;
assert!(x <= 1.0);
assert!(y <= 1.0);
(x * y < x) && (x * y < y)
}
However, when it fails, it will report the original values of x and y, not the modified ones. So for better test failure reporting, you should use this in code similar to #Shepmaster's:
#[derive(Debug, Copy, Clone)]
struct Probability(f64);
impl quickcheck::Arbitrary for Probability {
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
Probability(f64::arbitrary(g).abs() % 1.0)
}
}
#[quickcheck]
fn prop2(x: Probability, y: Probability) {
let x = x.0;
let y = y.0;
// ...
}
Of course, once you do all this, you'll notice your code failing for two reasons:
Since x and y could be exactly equal to 1.0, that means it's not a strict inequality. The true comparison should actually be (x * y <= x) && (x * y <= y).
f64::arbitrary can return NaN. If you want to skip NaNs, you could do that by either:
Returning quickcheck::TestCase from prop(), and returning TestCase::discard() if it sees a NaN input, or:
Looping inside Probability::arbitrary until you generate a non-NaN number.
Say I have a List of records in elm:
[ { id = 1, magnitude = 100 }
, { id = 3, magnitude = 300 }
, { id = 2, magnitude = 200 } ]
and I want to get the record with the greatest magnitude value (300). What is a good way of doing this?
The docs gives an example of using the "maximum" -method, but it uses a simple list of integers. How is it done with records?
Update based on recommendation from #robertjlooby
There is a function called maximumBy which does exactly this in elm-community/list-extra. Example:
List.Extra.maximumBy .magnitude list
Original Answer
There are a few ways to achieve this.
This first way is more concise but it involves sorting the whole list, reversing it, then taking the head.
maxOfField : (a -> comparable) -> List a -> Maybe a
maxOfField field =
List.head << List.reverse << List.sortBy field
If you want something that's more efficient and only traverses the list once, here's a more efficient version:
maxOfField : (a -> comparable) -> List a -> Maybe a
maxOfField field =
let f x acc =
case acc of
Nothing -> Just x
Just y -> if field x > field y then Just x else Just y
in List.foldr f Nothing
An example of it in use:
list =
[ { id = 1, magnitude = 100 }
, { id = 3, magnitude = 300 }
, { id = 2, magnitude = 200 } ]
main =
text <| toString <| maxOfField .magnitude list
Here is a version that uses foldl and a default record:
bigger =
let
choose x y =
if x.magnitude > y.magnitude then
x
else
y
in
List.foldl choose {id = 0, magnitude = 0} items
Sebastian's answer add an arbitrary start value which could cause a problem if all your magnitudes were negative. I would adjust to
bigger items =
case items of
[] -> []
(h :: []) -> h
(h :: tail) ->
let
choose x y =
if x.magnitude > y.magnitude then
x
else
y
in
List.foldl choose h tail