How to break from middle of generator in dart? - dart

How can I break from dart generator based on some condition?
fn sync*(...){
yield 1;
yield 2;
if(someCondition()) //cancel/break the generator
yield 3;
if(someCondition2()) //cancel/break the generator
yield 4;
if(someCondition4()) //cancel/break the generator
yield 5;
}

Simply return from your generator when you want it to stop generating new values:
Iterable<int> fn(bool flag) sync* {
yield 1;
yield 2;
if (flag) {
return;
}
yield 3;
}
void main() {
print(fn(true).toList()); // Prints: [1, 2]
print(fn(false).toList()); // Prints: [1, 2, 3]
}

Related

Quick sort throws a 'not in inclusive range' error but sometimes it works. (Dart)

I have implemented a quick sort algorithm in Dart which sorts a list of random integers in the range from 0 to 100. Most of the times, it throws a 'not in inclusive range' exception. Other times, it works. I don't understand what is wrong with my code or logic here.
import 'dart:math';
List<int> list = [];
void main() {
randomize();
quickSort(0, list.length - 1);
print(list);
}
void randomize() {
for (int i = 0; i < 100; ++i) {
list.add(Random().nextInt(100));
}
}
void quickSort(int l, int h) {
if (l < h) {
int mid = partition(l, h);
quickSort(l, mid - 1);
quickSort(mid + 1, h);
}
}
int partition(int l, int h) {
int pivot = l;
int i = l;
int j = h;
while (i < j) {
while (list[i] <= list[pivot]) {
++i;
}
while (list[j] > list[pivot]) {
--j;
}
if (i < j) {
int temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
int temp = list[pivot];
list[pivot] = list[j];
list[j] = temp;
return j;
}

How I can solve this problem? "The argument type 'int?' can't be assigned to the parameter type 'num'." (Dart)

I'm trying to write a code which print the sum of odd and even numbers from a group of inputs, but it doesn't work and I think it's a null safety issue.
This is the code
void main() {
List numbers = [1, 2, 3, 4];
List odd = [];
List even = [];
for (int i = 0; i < numbers.length; i++) {
var z = numbers[i] % 2;
if (z == 0) {
even.add(numbers[i]);
} //end if
else {
odd.add(numbers[i]);
} //end else
} //end for loop
int sumOdd = 0;
int sumEven = 0;
for (int i = 0; i < odd.length; i++) {
sumOdd = sumOdd + odd[i];
}//end for
for (int i = 0; i < even.length; i++) {
sumEven = sumEven + even[i];
}//end for
print("sum of odds numbers = $sumOdd");
print("sum of even numbers = $sumEven");
} //end main
i think its because you not specify the type of list.
by default it will define as a list of number.
but int sumOdd = 0; you define as integer.
thats why you got error when run here : sumOdd = sumOdd + odd[i];
sumOdd is integer
odd[i] is number .
solution:
List<int> numbers = [1, 2, 3, 4];
List <int> even =[];
List<int> odd =[];
second solution
you can parse odd[i] to integer

How to create ArrayAddition function using dart

What is the right syntax in dart for the below js code:
I am trying to create a function ArrayAddition(arr) take the array
of numbers stored in arr and return the string true if any combination of numbers
in the array can be added up to equal the largest number in the array, otherwise
return the string false. For example: if arr contains [4, 6, 23, 10, 1, 3] the
output should return true because 4 + 6 + 10 + 3 = 23.
function ArrayAddition(arr) {
arr.sort(function(a,b){return a - b});
var maxNum = arr.pop();
var tot = 0;
for (var i = 0; i < arr.length; i++){
tot += arr[i];
for (var j = 0; j < arr.length; j++){
if (i != j) {
tot += arr[j];
if (tot == maxNum) {
return true;
}
}
}
for (var k = 0; k < arr.length; k++) {
if (i != k) {
tot -= arr[k];
if (tot == maxNum) {
return true;
}
}
}
tot = 0;
}
return false;
}
So what is the rightt syntax for this in dart language?
It's almost the exact same code, just change the following lines:
function ArrayAddition(arr) {
to
bool ArrayAddition(List<int> arr) {
arr.sort(function(a,b){return a - b});
to
arr.sort((a, b) => a - b);
var maxNum = arr.pop();
to
var maxNum = arr.removeLast();

Dart While Loop usage

i have a logic mistake but i cant figure out, loop not stops when num= returnitemcount ?
void main() {
List<int> listAll = [1, 2, 3, 4, 5, 6, 7, 8, 9];
List<int> exceptions = [2, 3, 4];
List<int> exceptedlist(
int returnitemcount, List<int> exceptions, List<int> listfrom) {
List<int> returnlist = [];
int num = 0;
while (num < returnitemcount) {
for (var i = 0; i < listfrom.length; i++) {
if (!exceptions.contains(listfrom[i])) {
returnlist.add(listfrom[i]);
num++;
}
}
}
return returnlist;
}
List<int> mylist = exceptedlist(3, exceptions, listAll);
print(mylist);
// expected => 1,5,6
// result => 1, 5, 6, 7, 8, 9
}
Your problem is that your while are only evaluated twice. The first time num is 0 and the second time it is 6. It is not evaluated every time num is updated.
while loops does not mean that the code inside the block are running as long some statement are true. It means the code will loop as long the statement are true.
So what you need to do is to check num every time you update the value. Something like this:
void main() {
List<int> listAll = [1, 2, 3, 4, 5, 6, 7, 8, 9];
List<int> exceptions = [2, 3, 4];
List<int> exceptedlist(
int returnitemcount, List<int> exceptions, List<int> listfrom) {
List<int> returnlist = [];
int num = 0;
while (num < returnitemcount) {
for (var i = 0; i < listfrom.length; i++) {
if (!exceptions.contains(listfrom[i])) {
returnlist.add(listfrom[i]);
if (++num >= returnitemcount) {
break;
}
}
}
}
return returnlist;
}
List<int> mylist = exceptedlist(3, exceptions, listAll);
print(mylist); // [1, 5, 6]
}
I am not sure what you code are going to do exactly but you should be able to skip the while loop:
void main() {
List<int> listAll = [1, 2, 3, 4, 5, 6, 7, 8, 9];
List<int> exceptions = [2, 3, 4];
List<int> exceptedlist(
int returnitemcount, List<int> exceptions, List<int> listfrom) {
List<int> returnlist = [];
for (var i = 0; i < listfrom.length; i++) {
if (!exceptions.contains(listfrom[i])) {
returnlist.add(listfrom[i]);
if (returnlist.length >= returnitemcount) {
break;
}
}
}
return returnlist;
}
List<int> mylist = exceptedlist(3, exceptions, listAll);
print(mylist); // [1, 5, 6]
}
And can properly even be shorten into:
void main() {
final listAll = [1, 2, 3, 4, 5, 6, 7, 8, 9];
final exceptions = [2, 3, 4];
final mylist = exceptedlist(3, exceptions, listAll);
print(mylist); // [1, 5, 6]
}
List<int> exceptedlist(
int returnitemcount, List<int> exceptions, List<int> listfrom) =>
listfrom
.where((element) => !exceptions.contains(element))
.take(returnitemcount)
.toList();

Dart - Matrix Spiral

I'm trying to solve this common interview question but I'm getting a RangeError: Valid value range is empty in the body of the first for loop (results[startColumn][i] = counter;)
The problem is Given an integer n, generate a square matrix filled with elements in spiral order.
For example, Given n = 3,
You should return the following matrix: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
This is my solution:
void matrix(int n) {
List<List> results = [];
for (var i = 0; i < n; i++) {
results.add([]);
}
int counter = 1;
int startColumn = 0;
int endColumn = n - 1;
int startRow = 0;
int endRow = n - 1;
while (startColumn <= endColumn && startRow <= endRow) {
// Top row
for (var i = startColumn; i <= endColumn; i++) {
results[startColumn][i] = counter;
counter++;
}
startRow++;
// Right column
for (var i = startRow; i <= endRow; i++) {
results[endColumn][i] = counter;
counter++;
}
endColumn--;
// Bottom row
for (var i = endColumn; i >= startColumn; i--) {
results[endRow][i] = counter;
counter++;
}
endRow--;
// Start column
for (var i = endRow; i >= startRow; i--) {
results[startColumn][i] = counter;
counter++;
}
startColumn++;
}
print(results);
}
Any ideas why its going out of bounds? 0,0 should really be the first index of the first inner List so I'm not sure why its out of bounds?
Well, the range error is about the results list is not initialized completely. You are inserting empty lists to the list but these lists are empty so you cannot ask for a specific element like
(not even for inserting an element to the list) results[startColumn][i].
So you need to specify a length to the lists you are adding to your results list:
final results = <List<int>>[];
for (var i = 0; i < n; i++) {
results.add(List<int>(n));
}
By making that change the code now "works" and gives the following results:
[[1, 8, 3], [null, 9, null], [7, 6, 5]]
Since your question was about the "range error" I guess fixing your matrix method is out of scope. But please tell me if you also want me to take a look at it. :)
Updated with answer to the Matrix problem
You were really close with the solution but with using a debugger it becomes clear that you have a problem when updating vertical rows. This can be seen when you makes the update for Right column and Start column.
The full solution looks like the following (I have added comments the two places I made some changes):
void matrix(int n) {
final results = <List<int>>[];
for (var i = 0; i < n; i++) {
results.add(List<int>(n));
}
int counter = 1;
int startColumn = 0;
int endColumn = n - 1;
int startRow = 0;
int endRow = n - 1;
while (startColumn <= endColumn && startRow <= endRow) {
// Top row
for (var i = startColumn; i <= endColumn; i++) {
results[startColumn][i] = counter;
counter++;
}
startRow++;
// Right column
for (var i = startRow; i <= endRow; i++) {
results[i][endColumn] = counter; // Switched i and endColumn
counter++;
}
endColumn--;
// Bottom row
for (var i = endColumn; i >= startColumn; i--) {
results[endRow][i] = counter;
counter++;
}
endRow--;
// Start column
for (var i = endRow; i >= startRow; i--) {
results[i][startColumn] = counter; // Switched i and startColumn
counter++;
}
startColumn++;
}
print(results);
}
And when running the code it should give the following results:
matrix(2); // [[1, 2], [4, 3]]
matrix(3); // [[1, 2, 3], [8, 9, 4], [7, 6, 5]]
matrix(4); // [[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]

Resources