Given a screen containing alphabets from a-z, we can go from one character to another character using a remote. The remote contains left, right, top and bottom keys.
Remote :
Find the shortest possible path to type all characters of given string using the remote. The initial position is top left and all characters of input string should be printed in order. Find the total number of moves in such a path(Move UP, DOWN, LEFT, RIGHT). Pressing OK also accounts for one move.
Screen:
a b c d e
f g h i j
k l m n o
p q r s t
u v w x y
z
Example 1:
Input: str = "abc"
Output: 5
Explanation: Remote's position is at 'a'
initially. So 'a' -> 'b' = 1 step, 
'b'-> 'c'= 1 step. Three OK moves will also
be needed to print the three characters.
Example 2:
Input: str = "a"
Output: 1
Explanation: Remote is initially at 'a'.
 
Your Task:
You don't need to read or print anything. Your task is to complete the function FindPath() which takes the string str as input parameter and returns the minimum number of moves to cover all characters of the given string.
 
Expected Time Compelxity: O(n)
Expected Space Complexity: O(1)
 
Constraints:
1 <= |str| <= 10^{5}

Source: geeksforgeeks | Difficulty: EASY
Tags: Matrices

Data structures

Starter code: #User function Template for python3

class Solution:
	def FindPath(self, str):
		# Code here

Solutions:
class Solution:

	def FindPath(self, str):
		i = 0
		j = 0
		l = len(str)
		k = 0
		count = 0
		while k < l:
			elen = ord(str[k]) - 97
			icur = elen // 5
			jcur = elen % 5
			count += abs(i - icur) + abs(j - jcur)
			i = icur
			j = jcur
			k += 1
		return count + l


class Solution:

	def FindPath(self, str):
		char = {'a': (0, 0), 'b': (0, 1), 'c': (0, 2), 'd': (0, 3), 'e': (0, 4), 'f': (1, 0), 'g': (1, 1), 'h': (1, 2), 'i': (1, 3), 'j': (1, 4), 'k': (2, 0), 'l': (2, 1), 'm': (2, 2), 'n': (2, 3), 'o': (2, 4), 'p': (3, 0), 'q': (3, 1), 'r': (3, 2), 's': (3, 3), 't': (3, 4), 'u': (4, 0), 'v': (4, 1), 'w': (4, 2), 'x': (4, 3), 'y': (4, 4), 'z': (5, 0)}
		ans = 0
		prev = (0, 0)
		for i in range(len(str)):
			cur = char[str[i]]
			ans += abs(cur[0] - prev[0]) + abs(cur[1] - prev[1])
			prev = char[str[i]]
		return ans + len(str)


class Solution:

	def FindPath(self, str):
		dic = {'a': (0, 0), 'b': (0, 1), 'c': (0, 2), 'd': (0, 3), 'e': (0, 4), 'f': (1, 0), 'g': (1, 1), 'h': (1, 2), 'i': (1, 3), 'j': (1, 4), 'k': (2, 0), 'l': (2, 1), 'm': (2, 2), 'n': (2, 3), 'o': (2, 4), 'p': (3, 0), 'q': (3, 1), 'r': (3, 2), 's': (3, 3), 't': (3, 4), 'u': (4, 0), 'v': (4, 1), 'w': (4, 2), 'x': (4, 3), 'y': (4, 4), 'z': (5, 0)}
		(i, j) = (0, 0)
		res = 0
		for k in str:
			dist = abs(i - dic[k][0]) + abs(j - dic[k][1]) + 1
			(i, j) = (dic[k][0], dic[k][1])
			res += dist
		return res


class Solution:

	def FindPath(self, s):
		alpha = 'abcdefghijklmnopqrstuvwxyz'
		grid = []
		while alpha:
			grid.append(alpha[:5])
			alpha = alpha[5:]
		store = {}
		for i in range(len(grid)):
			for j in range(len(grid[i])):
				store[grid[i][j]] = (i, j)
		count = len(s)
		cell = (0, 0)
		for item in s:
			(i, j) = store[item]
			count += abs(cell[0] - i)
			count += abs(cell[1] - j)
			cell = (i, j)
		return count


class FloydWarshall:

	def copyMatrix(self, src, tar):
		for i in range(len(src)):
			for j in range(len(src[0])):
				tar[i][j] = src[i][j]

	def allPairShortestPath(self, graph):
		n = len(graph)
		adjMatrix = [[float('inf') for j in range(n)] for i in range(n)]
		for i in range(n):
			adjMatrix[i][i] = 0
		for i in range(n):
			for (x, w) in graph[i]:
				adjMatrix[i][x] = w
		tmpMatrix = [[float('inf') for j in range(n)] for i in range(n)]
		self.copyMatrix(adjMatrix, tmpMatrix)
		for k in range(n):
			for i in range(n):
				if i == k:
					continue
				for j in range(n):
					if j == k or i == j:
						continue
					tmpMatrix[i][j] = min(adjMatrix[i][j], adjMatrix[i][k] + adjMatrix[k][j])
			self.copyMatrix(tmpMatrix, adjMatrix)
		return tmpMatrix

class Solution:

	def getNormalizedIndex(self, char):
		return ord(char) - ord('a')

	def getManhatternDistanceBetweenIndex(self, idx1, idx2):
		(x1, y1) = (idx1 // 5, idx1 % 5)
		(x2, y2) = (idx2 // 5, idx2 % 5)
		return abs(x1 - x2) + abs(y1 - y2)

	def FindPath(self, str):
		s = 'abcdefghijklmnopqrstuvwxyz'
		graph = []
		for u in s:
			tmp = []
			ui = self.getNormalizedIndex(u)
			for v in s:
				vi = self.getNormalizedIndex(v)
				d = self.getManhatternDistanceBetweenIndex(ui, vi)
				tmp.append([vi, d])
			graph.append(tmp)
		fw = FloydWarshall()
		distMatrix = fw.allPairShortestPath(graph)
		count = 0
		prev = 'a'
		for char in str:
			count += distMatrix[self.getNormalizedIndex(prev)][self.getNormalizedIndex(char)]
			count += 1
			prev = char
		return count


class Solution:

	def getNormalizedIndex(self, char):
		return ord(char) - ord('a')

	def FindPath(self, str):
		count = 0
		(x, y) = (0, 0)
		for char in str:
			idx = self.getNormalizedIndex(char)
			count += abs(x - idx // 5)
			count += abs(y - idx % 5)
			count += 1
			(x, y) = (idx // 5, idx % 5)
		return count


class Solution:

	def FindPath(self, str):
		curr = 0
		total = 0
		for i in str:
			temp = ord(i) - 97
			x = abs(temp % 5 - curr % 5)
			y = abs(temp // 5 - curr // 5)
			curr = temp
			total += x + y + 1
		return total


class Solution:

	def FindPath(self, str):
		moves = 0
		jindex = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 0, 'g': 1, 'h': 2, 'i': 3, 'j': 4, 'k': 0, 'l': 1, 'm': 2, 'n': 3, 'o': 4, 'p': 0, 'q': 1, 'r': 2, 's': 3, 't': 4, 'u': 0, 'v': 1, 'w': 2, 'x': 3, 'y': 4, 'z': 0}
		iindex = {'a': 0, 'b': 0, 'c': 0, 'd': 0, 'e': 0, 'f': 1, 'g': 1, 'h': 1, 'i': 1, 'j': 1, 'k': 2, 'l': 2, 'm': 2, 'n': 2, 'o': 2, 'p': 3, 'q': 3, 'r': 3, 's': 3, 't': 3, 'u': 4, 'v': 4, 'w': 4, 'x': 4, 'y': 4, 'z': 5}
		a = list(str)
		for i in range(len(a) - 1):
			prev = a[i]
			moves += abs(jindex[a[i + 1]] - jindex[prev]) + abs(iindex[a[i + 1]] - iindex[prev])
		extra = jindex[a[0]] + iindex[a[0]]
		return moves + len(str) + extra


class Solution:

	def FindPath(self, str):
		n = 5
		ans = 0
		path = ''
		source_x = 0
		source_y = 0
		for ch in str:
			target = ord(ch) - ord('a')
			target_x = target // n
			target_y = target % n
			diff_x = target_x - source_x
			diff_y = target_y - source_y
			ans += abs(diff_x) + abs(diff_y) + 1
			if diff_x > 0:
				path += 'd' * abs(diff_x)
			else:
				path += 'u' * abs(diff_x)
			if diff_y > 0:
				path += 'r' * abs(diff_y)
			else:
				path += 'l' * abs(diff_y)
			path += '!'
			source_x = target_x
			source_y = target_y
		return ans


class Solution:

	def FindPath(self, string):
		pos = 'a'
		steps = 0
		for i in string:
			n = ord(i) - ord('a')
			m = ord(pos) - ord('a')
			row_diff = n // 5 - m // 5
			col_diff = n % 5 - m % 5
			steps += abs(row_diff) + abs(col_diff) + 1
			pos = chr(ord(pos) + n - m)
		return steps