Dart - Matrix Spiral - dart

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]]

Related

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();

How to make a docker image for AI created for connect 4

So I am working on creating a docker image that contains the AI for Connect 4. I have tried looking up tutorials and tried doing code but I am stuck. If you are in the defi space, you might have heard of golem network, I am currently just trying to implement Connect 4 into it. I would truly be happy with any help. Thx
Here is my code for the AI (this is currently not a docker image)
C4.AI = function(_game, _player, _strength) {
var _rack = _game.rack;
var _columns = _rack.length;
var _rows = _rack[0].length;
var _best_col = 0;
_player.human = false;
function findAndPlayMove() {
if (_game.current === _player) {
// Give the previous move's drop animation some time to finish
setTimeout(function() {
var best = alphabeta(_strength, -Infinity, Infinity, _player);
var r = _game.util.getDropRow(_best_col);
_game.trigger('drop', { col_index : _best_col });
_best_col = 0;
}, 500);
}
}
function alphabeta(depth, alpha, beta, player) {
var value = evaluateBoard(player);
// If maximum search depth is reached or this board is a win/loss we
// don't need to look further
if (depth === 0 || value === Infinity || value === -Infinity) {
return value;
}
// Calculate moves for this AI player
if (player === _player) {
var scores = [];
// For each column calculate the max possible score
// (player tries to maximize)
for (var c = 0; c < _columns; c++) {
var r = _game.util.getDropRow(c);
// This column is already full of coins
if (r === -1) continue;
// Temporarily store move
_rack[c][r] = player;
// Recursively calculate the best result this move could have
// for this player
alpha = Math.max(alpha, alphabeta(depth - 1, alpha, beta, player.opponent));
// Undo the move
delete _rack[c][r];
scores[c] = alpha;
if (beta <= alpha) break;
}
if (depth === _strength) {
var max_score = -Infinity;
var last_valid = null;
for (var i = 0; i < scores.length; i++) {
// TODO: find out why >= screws up AI
var score = scores[i];
if (score > max_score) {
max_score = score;
_best_col = i;
}
if (score) last_valid = i;
}
// All moves by player will lead to loss
// Just pick a valid column
if (max_score === -Infinity) {
_best_col = last_valid;
}
}
return alpha;
} else {
// For each column calculate the min possible score
// (opponent tries to minimize)
for (var c = 0; c < _columns; c++) {
var r = _game.util.getDropRow(c);
// This column is already full
if (r === -1) continue;
// Temporarily store move
_rack[c][r] = player;
// Recursively calculate the best result this move could have
// for oppponent
beta = Math.min(beta, alphabeta(depth - 1, alpha, beta, player.opponent));
// Undo the move
delete _rack[c][r];
// If the opponent's score for this column is <= to our player's
// maximum there's no need to further explore this branch: it
// would never lead to a better score
if (beta <= alpha) {
break;
}
}
return beta;
}
}
/* ################################################################################
UTILITIES
################################################################################ */
function evaluateBoard(player) {
// Some pre-calculated values for each rack position, based on the
// number of possible 4-in-a-rows a position could theoretically be part of
var values = [
[ 3, 4, 5, 5, 4, 3 ],
[ 4, 6, 8, 8, 6, 4 ],
[ 5, 8, 11, 11, 8, 5 ],
[ 7, 10, 13, 13, 10, 7 ],
[ 5, 8, 11, 11, 8, 5 ],
[ 4, 6, 8, 8, 6, 4 ],
[ 3, 4, 5, 5, 4, 3 ]
];
var patterns = {
'2 connected, empty on the left': {
rx: /__#{2}[^#_]/g,
value: 10
},
'2 connected, empty on the right': {
rx: /[^#_]#{2}__/g,
value: 10
},
'2 connected, empty on both sides': {
rx: /_#{2}_/g,
value: 20
},
'3 connected, empty on the left': {
rx: /_#{3}/g,
value: 50
},
'3 connected, empty on the right': {
rx: /#{3}_/g,
value: 50
},
'3 connected, empty middle left': {
rx: /#_#{2}/g,
value: 50
},
'3 connected, empty middle right': {
rx: /#{2}_#/g,
value: 50
},
'3 connected, empty on both sides': {
rx: /_#{3}_/g,
value: 100
}
};
var views = [
getSouthView(player),
getEastView(player),
getSouthWestView(player),
getSouthEastView(player)
];
var score = 0;
$.each(views, function(i, view) {
var player_view = view.replace(/X/g, '#');
var opponent_view = view.replace(/O/g, '#');
if (opponent_view.match(/#{4}/)) {
score = -Infinity;
return false;
}
if (player_view.match(/#{4}/)) {
score = Infinity;
return false;
}
$.each(patterns, function(name, pattern) {
var matches = player_view.match(pattern.rx);
if (matches) {
score += matches.length * pattern.value;
}
matches = opponent_view.match(pattern.rx);
if (matches) {
score -= matches.length * pattern.value;
}
});
});
return score;
}
function isCell(c, r) {
return 0 <= c && c < _columns && 0 <= r && r < _rows;
}
function getCellChar(c, r, player) {
var cell = _rack[c][r];
if (cell === _player) {
return 'X';
} else if (cell) {
return 'O';
}
return '_';
}
/* ################################################################################
VIEWS
################################################################################ */
function getEastView(player) {
var a = [];
for (var r = 0; r < _rows; r++) {
a.push('\n');
for (var c = 0; c < _columns; c++) {
a.push(getCellChar(c, r, player));
}
}
return a.join('') + '\n';
}
function getSouthView(player) {
var a = [];
for (var c = 0; c < _columns; c++) {
a.push('\n');
for (var r = 0; r < _rows; r++) {
a.push(getCellChar(c, r, player));
}
}
return a.join('') + '\n';
}
function getSouthWestView(player) {
var c = 0;
var r = 0;
var max = _columns * _rows;
var counter = 0;
var a = [];
a.push('\n');
while (counter != max) {
if (isCell(c, r)) {
var cell = _rack[c][r];
a.push(getCellChar(c, r, player));
counter++;
c++;
r--;
} else if (r < 0) {
a.push('\n');
r = c;
c = 0;
} else {
c++;
r--;
}
}
return a.join('') + '\n';
}
function getSouthEastView(player) {
var c = _columns - 1;
var r = 0;
var max = _columns * _rows;
var counter = 0;
var a = [];
a.push('\n');
while (counter != max) {
if (isCell(c, r)) {
var cell = _rack[c][r];
a.push(getCellChar(c, r, player));
counter++;
c--;
r--;
} else if (r < 0) {
a.push('\n');
r = _columns - c - 1;
c = _columns - 1;
} else {
c--;
r--;
}
}
return a.join('') + '\n';
}
_game.on('waitingForDrop', findAndPlayMove);
};

Try to calculate matrix but get RangeError (index): Index out of range: no indices are valid: 0

I am still new with dart, so I'm trying to figure things out. Right now, I tried to create matrix and calculate using this formula.
import 'dart:math';
​
void main() {
List<List<double>> normalisasi = new List<List<double>>();
​
List<List<double>> data = [
[10000000, 35, 110, 7],
[12000000, 45, 125, 6],
[15000000, 40, 150, 8],
[14000000, 37.5, 125, 7.5],
];
​
var bobot = [0.35, 0.25, 0.15, 0.25];
​
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data.length; j++) {
normalisasi[i][j] = data[i][j] / (pow(data[j][i], 2));
print(normalisasi[i][j]);
}
}
}
But I get this instead:
RangeError (index): Index out of range: no indices are valid: 0
Please help me, thank you.
Your normalisasi List is growable, therefore you need to use the 'add()' function to grow it. Alternatively, you can specify the fixed dimensions of the arrays on creation.
See fixed-size vs growable lists

Find maximum distance given a grid of nodes and a set of source nodes

Given a set of nodes arranged as an m by n grid (note: diagonal nodes are not connected), and a set of nodes marked as source nodes, find the maximum distance between nodes and the source nodes.
For example, for a 4 by 4 grid and a source node at (1, 0):
0 0 0 0
1 0 0 0
0 0 0 0
0 0 0 0
Computing the distance from each node to its closest source would produce:
1 2 3 4
0 1 2 3
1 2 3 4
2 3 4 5
And the maximum distance is therefore 5.
For a grid with more than 1 source, for example 3 source nodes:
0 0 1 0
1 0 0 0
0 0 0 0
0 0 0 1
Computing the distance from each node to its closest source would produce:
1 1 0 1
0 1 1 2
1 2 2 1
2 2 1 0
And the maximum distance is therefore 2.
I wrote up an algorithm that solves this, but it looks like the worst case scenario makes it run in O(n^4) (assume m == n):
// MaximumDistances.java
public class MaximumDistances {
public static void main(String[] args) {
int[][] sourceNodes = new int[][] {
{0, 0, 1, 0},
{1, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 1}
};
int maximumDistance = computeMaximumDistance(sourceNodes);
System.out.println(String.format(
"The maximum distance in this grid is %d.",
maximumDistance));
}
private static int computeMaximumDistance(int[][] sourceNodes) {
int m = sourceNodes.length;
int n = sourceNodes[0].length;
// Initializes the distance grid. Since none of the sites have been
// visited yet, the distance to any grid cell with be
// `Integer.MAX_VALUE`.
int[][] distanceGrid = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
distanceGrid[i][j] = Integer.MAX_VALUE;
}
}
// If we're at a source site, we mark its distance to each grid cell.
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (sourceNodes[i][j] == 1) {
markDistancesFromSourceSite(i, j, distanceGrid);
}
}
}
// The maximum value in the distance grid will be the maximum distance.
int maximumDistance = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (distanceGrid[i][j] > maximumDistance) {
maximumDistance = distanceGrid[i][j];
}
}
}
return maximumDistance;
}
private static void markDistancesFromSourceSite(int x, int y, int[][] distanceGrid) {
int m = distanceGrid.length;
int n = distanceGrid[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int distanceToSource = Math.abs(x - i) + Math.abs(y - j);
if (distanceGrid[i][j] > distanceToSource) {
distanceGrid[i][j] = distanceToSource;
}
}
}
}
}
Is there a faster algorithm that solves this?
Yes You can solve this problem using a concept called multisource BFS . The concept of multisource BFS is just like BFS but here is the minor difference .
In normal BFS we just push 1 node in the queue initially while in multisource BFS we push all the source nodes .
So after pushing all the source nodes we can just do the normal BFS operation to solve the problem .
The time complexity will be O(n*m) .
import java.util.*;
class Pair{
int x , y , dist;
Pair(int first , int second){
this.x = first;
this.y = second;
this.dist = 0;
}
Pair(int first , int second , int dist){
this.x = first;
this.y = second;
this.dist = dist;
}
}
public class MultisourceBFS {
public static void main(String[] args) {
int[][] sourceNodes = new int[][] {
{0, 0, 1, 0},
{1, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 1}
};
int maximumDistance = computeMaximumDistance(sourceNodes);
System.out.println(String.format(
"The maximum distance in this grid is %d.",
maximumDistance));
}
private static int computeMaximumDistance(int[][] sourceNodes) {
int m = sourceNodes.length;
int n = sourceNodes[0].length;
int maximumDistance = 0;
int xx[] = {0 , 0 , 1 , -1}; // Normal array to go to up , down , left , right;
int yy[] = {1 , -1 , 0 , 0}; // Normal array to go to up ,down , left , right
Queue<Pair> q = new LinkedList<Pair>();
boolean isVisited[][] = new boolean[m][n]; // An array to check if a cell is visited or not .
// I am adding all the source nodes to the queue
for(int i = 0 ; i < m ; ++i)
for(int j = 0 ; j < n ; ++j)
if(sourceNodes[i][j]==1){
q.add(new Pair(i , j));
isVisited[i][j] = true;
}
// Now it is going to be normal BFS
while(!q.isEmpty()){
Pair node = q.remove();
for(int k = 0 ; k < 4 ; ++k){
int new_i = node.x + xx[k];
int new_j = node.y + yy[k];
if(new_i >= 0 && new_i < m && new_j >= 0 && new_j < n && isVisited[new_i][new_j]==false){
maximumDistance = Math.max(node.dist + 1 , maximumDistance);
isVisited[new_i][new_j] = true;
q.add(new Pair(new_i , new_j , node.dist + 1));
}
}
}
return maximumDistance;
}
}

Resources