Return Option inside Loop - while-loop

The program aims to use a loop to check if the index of a iterator variable meets certain criteria (i.g., index == 3). If find the desired index, return Some(123), else return None.
fn main() {
fn foo() -> Option<i32> {
let mut x = 5;
let mut done = false;
while !done {
x += x - 3;
if x % 5 == 0 {
done = true;
}
for (index, value) in (5..10).enumerate() {
println!("index = {} and value = {}", index, value);
if index == 3 {
return Some(123);
}
}
return None; //capture all other other possibility. So the while loop would surely return either a Some or a None
}
}
}
The compiler gives this error:
error[E0308]: mismatched types
--> <anon>:7:9
|
7 | while !done {
| ^ expected enum `std::option::Option`, found ()
|
= note: expected type `std::option::Option<i32>`
= note: found type `()`
I think the error source might be that a while loop evaluates to a (), thus it would return a () instead of Some(123). I don't know how to return a valid Some type inside a loop.

The value of any while true { ... } expression is always (). So the compiler expects your foo to return an Option<i32> but finds the last value in your foo body is ().
To fix this, you can add a return None outside the original while loop. You can also use the loop construct like this:
fn main() {
// run the code
foo();
fn foo() -> Option<i32> {
let mut x = 5;
loop {
x += x - 3;
for (index, value) in (5..10).enumerate() {
println!("index = {} and value = {}", index, value);
if index == 3 {
return Some(123);
}
}
if x % 5 == 0 {
return None;
}
}
}
}
The behaviour of while true { ... } statements is maybe a bit quirky and there have been a few requests to change it.

Related

Is there an alternative to this unsafe code for mutable index rust

I am making a chess game and I'm looking to return a mutable null character from an array of pieces when the index of the array (a Vec2 is out of bounds), the reason I need to do this is that my function for moving the piece needs a mutable reference to the Indexed piece, long story short I ended up needing to create a static NULL_PIECE that I could reference within the function but this is potentially quite dangerous as you'll see from my code
impl Index<IVec2> for Board {
type Output = Piece;
fn index(&self, index : IVec2) -> &Self::Output{
if (index.abs() != index) || (index.max_element() > WIDTH-1) {
&Piece('\0') // this works
} else {
let i : usize = (index.x + WIDTH* index.y).try_into().unwrap();
&self.pieces[i]
}
}
}
impl IndexMut<IVec2> for Board {
fn index_mut(&mut self, index: IVec2) -> &mut Self::Output{
if (index.abs() != index) || (index.max_element() > WIDTH-1) {
// &mut Piece('\0') // this does not work
unsafe {&mut NULL_PIECE} // this works but I don't like it
} else {
let i : usize = (index.x + WIDTH * index.y).try_into().unwrap();
&mut self.pieces[i]
}
}
}
There is a lot of potential for this to cause an error in the event that this mutates to be a piece because of the recursion I've implemented on the piece movement.
You can find the GitHub link here:
https://github.com/LyndonAlcock/chess_test/tree/main/src
Instead of implementing Index you could write it as:
impl Board {
fn get(&self, index: IVec2) -> Option<&Piece> {
if (index.abs() != index) || (index.max_element() > WIDTH-1) {
None
} else {
let i = (index.x + WIDTH* index.y).try_into().ok()?;
Some(&self.pieces[i])
}
}
fn get_mut(&mut self, index: IVec2) -> Option<&mut Piece> {
if (index.abs() != index) || (index.max_element() > WIDTH-1) {
None
} else {
let i = (index.x + WIDTH * index.y).try_into().ok()?;
Some(&mut self.pieces[i])
}
}
}
Index implementations should panic when the index is out of bounds.

If else on Mono if empty or has value

This is the sample code
repo1.findById( id )
.map( p -> {
if( p == null ){
return repo2.findById( id ).flatMap( g -> {
g.setValue("some value");
return g;
});
}
else{
return repo3.findById( id ).flatMap( h -> {
h.setValue("some value");
return h;
});
}
});
Any better way to do this ?. If else inside flat map does not look neat to me.
The idiomatic approach would be to use the switchIfEmpty() operator.
You would only proceed to use the call to repo3 if repo1 actually returns a result.
If not data matches repo1.findById(id), then this call would return an empty result, not null.
To cover this case, use switchIfEmpty().
public Mono<Data> load(String id){
return repo1.findById(id)
.flatMap(p -> {
return repo3.findById(id)
.flatMap(h -> {
h.setValue("some value");
return h;
});
})
.switchIfEmpty(repo2.findById(id)
.flatMap(g -> {
g.setValue("some value");
return g;
}));
}

Index out of bounds while checking if a string is rotated

// This function checks if two string are rotation of itself
//
// #Arguments
//
// 'str1' - a str type reference to store one string to check
// 'str2' - a str type reference to store other string to check
//
// #Return
//
// Return a bool value denoting if the string are rotation of each other
pub fn is_rotation(str1: &str, str2: &str) -> bool {
let len1 = str1.len();
let len2 = str2.len();
let string1: Vec<char> = str1.chars().collect();
let string2: Vec<char> = str2.chars().collect();
if len1 != len2 {
return false;
}
let mut longest_prefix_suffix = vec![0, len1];
let mut prev_len = 0;
let mut i = 1;
while i < len1 {
if string1[i] == string2[prev_len] {
prev_len += 1;
longest_prefix_suffix[i] = prev_len;
i += 1;
} else if prev_len == 0 {
longest_prefix_suffix[i] = 0;
i += 1;
} else {
prev_len = longest_prefix_suffix[prev_len - 1];
}
}
i = 0;
let mut k = longest_prefix_suffix[len1 - 1];
while k < len2 {
if string2[k] != string1[i] {
return false;
}
i += 1;
k += 1;
}
true
}
When I run the code, I receive the following error:
thread 'main' panicked at 'index out of bounds: the len is 2 but the index is 2', src/rotation.rs:29:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
How would I solve this?
It looks like there is a typo for longest_prefix_suffix. I assume you intended to write the following:
let mut longest_prefix_suffix = vec![0; len1];
Note the ; between 0 and len1.
The use of a , created a Vec with two elements.
Alternatively, an easier way might be the following:
fn is_rotation(s1: &str, s2: &str) -> bool {
if s1.len() != s2.len() {
return false;
}
s1.repeat(2).contains(&s2)
}
assert!(is_rotation("hello", "ohell") // true
assert!(is_rotation("hello", "olleh") // false

How to remake the program so that words are passed in function arguments in the KOTLIN programming language?

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) }
}

Appending a pointer to a Slice in Golang

I want to append a pointer to a slice.Is it possible..?In Partentnode.children is a slice I want to append it with X as pointer.
https://play.golang.org/p/ghWtxWGOAU
func Tree(Parentnode *Node) {
if IsvisitedNode(Parentnode.currentvalue - 1) {
m := MovesArray[Parentnode.currentvalue-1]
for j := 0; j < 8; j++ {
if m[j] != 0 {
var X *Node
X.parentnode = Parentnode
X.currentvalue = m[j]
if IsvisitedNode(m[j]) {
Parentnode.children = append(Parentnode.children, *X)
Tree(X)
}
}
}
}
}
You have a off by one error.
In main you set Y.currentvalue = 1.
Then in Tree currentvalue walks to 64.
X.currentvalue = m[j]
fmt.Printf("cv: %v\n",X.currentvalue) //walks to 64
if IsvisitedNode(m[j]) {
An in IsvisitedNode you test that index against visithistory that has 64 indexes, thus stops at index 63. -> index error
var visithistory [64]bool
func IsvisitedNode(position int) bool {
if visithistory[position] == true {
Things work if you set var visithistory [65]bool but I think you need to rethink you logic here somewhat.