Is there a method we use to reach the desired number in an array given in dart language.. I can do this for binary ones, but I can't do it for a code that finds the sum of 3 or more elements
For example
Input: candidates = [10,1,2,7,6,1,5], target = 8
Output:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
this is the my code i have done until now
void main() {
var candidates = [10, 1, 2, 7, 6, 1, 5], target = 8;
var answer = [];
for (int i = 0; i < candidates.length; i++) {
for (int j = 0; j < candidates.length; j++) {
if (candidates[i] + candidates[j] == target && i != j && i < j) {
answer.add([candidates[i], candidates[j]]);
}
}
}
}
I am sure this can be done more efficient but since the solution is for some Leetcode assignment, I don't really want to spend too much time on optimizations.
I have tried added some comments in the code which explains my way of doing it:
void main() {
getSumLists([10, 1, 2, 7, 6, 1, 5], 8).forEach(print);
// [5, 1, 2]
// [1, 6, 1]
// [1, 7]
// [6, 2]
getSumLists([2, 5, 2, 1, 2], 5).forEach(print);
// [2, 1, 2]
// [5]
}
Iterable<List<int>> getSumLists(
List<int> candidates,
int target, {
List<int>? tempAnswer,
int sum = 0,
}) sync* {
// We cannot use default value in parameter since that makes list const
final tempAnswerNullChecked = tempAnswer ?? [];
if (sum == target) {
// We got a result we can return.
// OPTIMIZATION: If you know the returned list from each found result is not
// being used between found results, you can remove the `.toList()` part.
yield tempAnswerNullChecked.toList();
} else if (sum > target) {
// No need to search further in this branch since we are over the target
return;
}
// Make a copy so we don't destroy the input list but also so it works even
// if provided list as input is non-growing / non-modifiable
final newCandidates = candidates.toList();
while (newCandidates.isNotEmpty) {
// We take numbers from the end of the list since that is more efficient.
final number = newCandidates.removeLast();
// Recursive call where we return all results we are going to find given
// the new parameters
yield* getSumLists(
newCandidates,
target,
tempAnswer: tempAnswerNullChecked..add(number),
sum: sum + number,
);
// Instead of creating a new tempAnswerNullChecked, we just reuse it and
// make sure we remove any value we are temporary adding
tempAnswerNullChecked.removeLast();
// Ensure we don't get duplicate combinations. So if we have checked the
// number `1` we remove all `1` so we don't try the second `1`.
newCandidates.removeWhere((element) => element == number);
}
}
Related
In Python, you can specify a "step" argument to a list slice that specifies the separation between indices that are selected to be in the slice:
my_list[start:stop:step]
However, none of the list methods in Dart seem to offer this functionality: sublist and getRange just take the start and end index.
How can I do this in Dart without using an ugly for-loop?
For example, to select only the even indices of a list I currently see no alternative to this:
List<Object> myList = ...;
List<Object> slice = [];
for (var i = 0; i < myList.length; i += 2) {
slice.add(myList[i]);
}
Or slightly less ugly with a list comprehension:
[for (var i = 0; i < myList.length; i += 2) myList[i]]
I could write my own function or extension method, but that defeats the purpose, I'm looking for ideally a built-in or a third package solution.
For this you can create extension on list to return custom result.
List<T> slice([int? start, int? end, int? step]) {
if (start == null && end == null && step == null) {
return this!;
} else if (start != null && end == null && step == null) {
return this!.sublist(start);
} else if (start != null && end != null && step == null) {
return this!.sublist(start, end);
} else if (start != null && end != null && step != null) {
// iterate over the list and return the list
// iterator start from start index
// iterator end at end index
// iterator step by step
final list = <T>[];
for (var i = start; i < end; i += step) {
list.add(this![i]);
}
return list;
} else {
return this!;
}
}
You can use the slice extension on any list. Below are examples of how to use it.
Example 1
This example will return the slice list of the list depending starting and ending index.
final list1 = [1, 2, 3, 4, 5];
final result = list1.slice(1, 4);
print(result); // [2, 3, 4]
Example 2
This example will return the slice list of the list depending starting index.
final list1 = [1, 2, 3, 4, 5];
final result = list1.slice(1);
print(result); // [2, 3, 4, 5]
Complate program.
You can run this example in Dartpad to check results.
void main() {
final list1 = [1, 2, 3, 4, 5,6,7,8,9,10,11,12,13,14,15,15,17,18,19,20];
// Example - 1
final result = list1.slice(1, 4);
print(result); // [2, 3, 4]
//Example - 2
final result2 = list1.slice(10);
print(result2); // [11, 12, 13, 14, 15, 15, 17, 18, 19, 20]
//Example - 3
final result4 = list1.slice(4, 10, 2);
print(result4); // [5, 7, 9]
//Example - 4
final result3 = list1.slice();
print(result3); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 17, 18, 19, 20]
}
extension ListHelper<T> on List<T>? {
List<T> slice([int? start, int? end, int? step]) {
if (start == null && end == null && step == null) {
return this!;
} else if (start != null && end == null && step == null) {
return this!.sublist(start);
} else if (start != null && end != null && step == null) {
return this!.sublist(start, end);
} else if (start != null && end != null && step != null) {
// iterate over the list and return the list
// iterator start from start index
// iterator end at end index
// iterator step by step
final list = <T>[];
for (var i = start; i < end; i += step) {
list.add(this![i]);
}
return list;
} else {
return this!;
}
}
}
You can easily create your own slice method in Dart.
The first thing to decide is whether you want it to be lazy or eager—does it create a list or an iterable.
The traditional Dart way would be an iterable, created from another iterable, which is also slightly more complicated to write.
extension LazySlice<T> on Iterable<T> {
/// A sub-sequence ("slice") of the elements of this iterable.
///
/// The elements of this iterable starting at the [start]th
/// element, and ending before the [end]th element, or sooner
/// if this iterable has fewer than [end] elements.
/// If [end] is omitted, the sequence continues
/// to the end of this iterable.
/// If [step] is provided, only each [step]th element of the
/// [start]..[end] range is included, starting with the first,
/// and skipping `step - 1` elements after each that is included.
Iterable<T> slice([int start = 0, int? end, int step = 1]) {
// Check inputs.
RangeError.checkNotNegative(start, "start");
if (end != null && end < start) {
throw RangeError.range(end, start, null, "end");
}
if (step < 1) {
throw RangeError.range(step, 1, null, "step");
}
// Then return an iterable.
var iterable = this;
if (end != null) iterable = iterable.take(end);
if (start > 0) iterable = iterable.skip(start);
if (step != 1) iterable = iterable.step(step);
return iterable;
} // slice
/// Every [step] element.
///
/// The first element of this iterable, and then every
/// [step]th element after that (skipping `step - 1`
/// elements of this iterable between each element of
/// the returned iterable).
Iterable<T> step(int step) {
if (step == 1) return this;
if (step < 1) {
throw RangeError.range(step, 1, null, "step");
}
return _step(step);
}
/// [step] without parameter checking.
Iterable<T> _step(int step) sync* {
var it = iterator;
if (!it.moveNext()) return;
while (true) {
yield it.current;
for (var i = 0; i < step; i++) {
if (!it.moveNext()) return;
}
}
} // _step
} // extension LazySLice
Working with a list is much easier:
extension EagerSlice<T> on List<T> {
List<T> slice([int start = 0, int? end, int step = 1]) {
if (step == 1) return sublist(start, end); // Checks parameters.
end = RangeError.checkValidRange(start, end, length);
if (step < 1) {
throw RangeError.range(step, 1, null, "step");
}
return <T>[for (var i = start; i < end; i += step) this[i]];
}
}
(Effectively the same approach proposed by #Anakhand in the comments above, just with better parameter checking.)
The list approach is easier, mainly because we don't already have a step method on iterables, which picks every nth element.
I'm really confused on how I'm gonna find the index of item in array where there's a lot of duplicated words.
List<String> _words = "the quick brown fox jumps over the lazy dog".split(" ");
now I want to get the all the index in word "the" programmatically.
I expect a result of
List indexOfWords = _words.indexOfAll("the");
print(indexOfWords);
// [0, 6]
You can define indexOfAll as an extension method. I would implement it like this:
extension ListExtension<T> on List<T> {
List<int> indexOfAll(T item) => [
for (int i = 0; i < length; i++)
if (this[i] == item) i,
];
}
You can create an extension method. like this:
extension Occurrences on List {
List<int> indexOfAll(String pattern) {
List<int> indexes = [];
for (int i = 0; i < this.length; i++) {
if (this[i] == pattern) {
indexes.add(i);
}
}
return indexes;
}
}
then you can use it as function on your list
print(_words.indexOfAll("the")); // [0, 6]
I don't know if there is a direct solution for this job. To solve this problem I developed a function called GetIndexes() and it works successfully.
This example prints the following output to the console:
[the, quick, brown, fox, jumps, over, the, lazy, dog]
[3, 9, 15, 19, 25, 30, 34, 39]
The solution I developed is available below:
void main()
{
String text = "the quick brown fox jumps over the lazy dog";
var split = ' ';
List<int> indexes = [];
List<String> words;
words = text.split(split);
GetIndexes(text, split, indexes);
print(words);
print(indexes);
}
void GetIndexes(String text, var split, List<int> indexes)
{
int index = 0;
for(int i=0 ; i<text.length; ++i)
{
if(text[i] == split)
{
indexes.insert(index, i);
++index;
}
}
}
I need to get all possible subsets of an array.
Say I have this:
<int>[1, 2, 3]
How do I get this?
[], [1], [2], [3],[1, 2], [2, 3], [1, 3], [1, 2, 3]
I am interested in all subsets. For subsets of specific length, refer to the following questions:
How to find all subsets of a set in JavaScript?
Here is my take on it, with only native function as in your link:
List getAllSubsets(List l) => l.fold<List>([[]], (subLists, element) {
return subLists
.map((subList) => [
subList,
subList + [element]
])
.expand((element) => element)
.toList();
});
If you want a specific size:
List getSizedSubsets(List l, int size) =>
getAllSubsets(l).where((element) => element.length == size).toList();
I'd probably go with something simple like:
Iterable<Set<E>> subsets<E>(Set<E> elements) sync* {
if (elements.length >= 32) {
// Otherwise there'll be more than 2^32 subsets. And bitops will overflow in JS.
throw ArgumentError.value(elements, "elements", "must have less than 32 elements");
}
var list = [...elements];
var subsetCount = 1 << list.length;
for (var i = 0; i < subsetCount; i++) {
yield {
for (var j = 0, bit = 1; j < elements.length; j++, bit <<= 1)
if (i & bit != 0) list[j]
};
}
}
Another approach is to only have one set, and then update it iteratively to contain different elements. It's possible to go through all the sets doing only single-element changes on each step (using Gray-code):
/// Iterates a set through all combinations of its elements.
///
/// Adds and removes elements from [set] to make it iterate through all
/// possible combinations of its initial elements.
/// The current value of the iterator is always [set].
/// If iterated through to the end, the [set] ends up with all its original elements.
Iterable<Set<E>> subsets<E>(Set<E> set) sync* {
if (set.length >= 32) {
throw ArgumentError.value(set, "set", "must have less than 32 elements");
}
var list = [...set];
var prev = 0;
var counter = 0;
do {
yield set;
var next = ++counter ^ (counter >> 1);
var bit = prev ^ next; // One bit set.
var index = bit.bitLength - 1;
if (index >= list.length) index = 0;
var element = list[index];
if (next & bit == 0) {
set.add(element);
} else {
set.remove(element);
}
prev = next;
} while (set.length < list.length);
}
I would like to get the second to last item in a List, similarly than with getter last.
I tried the following :
final list = [1, 2, 3, 4, 5];
final secondToLast = (list..removeLast()).last; // Mutates the List
However it mutates the List.
There is many options available (however you should make sure that list is not null and has at least 2 elements) :
final list = [1, 2, 3, 4, 5];
// Works only for Lists
final secondToLast = list[list.length - 2];
final secondToLast = list.reversed.elementAt(1);
final secondToLast = list.reversed.skip(1).first;
// Works for any Iterable
final secondToLast = list.elementAt(list.length - 2);
To get something similar to last, you can write an extension on Iterable :
extension CustomIterable<T> on Iterable<T> {
T? get secondToLast {
return this == null || length < 2 ? null : elementAt(length - 2);
}
}
Ok guys, i've tried this:
List<num> test
for(num i = ...){
test[i]...
(...)
for(num j = ...){
test[i][j] = ...
}
}
today but didn't seem to work. My question is... Is there a way to make this in Dart? :)
Here is one way to do it:
main() {
List<List<int>> matrix = new List<List<int>>();
for (var i = 0; i < 10; i++) {
List<int> list = new List<int>();
for (var j = 0; j < 10; j++) {
list.add(j);
}
matrix.add(list);
}
print(matrix);
print(matrix[2][4]);
}
If you know the length ahead of time, and it won't change, you can pass the length to the constructor:
main() {
int size = 10;
List<List<int>> matrix = new List<List<int>>(size);
for (var i = 0; i < size; i++) {
List<int> list = new List<int>(size);
for (var j = 0; j < size; j++) {
list[j] = j;
}
matrix[i] = list;
}
print(matrix);
print(matrix[2][4]);
}
Notice the main difference. In the first example, the list is created empty, so the loops need to explicitly add elements to the list. In the second example, the list is created with a fixed size, with null elements at each index.
Changelog: The original version of the second example used the List.fixedLength(size) constructor, which existed before Dart 1.0.
One way to construct a list with a different value in each position is to use the idiom
new Iterable.generate(size, function).toList()
makeMatrix(rows, cols) =>
new Iterable<List<num>>.generate(
rows,
(i) => new List<num>.fixedLength(cols, fill: 0)
).toList();
main() {
print(makeMatrix(3, 5));
}
prints: [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
It is slightly annoying that to get the fill: parameter you have to construct a fixed length list. Without a fill value, the inner lists would contain nulls. One way to get an extendable list with an initial value is to create an empty list and grow it.
(i) => <num>[]..insertRange(0, cols, 0)
This is using a method cascade to modify the list before returning it - a..b()..c() calls a.b() and a.c() before returning a. This is handy as it avoids the need for a temporary variable.
Note that, for some reason, insertRange has a positional rather than a named fill parameter.
If you want more control over the contents, you can extend the generate-to-list idea to two levels:
makeMatrix(rows, cols, function) =>
new Iterable<List<num>>.generate(
rows,
(i) => new Iterable<num>.generate(cols, (j) => function(i, j)).toList()
).toList();
main() {
print(makeMatrix(3,5, (i, j) => i == j ? 1 : 0));
}
prints: [[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0]]
There are some excellent libraries on pub for handling matrices (like Kevin Moore's BOT for example), but if your looking for something quick, you can just do:
List<List> test = new List<List>(n);
for (var i = 0; i < n; i++) {
test[i] = new List(n);
}
for (var i = 0; i < n; i++) {
for (var j = 0; j < n; j++) {
test[i][j] = myValue;
}
}