Search code examples
pythonpath-finding

Path finding algorithm excercise and working with .txt files


This is a homework which was given to me and I have been struggling with writing the solution.

Write a program that finds the longest adjacent sequence of colors in a matrix(2D grid). Colors are represented by ‘R’, ‘G’, ‘B’ characters (respectively Red, Green and Blue).
You will be provided with 4 individual test cases, which must also be included in your solution.
An example of your solution root directory should look like this:

solutionRootDir
| - (my solution files and folders)
| - tests/
| - test_1
| - test_2
| - test_3
| - test_4

  1. Individual test case input format:
  • First you should read two whitespace separated 32-bit integers from the provided test case
  • that represents the size (rows and cols) of the matrix.
  • Next you should read rows number of newline separated lines of 8-bit characters. Your program should find and print the longest adjacent sequence (diagonals are not counted as adjacent fields), and print to the standard output the number. NOTE: in case of several sequences with the same length – simply print their equal length.

test_1
Provided input:
3 3
R R B
G G R
R B G
Expected Output:
2

test_2
Provided input:
4 4
R R R G
G B R G
R G G G
G G B B
Expected Output:
7

test_3
Provided input:
6 6
R R B B B B
B R B B G B
B G G B R B
B B R B G B
R B R B R B
R B B B G B
Expected Output: 22

test_4
Provided input:
1000 1000
1000 rows of 1000 R’s
Expected Output:
1000000

  1. Your program entry point should accepted from one to four additional parameters. Those parameters will indicate the names of the test cases that your program should run.

• Example 1: ./myprogram test_1 test_3

• Example 2: ./myprogram test_1 test_2 test_3 test_4

• you can assume that the input from the user will be correct (no validation is required)

import numpy as np

a = int(input("Enter rows: "))
b = int(input("Enter columns: "))
rgb = ["R", "G", "B"]
T = [[0 for col in range(b)] for row in range(a)]

for row in range(a):
    for col in range(b):
        T[row][col] = np.random.choice(rgb)

for r in T:
    for c in r:
        print(c, end=" ")
    print()

def solution(t):
    rows: int = len(t)
    cols: int = len(t[0])
    longest = np.empty((rows, cols))
    longest_sean = 1

    for i in range(rows - 1, -1, -1):
        for j in range(cols - 1, -1, -1):
            target = t[i][j]

            current = 1

            for ii in range(i, rows):
                for jj in range(j, cols):
                    length = 1
                    if target == t[ii][jj]:
                        length += longest[ii][jj]
                    current = max(current, length)

            longest[i][j] = current
            longest_sean = max(current, longest_sean)

    return longest_sean

print(solution(T))

Solution

  • in order to get the parameters from the console execution you have to use sys.argv so from sys import argv. than convert your text field to python lists like this

    def load(file):
        with open(file+".txt") as f:
            data = f.readlines()
        res = []
        for row in data:
            res.append([])
            for element in row:
                if element != "\n" and element != " ":
                    res[-1].append(element)
    
        return res
    

    witch will create a 2 dimentional list of containing "R", "B" and "G". than you can simply look for the longest area of one Value like using this Function:

    def findLargest(data):
        visited = []
        area = []
        length = 0
        movement = [(1,0), (0,1), (-1,0),(0,-1)]
    
        def recScan(x, y, scanArea):
            visited.append((x,y))
            scanArea.append((x,y))
            
            for dx, dy in movement:
                newX, newY = x+dx, y+dy
                if newX >= 0 and newY >= 0 and newX < len(data) and newY < len(data[newX]):
                    if data[x][y] == data[newX][newY] and (not (newX, newY) in visited):
                        recScan(newX, newY, scanArea)
            return scanArea
                
    
        for x in range(len(data)):
            for y in range(len(data[x])):
                if (x, y) not in visited:
                    newArea = recScan(x, y, [])
                    if len(newArea) > length:
                        length = len(newArea)
                        area = newArea
        return length, area
    

    whereby recScan will check all adjacent fields that haven't bean visited jet. than just call the functions like this:

    if __name__ == "__main__":
        for file in argv[1:]:
            data = load(file)
            print(findLargest(data))
    

    the argv[1:] is reqired because the first argument passed to python witch is the file you want to execute. my data structure is.

    main.py
    test_1.txt
    test_2.txt
    test_3.txt
    test_4.txt

    and test_1 threw test_4 look like this just with other values.


    R R B B B B
    B R B B G B
    B G G B R B
    B B R B G B
    R B R B R B
    R B B B G B