Minimax Algorithm - c#

ok my problem has changed my problem now is that im trying to use the minimax algorithm like that website explains http://neverstopbuilding.com/minimax
and it gives me this error: "Argument out of range exception"
why is it happening i cant tell why the exception happens
this is what i did:
int MiniMax(Seed[,] board, Seed currPlayer)
{
if (checkBoard1(this.board) != -1) return score();
List<int> scores = new List<int>();
List<Vector2> moves = generateMoves();
for (int i = 0; i < moves.Count; i++)
{
if (currPlayer == Seed.NOUGHT)
currPlayer = Seed.CROSS;
else
currPlayer = Seed.NOUGHT;
Seed[,] possibleBoard = getPossibleBoard(moves[i]);
scores.Add(MiniMax(possibleBoard, currPlayer));
}
if(currPlayer == Seed.NOUGHT)
{
int max_score_index = getMaxIndexFromList(scores);
choice = (Vector2)moves[max_score_index];
return scores[max_score_index];
}
else
{
int min_score_index = getMinIndexFromList(scores);
choice = (Vector2)moves[min_score_index];
return scores[min_score_index];
}
}
int getMinIndexFromList(List<int> list)
{
int min = list[0], minIndex = 0;
for (int i = 1; i < list.Count; i++)
{
if (list[i] < min)
{
min = list[i];
minIndex = i;
}
}
return minIndex;
}

Related

2D array 3x9 matrix get the index of the next two elements of the current index and check if it is equal to 0

I am a total newbie to programming and i have been following some tutorials on array related to housie ticket generator.The point where I am stuck is that, I have to check each rows and each rows of the 3x9 matrix should not have more the two empty cells or it cannot have more then two cells filled next to each other.I am putting random numbers on the arrays and trying to validate the rules but,the program crashes. Can someone please give me an idea.?
This is what i've tried.
for(int columnIndex=0;columnIndex<=6;columnIndex++)
{
if(game[i,columnIndex+2]!=0)
{
return -1;
}
}
And this is the whole code
using System;
namespace HelloWorld
{
class Program
{
public static void Main (String[] args)
{
for(int times=0;times<2;times++)
{
startGame();
Console.WriteLine("******************************************************************");
}
}
private static void startGame()
{
int[,] game = new int[3, 9];
int occupancyLimit = 15;
while (occupancyLimit > 0)
{
int i = getRandomNumber(3);
int j = getRandomNumber(9);
//Console.Write(i);
//Console.Write(j);
// Console.Write(game[i,j]+" ");
int data = validateAndReturnNumber(i, j, game);
if (data>0)
{
game[i, j] = data;
occupancyLimit--;
//Console.WriteLine(game[i,j]);
}
}
for (int i = 0; i < game.GetLength(0); i++)
{
for (int j = 0; j < game.GetLength(1); j++)
{
Console.Write(game[i,j] + "\t");
}
Console.WriteLine();
}
}
private static int validateAndReturnNumber(int i, int j, int[,] game)
{
//do not override existing elements in array
if (game[i,j] != 0)
{
return -1;
}
//column cannot have more then two elements
int columncounter = 0;
for(int c=0;c<3;c++)
{
if(game[c,j]!=0)
{
columncounter++;
}
}
if(columncounter>=2)
{
return -1;
}
/*
//rows cannot have more then two cells filled in and
//rows cannot have more then two empty cells
for(int columnIndex=0;columnIndex<=6;columnIndex++)
{
if(game[i,columnIndex+2]!=0)
{
return -1;
}
}
*/
// rows cannot have more then 5 elements
int rowcounter = 0;
for(int r=0;r<9;r++)
{
if(game[i,r]!=0)
{
rowcounter++;
}
}
//Applying, rows cannot have more then 5 elements
if(rowcounter>=5)
{
return -1;
}
//return getRandomNumberForColumn(j);
int data = 0;
Boolean isValueSet = false;
do
{
data = getRandomNumberForColumn(j);
isValueSet = isValueExistsInCol(game, i, j, data);
} while (isValueSet);
return data;
}
private static bool isValueExistsInCol(int[,] game, int i, int j, int data)
{
Boolean status = false;
for(int k=0;k<3;k++)
{
if(game[k,j]==data)
{
status = true;
break;
}
}
return status;
}
private static int getRandomNumberForColumn(int high)
{
if(high==0)
{
high = 10;
}
else
{
high=(high + 1) * 10;
}
int low = high - 9;
Random random = new Random();
return random.Next(high-low)+low;
}
private static int getRandomNumber(int max)
{
Random random = new Random();
int num=random.Next(max);
return (num);
}
}
}
Why your for loop does not work:
for (int columnIndex = 0; columnIndex <= 6; columnIndex++)
{
if (game[i, columnIndex + 2] != 0)
{
return -1;
}
}
This loop does not take j into account. It is testing for previous numbers added, as soon as one previous number fails this test, it will fail indefinitely. This creates an infinite loop. This loop also fails if a number is placed in any position past 1, while it needs to fill 5 positions to succeed. This is mathematically impossible.
This:
'should not have more the two empty cells or it cannot have more then two cells' is also mathematically impossible. a row of 9 cannot have less than 2 full and less than 2 empty at the same time.
I think you are after 2 empty or full consecutively in a row. For that testing for two empty in a row cannot be achieved as it starts empty, and you are testing it before you fill it. Fortunately this is a redundant test that will always be true based on all of the other test cases.
No more than 2 full in a row is possible, but can also lead to impossible scenarios. I have added a check that resets the scenario if it has not found the solution after 1000 guesses.
using System;
namespace HelloWorld
{
class Program
{
public static void Main(String[] args)
{
for (int times = 0; times < 2; times++)
{
startGame();
// Console.WriteLine("******************************************************************");
}
}
private static void startGame()
{
int iCount = 0;
int[,] game = new int[3, 9];
int occupancyLimit = 15;
while (occupancyLimit > 0)
{
int i = getRandomNumber(3);
int j = getRandomNumber(9);
//Console.Write(i);
//Console.Write(j);
// Console.Write(game[i,j]+" ");
int data = validateAndReturnNumber(i, j, game);
if (data > 0)
{
game[i, j] = data;
occupancyLimit--;
//Console.WriteLine(game[i,j]);
}
else
{
iCount++;
//Console.WriteLine(iCount);
//printGame(game);
// If X many fails, retry
if(iCount > 1000)
{
iCount = 0;
game = new int[3, 9];
occupancyLimit = 15;
}
}
// If you want to check for zeros you would need to do it here. And use while(true) above
/*
if( //Check for zeros)
{
break; // Ends While loop
}
else
{
// Reset and try again
iCount = 0;
game = new int[3, 9];
occupancyLimit = 15;
}
*/
}
printGame(game);
}
private static void printGame(int[,] game)
{
for (int i = 0; i < game.GetLength(0); i++)
{
for (int j = 0; j < game.GetLength(1); j++)
{
Console.Write(game[i, j] + "\t");
}
Console.WriteLine();
}
Console.WriteLine("******************************************************************");
}
private static int validateAndReturnNumber(int i, int j, int[,] game)
{
//do not override existing elements in array
if (game[i, j] != 0)
{
return -1;
}
//column cannot have more then two elements
int columncounter = 0;
for (int c = 0; c < 3; c++)
{
if (game[c, j] != 0)
{
columncounter++;
}
}
if (columncounter >= 2)
{
return -1;
}
if(
(j != 0 && j != 1 && game[i, j - 2] != 0 && game[i, j - 1] != 0) || // 12X
(j != 0 && j != 8 && game[i, j - 1] != 0 && game[i, j + 1] != 0) || // 1X3
(j != 7 && j != 8 && game[i, j + 1] != 0 && game[i, j + 2] != 0) // X23
)
{
return -1;
}
//for (int columnIndex = 0; columnIndex <= 6; columnIndex++)
//{
// if (game[i, columnIndex + 2] != 0)
// {
// return -1;
// }
//}
// rows cannot have more then 5 elements
int rowcounter = 0;
for (int r = 0; r < 9; r++)
{
if (game[i, r] != 0)
{
rowcounter++;
}
}
//Applying, rows cannot have more then 5 elements
if (rowcounter >= 5)
{
return -1;
}
//return getRandomNumberForColumn(j);
int data = 0;
Boolean isValueSet = false;
do
{
data = getRandomNumberForColumn(j);
isValueSet = isValueExistsInCol(game, i, j, data);
} while (isValueSet);
return data;
}
private static bool isValueExistsInCol(int[,] game, int i, int j, int data)
{
Boolean status = false;
for (int k = 0; k < 3; k++)
{
if (game[k, j] == data)
{
status = true;
break;
}
}
return status;
}
private static int getRandomNumberForColumn(int high)
{
if (high == 0)
{
high = 10;
}
else
{
high = (high + 1) * 10;
}
int low = high - 9;
Random random = new Random();
return random.Next(high - low) + low;
}
private static int getRandomNumber(int max)
{
Random random = new Random();
int num = random.Next(max);
return (num);
}
}
}
Cheers!

Hackerrank: Climbing the Leaderboard

i have a deal with a hackerrank algorithm problem.
It works at all cases, except 6-7-8-9. It gives timeout error. I had spent so much time at this level. Someone saw where is problem?
static long[] climbingLeaderboard(long[] scores, long[] alice)
{
//long[] ranks = new long[scores.Length];
long[] aliceRanks = new long[alice.Length]; // same length with alice length
long lastPoint = 0;
long lastRank;
for (long i = 0; i < alice.Length; i++)
{
lastPoint = scores[0];
lastRank = 1;
bool isIn = false; // if never drop in if statement
for (long j = 0; j < scores.Length; j++)
{
if (lastPoint != scores[j]) //if score is not same, raise the variable
{
lastPoint = scores[j];
lastRank++;
}
if (alice[i] >= scores[j])
{
aliceRanks[i] = lastRank;
isIn = true;
break;
}
aliceRanks[i] = !isIn & j + 1 == scores.Length ? ++lastRank : aliceRanks[i]; //drop in here
}
}
return aliceRanks;
}
This problem can be solved in O(n) time, no binary search needed at all. First, we need to extract the most useful piece of data given in the problem statement, which is,
The existing leaderboard, scores, is in descending order.
Alice's scores, alice, are in ascending order.
An approach that makes this useful is to create two pointers, one at the start of alice array, let's call it "i", and the second is at the end of scores array, let's call it "j". We then loop until i reaches the end of alice array and at each iteration, we check for three main conditions. We increment i by one if alice[i] is less than scores[j] because the next element of alice may be also less than the current element of scores, or we decrement j if alice[i] is greater than scores[j] because we are sure that the next elements of alice are also greater than those elements discarded in scores. The last condition is that if alice[i] == scores[j], we only increment i.
I solved this question in C++, my goal here is to make you understand the algorithm, I think you can easily convert it to C# if you understand it. If there are any confusions, please tell me. Here is the code:
// Complete the climbingLeaderboard function below.
vector<int> climbingLeaderboard(vector<int> scores, vector<int> alice) {
int j = 1, i = 1;
// this is to remove duplicates from the scores vector
for(i =1; i < scores.size(); i++){
if(scores[i] != scores[i-1]){
scores[j++] = scores[i];
}
}
int size = scores.size();
for(i = 0; i < size-j; i++){
scores.pop_back();
}
vector<int> ranks;
i = 0;
j = scores.size()-1;
while(i < alice.size()){
if(j < 0){
ranks.push_back(1);
i++;
continue;
}
if(alice[i] < scores[j]){
ranks.push_back(j+2);
i++;
} else if(alice[i] > scores[j]){
j--;
} else {
ranks.push_back(j+1);
i++;
}
}
return ranks;
}
I think this may help you too:
vector is like an array list that resizes itself.
push_back() is inserting at the end of the vector.
pop_back() is removing from the end of the vector.
Here is my solution with c#
public static List<int> climbingLeaderboard(List<int> ranked, List<int> player)
{
List<int> result = new List<int>();
ranked = ranked.Distinct().ToList();
var pLength = player.Count;
var rLength = ranked.Count-1;
int j = rLength;
for (int i = 0; i < pLength; i++)
{
for (; j >= 0; j--)
{
if (player[i] == ranked[j])
{
result.Add(j + 1);
break;
}
else if(player[i] < ranked[j])
{
result.Add(j + 2);
break;
}
else if(player[i] > ranked[j]&&j==0)
{
result.Add(1);
break;
}enter code here
}
}
return result;
}
Here is a solution that utilizes BinarySearch. This method returns the index of the searched number in the array, or if the number is not found then it returns a negative number that is the bitwise complement of the index of the next element in the array. Binary search only works in sorted arrays.
public static int[] GetRanks(long[] scores, long[] person)
{
var defaultComparer = Comparer<long>.Default;
var reverseComparer = Comparer<long>.Create((x, y) => -defaultComparer.Compare(x, y));
var distinctOrderedScores = scores.Distinct().OrderBy(i => i, reverseComparer).ToArray();
return person
.Select(i => Array.BinarySearch(distinctOrderedScores, i, reverseComparer))
.Select(pos => (pos >= 0 ? pos : ~pos) + 1)
.ToArray();
}
Usage example:
var scores = new long[] { 100, 100, 50, 40, 40, 20, 10 };
var alice = new long[] { 5, 25, 50, 120 };
var ranks = GetRanks(scores, alice);
Console.WriteLine($"Ranks: {String.Join(", ", ranks)}");
Output:
Ranks: 6, 4, 2, 1
I was bored so i gave this a go with Linq and heavily commented it for you,
Given
public static IEnumerable<int> GetRanks(long[] scores, long[] person)
// Convert scores to a tuple
=> scores.Select(s => (scores: s, isPerson: false))
// convert persons score to a tuple and concat
.Concat(person.Select(s => (scores: s, isPerson: true)))
// Group by scores
.GroupBy(x => x.scores)
// order by score
.OrderBy(x => x.Key)
// select into an indexable tuple so we know everyones rank
.Select((groups, i) => (rank: i, groups))
// Filter the person
.Where(x => x.groups.Any(y => y.isPerson))
// select the rank
.Select(x => x.rank);
Usage
static void Main(string[] args)
{
var scores = new long[]{1, 34, 565, 43, 44, 56, 67};
var alice = new long[]{578, 40, 50, 67, 6};
var ranks = GetRanks(scores, alice);
foreach (var rank in ranks)
Console.WriteLine(rank);
}
Output
1
3
6
8
10
Based on the given constraint brute-force solution will not be efficient for the problem.
you have to optimize your code and the key part here is to look up for exact place which can be effectively done by using binary search.
Here is the solution using binary search:-
static int[] climbingLeaderboard(int[] scores, int[] alice) {
int n = scores.length;
int m = alice.length;
int res[] = new int[m];
int[] rank = new int[n];
rank[0] = 1;
for (int i = 1; i < n; i++) {
if (scores[i] == scores[i - 1]) {
rank[i] = rank[i - 1];
} else {
rank[i] = rank[i - 1] + 1;
}
}
for (int i = 0; i < m; i++) {
int aliceScore = alice[i];
if (aliceScore > scores[0]) {
res[i] = 1;
} else if (aliceScore < scores[n - 1]) {
res[i] = rank[n - 1] + 1;
} else {
int index = binarySearch(scores, aliceScore);
res[i] = rank[index];
}
}
return res;
}
private static int binarySearch(int[] a, int key) {
int lo = 0;
int hi = a.length - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (a[mid] == key) {
return mid;
} else if (a[mid] < key && key < a[mid - 1]) {
return mid;
} else if (a[mid] > key && key >= a[mid + 1]) {
return mid + 1;
} else if (a[mid] < key) {
hi = mid - 1;
} else if (a[mid] > key) {
lo = mid + 1;
}
}
return -1;
}
You can refer to this link for a more detailed video explanation.
static int[] climbingLeaderboard(int[] scores, int[] alice) {
int[] uniqueScores = IntStream.of(scores).distinct().toArray();
int [] rank = new int [alice.length];
int startIndex=0;
for(int j=alice.length-1; j>=0;j--) {
for(int i=startIndex; i<=uniqueScores.length-1;i++) {
if (alice[j]<uniqueScores[uniqueScores.length-1]){
rank[j]=uniqueScores.length+1;
break;
}
else if(alice[j]>=uniqueScores[i]) {
rank[j]=i+1;
startIndex=i;
break;
}
else{continue;}
}
}
return rank;
}
My solution in javascript for climbing the Leaderboard Hackerrank problem. The time complexity of the problem can be O(i+j), i is the length of scores and j is the length of alice. The space complexity is O(1).
// Complete the climbingLeaderboard function below.
function climbingLeaderboard(scores, alice) {
const ans = [];
let count = 0;
// the alice array is arranged in ascending order
let j = alice.length - 1;
for (let i = 0 ; i < scores.length ; i++) {
const score = scores[i];
for (; j >= 0 ; j--) {
if (alice[j] >= score) {
// if higher than score
ans.unshift(count+1);
} else if (i === scores.length - 1) {
// if smallest
ans.unshift(count+2);
} else {
break;
}
}
// actual rank of the score in leaderboard
if (score !== scores[i-1]) {
count++;
}
}
return ans;
}
Here is my solution
List<int> distinct = null;
List<int> rank = new List<int>();
foreach (int item in player)
{
ranked.Add(item);
ranked.Sort();
ranked.Reverse();
distinct = ranked.Distinct().ToList();
for (int i = 0; i < distinct.Count; i++)
{
if (item == distinct[i])
{
rank.Add(i + 1);
break;
}
}
}
return rank;
This can be modified by removing the inner for loop also
List<int> distinct = null;
List<int> rank = new List<int>();
foreach (int item in player)
{
ranked.Add(item);
ranked.Sort();
ranked.Reverse();
distinct = ranked.Distinct().ToList();
var index = ranked.FindIndex(x => x == item);
rank.Add(index + 1);
}
return rank;
This is my solution in c# for Hackerrank Climbing the Leaderboard based on C++ answer here.
public static List<int> climbingLeaderboard(List<int> ranked, List<int> player)
{
List<int> _ranked = new List<int>();
_ranked.Add(ranked[0]);
for(int a=1; a < ranked.Count(); a++)
if(_ranked[_ranked.Count()-1] != ranked[a])
_ranked.Add(ranked[a]);
int j = _ranked.Count()-1;
int i = 0;
while(i < player.Count())
{
if(j < 0)
{
player[i] = 1;
i++;
continue;
}
if(player[i] < _ranked[j])
{
player[i] = j+2;
i++;
}
else
if(player[i] == _ranked[j])
{
player[i] = j+1;
i++;
}
else
{
j--;
}
}
return player;
}
My solution in Java for climbing the Leaderboard Hackerrank problem.
// Complete the climbingLeaderboard function below.
static int[] climbingLeaderboard(int[] scores, int[] alice) {
Arrays.sort(scores);
HashSet<Integer> set = new HashSet<Integer>();
int[] ar = new int[alice.length];
int sc = 0;
for(int i=0; i<alice.length; i++){
sc = 1;
set.clear();
for(int j=0; j<scores.length; j++){
if(alice[i] < scores[j] && !set.contains(scores[j])){
sc++;
set.add(scores[j]);
}
}
ar[i] = sc;
}return ar;
}

I want to know what is wrong with my minmax algorithm for connect4 game?

iam try to write min max algorithm for connect4 game but when i run this code it go in infinte loop and not return move or result, so i want a help to know what is wrong with it , i work in board of 6*7 cells
private int score()
{
int x = check_Winner();//i checked it and it work right ot return 1 if player 1 win or 2 if pc win or 0 in tie
if (x == 1) return 10;
else if (x == 2) return -10;
else return 0;
}
public int MinMax(int player_num)
{
List<pair> possiple_moves = get_possible_moves();// it works will
int score_so_far = score();
if (possiple_moves.Count == 0 || score_so_far != 0)
return score_so_far;
List<int> scores = new List<int>();
List<pair> moves = new List<pair>();
foreach (pair move in possiple_moves)
{
if (player_num == 1)
{
cells[move.x, move.y].player_num = 1;
scores.Add(MinMax(2));
}
else
{
cells[move.x, move.y].player_num = 2;
scores.Add(MinMax(1));
}
moves.Add(move);
cells[move.x, move.y].player_num = 0;
}
if (player_num == 1)
{
int max_score_indx = 0, tmp = int.MinValue;
for (int i = 0; i < scores.Count; i++)
{
if (scores[i] > tmp)
{
tmp = scores[i];
max_score_indx = i;
}
}
pc_choise = moves[max_score_indx];
return scores[max_score_indx];
}
//==================
else
{
int min_score_indx = 0, tmp = int.MaxValue;
for (int i = 0; i < scores.Count; i++)
{
if (scores[i] < tmp)
{
tmp = scores[i];
min_score_indx = i;
}
}
pc_choise = moves[min_score_indx];
return scores[min_score_indx];
}
}
#Equalsk is right, I believe: you are calling MinMax from within the foreach loop, before you reach the code that evaluates the stop conditions. So providing that the method get_possible_moves returns something different to Null, you will get stuck in foreach --> MinMax --> foreach --> MinMax --> foreach...

Largest substring composed of identical characters

I want to develop method that will return the length of largest substring composed of identical characters form string that is passed as argument, but without using any of .NET libraries.
For example if we pass aaacccccdefffgg as parameter the biggest substring is ccccc and method should return 5.
Here is my working solution :
public static int GetMaxSubstringLenght(char[] myArray)
{
int max = 0;
for (int i = 0; i < myArray.Length-1; i++)
{
if (myArray.Length == 0)
{
return 0;
}
else
{
int j = i + 1;
int currentMax = 1; // string has some value, so we start with 1
while (myArray[i] == myArray[j])
{
currentMax++;
if (max < currentMax)
{
max = currentMax;
}
j++;
}
}
}
return max;
}
The code above will return expected result, but there will be some unnecessary iteration in for loop that I want to avoid. In first iteration when i=0it will compare it until j=2 and then will get out of while loop and start second iteration in for loop comparing the one at [1] index with [2], which we already did in previous iteration.So basically, when first iteration is completed, next one should start from the last value of j. How can I achieve that ?
Thank You in advance.
Since you want "Largest substring..." let's take String as argument and return String
public static String GetMaxSubstring(String value) {
if (String.IsNullOrEmpty(value))
return "";
int bestCount = 0;
char bestChar = '\0';
int currentCount = 0;
char current = '\0';
for (int i = 0; i < value.Length; ++i) {
if ((i == 0) || (value[i] != current))
currentCount = 0;
currentCount += 1;
current = value[i];
if (currentCount > bestCount) {
bestCount = currentCount;
bestChar = current;
}
}
return new String(bestChar, bestCount);
}
....
// "ccccc"
String result = GetMaxSubstring("aaacccccdefffgg");
// 5
int length = result.Length;
Another approach:
public static int MaxSubstringLength(string s)
{
if (string.IsNullOrEmpty(s))
return 0;
int max = 0, cur = 1;
for (int i = 1; i < s.Length; ++i, ++cur)
{
if (s[i] != s[i-1])
{
max = cur > max ? cur : max;
cur = 0;
}
}
return cur > max ? cur : max;
}
[EDIT] Simplified the code.
[EDIT2] Simplified the code further.
you also can do it with one loop:
public static int GetMaxSubstringLenght(char[] myArray)
{
int max = 0;
char currentchar = myArray[0];
int count = 1;
for each(char c in myArray)
{
if(currentchar != c)
{
count = 1;
currentchar = c;
}
if(count > max)
{
max = count;
}
count++;
}
return max;
}
I changed the code... now this code does not use math.max and I think I eleminated the mistake... I've no IDE at the moment to test it
public static int GetMaxSubstringLenght(char[] myArray)
{
if (myArray.Length == 0)
return 0;
if (myArray.Length == 1)
return 1;
int max = 1;
int localMax = 1;
for (int i = 0; i < myArray.Length - max; i++ )
{
if (myArray[i] == myArray[i + 1])
{
localMax++;
}
else
{
max = Math.Max(max, localMax);
localMax = 1;
}
}
return Math.Max(max, localMax);
}
static int LongestCharSequence(string s)
{
if (string.IsNullOrEmpty(s)) return 0;
var prevChar = '\0';
int cmax = 0;
int max = 1;
foreach (char c in s)
{
if (c != prevChar)
{
cmax = 1;
prevChar = c;
}
else
{
if (++cmax > max) max = cmax;
}
}
return max;
}
recursion!
static int LongestCharSequence(string s)
{
int i = (s?.Length ?? 0) == 0 ? 0 : 1;
for (; i < s?.Length; i++)
if (s[i] != s[i - 1]) return Math.Max(i, LongestCharSequence(s.Substring(i)));
return i;
}
Another solution using my favorite nested loop technique:
public static int MaxSubstringLength(string s)
{
int maxLength = 0;
for (int length = s != null ? s.Length : 0, pos = 0; pos < length;)
{
int start = pos;
while (++pos < length && s[pos] == s[start]) { }
maxLength = Math.Max(maxLength, pos - start);
}
return maxLength;
}

Converting Codility solution to C# (Grocery-store, Hydrogenium 2013)

In order to learn and understand how Dijkstra's algorithm is used to solve the "Grocery Store" ([Hydrogenium 2013]: https://codility.com/programmers/challenges/hydrogenium2013) problem on codility, I'm trying to rewrite the #2, O(n^2) solution(https://codility.com/media/train/solution-grocery-store.pdf) in C#.
1) What language are those solutions written in?
2) What would be the C# equivalent to this bit of code?
G = [[]] *N
for i in xrange(M):
G[A[i]] = G[A[i]] + [(B[i], C[i])]
G[B[i]] = G[B[i]] + [(A[i], C[i])]
This is what I have so far
int[] G = new int[N];
for (int i = 0; i < M; i++)
{
G[A[i]] = G[A[i]];
G[B[i]] = G[B[i]];
}
Thanks in advance,
Gregory
Downloaded IDLE (a python IDE...kind of) and figured it out. It appears to be adding pairs to each array element. Here's the code I came up with if anyone else happens to stumble across the same problem.
private struct nodePair
{
public int node;
public int time;
public nodePair(int node, int time)
{
this.node = node;
this.time = time;
}
}
public int solution(int[] A, int[] B, int[] C, int[] D)
{
int M = A.Length;
int N = D.Length;
//build the graph
List<nodePair>[] G = new List<nodePair>[N];
for (int i = 0; i < N; i++)
{
G[i] = new List<nodePair>();
}
for (int i = 0; i < M; i++)
{
G[A[i]].Add(new nodePair(B[i], C[i]));
G[B[i]].Add(new nodePair(A[i], C[i]));
}
//initialize the distance table
int[] dist = new int[N];
for (int i = 0; i < N; i++)
{
dist[i] = int.MaxValue;
}
bool[] visited = new bool[N];
for (int i = 0; i < N; i++)
{
visited[i] = false;
}
//look for the minimum value
int ii = 0; ;
dist[0] = 0;
for (int k = 0; k < N; k++)
{
int s = int.MaxValue;
//find the minimum
for (int j = 0; j < N; j++)
{
if ((dist[j] < s) && (visited[j] == false))
{
s = dist[j];
ii = j;
}
}
visited[ii] = true;
if (s < D[ii])
{
return s;
}
List<nodePair> thisNodeLIst = G[ii];
foreach (nodePair oneNode in thisNodeLIst)
{
dist[oneNode.node] = Math.Min(dist[oneNode.node], s + oneNode.time);
}
}//for
return -1;
}
}

Categories

Resources