Python program determining the letter based on row and col - python

My current code is under here with the pattern I want to be displayed
XOOOOOX
OXOOOXO
OOXOXOO
OOOXOOO
OOXOXOO
OXOOOXO
XOOOOOX
Code:
#starting from the 1st row and ending at the 8th row
for row in range (1, 8):
#within each row, starting from the 1st col and ending in the 8th col
for col in range(1, 8):
#decide what to print at the current location
if ((row - col)) == 0:
print("X", end="")
elif((row + 1)) == 0:
print("X", end="")
else:
print("O", end="")
#go onto the next row
print()

If you want to display x, the following code is sufficient:
You can differ the size of letter by N, try to avoid hard-coding some arbitrally numbers.
N = 8
# starting from the 1st row and ending at the 8th row
for row in range(1, N):
# within each row, starting from the 1st col and ending in the 8th col
for col in range(1, N):
# decide what to print at the current location
if row == col or row == N-col:
print("X", end="")
else:
print("O", end="")
# go onto the next row
print()

Your logic does nothing to insert the second X, as you've seen.
for row in range (1, 8):
...
elif((row + 1)) == 0:
Since row takes on values in the range 0-7, this isn't possible: it can be true only when row = -1. Yes, Python allows you to index a list from the right, but a variable used as an index does not automatically take on a second value to satisfy those semantics. You have to explicitly give it a single value.
You need to rewrite your condition to compare row to the end index, and you'll have to involve col, just as you did with the main diagonal.

You can convert your string to list and make the change symmetrical based on the length of your string and the current i
LEN = 7#length of string
string = ""
#initialize string
for i in range(LEN):
string += "O"
#change and print
for i in range(LEN):
new_string = list(string)#from string to list
new_string[i] = "X"#change the i
new_string[LEN-i-1] = "X"#symmetrical change
new_string = "".join(new_string)#list to string
print(new_string)
You can change the LEN and the characters as you wish

Related

Why my code does not produce the pattern in the 2nd loop?

Why does my code not work in the 2nd iteration? I want to give input in row = 3 or 5 or x, and then I expect it to produce the following output pattern:
#When row = 3
1|. . #
2|. ##
3|###
Please note that the number of "." will be opposite to the number of "#"
The i loop prints a new line, the j loop prints "#", and the k loop prints "."
row = 3
for i in range(1, row + 1):
for j in range(1, i + 1):
for k in range(1, (row - i) + 1):
print(".", end= "")
print("#", end="")
print("")
Your k loop runs too many times to do what you want after the first iteration.
However I think this does what you want, hope it helps:
row = 3
n_hash = 0
n_dots = row
for i in range(row):
print(f'{i+1}|{n_dots * "."}{n_hash * "#"}')
n_dots -= 1
n_hash += 1

Print 2d list as a game board

I have a 2d list [1,2,3,4],[4,3,3,1],[3,2,1,1],[2,2,2,1] and I want to print it out to match the following format.
0123
XXXXXXXX
0*1234*0
1*4331*1
2*3211*2
3*2221*3
XXXXXXXX
0123
It should not be hard coded and the length of the list = n so this list n=4 but if list n=5 there would be 5 digits per row and the number on the sides would go 0,1,2,3,4.
So far all I have is:
for row in board:
for column in row:
print(column, end="")
print("")
Which only outputs the list as:
1234
4331
3211
2221
please help me add all the special stuff.
so I find a solution for what you want to do however I think it can be improved a lot (not program quite a lot in python), but I'll leave it here anyways :)
print(" ", end="")
for x in range(len(board)):
print(x, end="")
print()
for x in range(len(board)+4):
print("X", end="")
print()
for num,row in enumerate(board):
print(f"{num}*", end="")
for column in row:
print(column, end="")
print(f"*{num}", end="")
print("")
for x in range(len(board)+4):
print("X", end="")
print()
print(" ", end="")
for x in range(len(board)):
print(x, end="")
print()
Well for the first line you pretty much print 2 spaces, followed by all the digits between 0 and the number of columns in your board. You can use the "range" function for this. Then you must print the correct amount of 'X'. The correct amount is number of columns + 4, I think you can see why.
You should keep a counter starting from 0. For each row you print, you must print the string value of the counter, followed by an asterisk(*), followed by your row, followed by an asterisk(*) and finally followed by the same counter value. You must increment the counter by one for each row.
The last 2 rows are the same as top 2.
I do not want to share my code because this is such a simple problem, I think solving it on your own will help you in the long run.
Probably an unpopular opinion, but I think these kinds of problems are really fun.
This solution formats the contents correctly, even if you change the number of rows, and even the number of items in each row.
def draw_board(board):
# determining the number of elements in a row,
# this is used for printing the X's
# and printing the spaced ranges (i.e. " 0123 ")
n = len(board[0])
# calculating the total width of the board,
# + 4 is because of the "0*...*0" situation
width = n + 4
# calculating margin of the spaced ranges
# (i.e. calculating how much space on each side)
margin = int(n / 2)
# printing the spaced ranges using the margin
print(" " * margin + "".join(str(num) for num in list(range(n))) + " " * margin)
# printing the XXXX
print("X" * width)
# printing the row index number,
# with the *,
# along with the numbers in the row,
# followed by the * and the row number
for row in range(len(board)):
print(str(row) + "*" + "".join(str(elem) for elem in board[row]) + "*" + str(row))
# printing the XXXX
print("X" * width)
# printing the spaced ranges using the margin
print(" " * margin + "".join(str(num) for num in list(range(n))) + " " * margin)
b = [
[1,2,3,4],
[4,3,3,1],
[3,2,1,1],
[2,2,2,1]
]
draw_board(b)
# OUTPUT:
# 0123
# XXXXXXXX
# 0*1234*0
# 1*4331*1
# 2*3211*2
# 3*2221*3
# XXXXXXXX
# 0123
Edited to remove my own tests and to reflect given problem.

Print odd index in same line

I'm trying to complete challenge on HackerRank ( Day 6 : Let's review!) and I only did to print the even numbers on the same line, but I can't print the odd indexes that would be needed to complete the challenge.
This is my code:
word_check = input()
for index, char in enumerate (word_check):
if (index % 2 == 0):
print( char ,end ="" )
This is the most specific task:
Given a string, S , of length N that is indexed from 0 to N -1 , print its even-indexed and odd-indexed characters as space-separated strings on a single line.
Thanks!!!
RavDev
You can use slice notation for indexing the original string:
word_check[::2] + " " + word_check[1::2]
[::2] means "start at the beginning and skip every second element until we reach the end" and [1::2] means "start at the second element and skip every second element until we reach the end". Leaving out either start or stop arguments of the slice implies beginning or end of the sequence respectively. Leaving out the step argument implies a step size of 1.
Slice notation is a better approach, but if you want to use for loop and stick to your approach, you can do in this way:
even =''
odd=''
for index, char in enumerate (word_check):
if (index % 2 == 0):
even += char
else: odd += char
print (even, odd)
I am currently trying to solve the same problem. To get your answers on the same line, initiate two strings: one for even and one for odd. If the character's index is even, add it to the even string and vice versa. Here is my working code so far:
def indexes(word,letter):
result = list()
for i,x in enumerate(word):
if x == letter:
result.append(i)
return result
T = int(input())
if T <= 10 and T>= 1:
for i in range(T):
evenstring = ""
oddstring = ""
lastchar = False
S = input()
if len(S) >= 2 and len(S) <= 10000:
for index, char in enumerate (S):
if (index % 2 == 0):
evenstring += char
else: oddstring += char
if len(indexes(S, char)) > 1:
evenstring.replace(evenstring[evenstring.rfind(char)], '')
oddstring.replace(oddstring[oddstring.rfind(char)], '')
print(evenstring, oddstring)
Your next problem now is trying to remove any reoccurrences of duplicate letters from your final answer (they show up in other test cases)

Python multiplication table, seperte with strings

I want to create a function that takes 2 parameter, and prints the multiplication table for this number in a nice format where rows are separated by lines. This is the target:
target design
I have tried, but have no idea where to integrate the "--------" string. Any ideas?
def multi_table(x,y):
for row in range(1, x+1):
for col in range(1, y+1):
num = row * col
if num < 10: blank = ' '
else:
if num < 100: blank = ' '
print(blank, num, end = '')
print()
multi_table(4,5)
You need to add the print statement between the row and column loop. You also need to ensure that you end the print statement with a new line character \n. Refer below.
def multi_table(x,y):
for row in range(1, x+1):
print("---------------------\n")
for col in range(1, y+1):
num = row * col
if num < 10: blank = ' '
else:
if num < 100: blank = ' '
print(blank, num, end = '')
print()
multi_table(4,5)
The print() is used to go to the next line, and that's where you want to add the "---------------". So change the print() to print('\n------------------------\n'). \n indicates to go to the next line.
To compensate for y, you can use the following,
also, you can simplify the formatting with the format string method:
def multi_table(x,y):
for row in range(1, x+1):
print('----' * y)
for col in range(1, y+1):
num = row * col
print('{:4}'.format(num), end = '')
print()

Change Breadth First Search to Depth First Search, N- Queen Solver

I would appreciate if someone helps me understand how to change the Breadth First Search to Depth First Search, or which steps I need to follow.
The algorithm is basically in the next functions:
canPlace
getpositions
loopBoard
CODE:
import sys
import copy
from os import system
#Set the console title
system("title Michael Fiford - Breadth First N-Queen Solver")
class QueenSolver:
#Store for the amount of queens we're placing, or table size
tableSize = 0
#The alphabet, for nice cell referencing on the output
alphabet = ['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']
#The queue of possible moves that we will create and loop through
queue = []
#Whether or not the solver can be ran
canRun = False
def setup(self, queenNumber):
#Set the number of queens/table size
self.tableSize = queenNumber
#Can run, so long as there are no errors
self.canRun = True
#Show error if there is no solution, or would take too long
if queenNumber < 4:
print "ERROR: A solution is not available for this few number of queens"
self.canRun = False
elif queenNumber > 13:
print "ERROR: This solution would take too long to calculate, and your computer would probably run out of memory first!"
self.canRun = False
#Create an empty table
def blankTable(self):
table = []
for row in xrange(self.tableSize):
new = []
for col in xrange(self.tableSize):
new.append(0);
table.append(new)
return table
#Place a queen in a table
def placeQueen(self, table, row, col):
#Copy the table, as python is annoying and will change both
t2 = copy.deepcopy(table)
t2[row][col] = 1
return t2
#The main program loop
def loopBoard(self):
#The column we are currently looking at
col = 1
#Loop while the queue isn't empty, and there are still move possibilities to explore
while len(self.queue):
#Create a new empty queue
queue2 = []
#Update status
print col, "Queens Placed"
#Loop the queue, looking for positions from each status
#s is an array containing the current queen positions for this status
for s in self.queue:
#Get what moves are available from this status
availableMoves = self.getPositions(s, col)
#If we are placing the last queen, and there are solutions available, finish
if col == self.tableSize -1 and len(availableMoves):
#Clear queue
self.queue = []
#Get the solution (or one of them, we only care about the first one)
s = availableMoves[0]
break;
#Add the possible moves to the new queue
#This a table containing all queens now placed
if len(availableMoves):
queue2 += availableMoves
#Replace the old queue with the new one
self.queue = queue2
#Increase Queen/col counter
col += 1
self.finish(s, col)
#Get an array of moves that are available, given info about the current table, and the current column
def getPositions(self, table, col):
#Create a row counter, and array to contain our position info
row = 0
possiblePositions = []
#Loop all rows on the board
while row < self.tableSize:
#If we can place in this space
if self.canPlace(table, row, col):
#Add the table with the newly added queen to the list of possible moves
possiblePositions.append(self.placeQueen(table, row, col))
row += 1
return possiblePositions
#Check whether or not we can place a queen in a position, given the table and the row and col of the desired position
#Return True if space is available
def canPlace(self, table, row, col):
# - Direction
# Check left/right
x = 0
#Loop across the table
while x < self.tableSize:
if table[x][col]:
return False
x += 1
# | Direction
#Check up/down
y = 0
#Loop down the table
while y < self.tableSize:
if table[row][y]:
return False
y += 1
# / Direction
#Check up right Diagonal
#We can start in the cell 1 up and 1 right of the cell in question, as we have already checked the actual cell in the above 2 checks
x = row + 1
y = col + 1
#Loop up/right through the table
while x < self.tableSize and y < self.tableSize:
if table[x][y]:
return False
x += 1
y += 1
#Check down left Diagonal
#Again, not starting in the cell specified
x = row - 1
y = col - 1
#Loop down/left through the table
while x >= 0 and y >= 0:
if table[x][y]:
return False
x -= 1
y -= 1
# \ Direction
#Check up left diagonal
#Again, not starting in the cell specified
x = row - 1
y = col + 1
#Loop up left through the table
while x >= 0 and y < self.tableSize:
if table[x][y]:
return False
x -= 1
y += 1
#Check down right diagonal
#Again, not starting in the cell specified
x = row + 1
y = col - 1
#Loop down right through the table
while x < self.tableSize and y >= 0:
if table[x][y]:
return False
x += 1
y -= 1
return True
#Output a table to a user, looking all pretty
def display(self, table):
#Max Number Length, so we can indent our table nicely later
mnl = len(str(len(table)))
#New Line
print ""
#Top of the table, E.g " A B C D"
print " "*mnl, " ",
for x in range(self.tableSize):
print self.alphabet[x],
#New Line
print ""
#Row spacer, E.g " * - - - - *
print " " * mnl, " *",
for x in range(self.tableSize):
print "-",
print "*"
#Row Counter
#Print the actual table, with the Queens as 1's, empty space as 0
#Also prefixed by the row number, E.g " 3 | 0 1 0 0 |
x = 1
for row in table:
#If numbers are shorter than the largest number, give them extra spaces so the rows still line up
extraPadding = mnl - len(str(x))
#Show the number prefix, spaces, and | symbol, E.g " 6 | "
print "", x, " "*int(extraPadding) + "|",
#Show the value of the cell (1 or 0)
for col in row:
print col,
#End of the row
print "|"
#Next Row
x += 1
#Show the same row spacer as at the top of the table, E.g " * - - - - *
print " " * mnl, " *",
for x in range(self.tableSize):
print "-",
print "*"
#We're done! Show output to the user
def finish(self, table, col):
#If we found the right number of queens
if col == self.tableSize:
print ""
print "Total of", self.tableSize, "Queens placed!"
print "Solution:"
self.display(table)
else:
print ""
print "ERROR: Could not place all queens for some unknown reason =["
#Run the script
def run(self):
if not self.canRun:
print "ERROR: Can not run"
else:
print ""
print "Working..."
print ""
self.queue = self.getPositions(self.blankTable(), 0)
self.loopBoard()
#Ask the user how many Queens they want to use
def ask():
while True:
print ""
print "How many Queens would you like use? [8]"
input = raw_input()
#Check if the input given is an integer
if input.isdigit():
return int(input)
#If no input is given, use the standard 8
elif input == "":
return 8;
print "ERROR: Invalid Input"
#Run the program
def run():
#Instantiate the solver
qs = QueenSolver()
#While ask hasn't given a valid input
while(not qs.canRun):
qs.setup(ask())
print ""
#GO!
qs.run()
#Prompt the user if they want to run the program again
def prompt():
#Has valid input been received?
while True:
print ""
print "Would you like to run the script again? Please enter Y/N [N]"
input = raw_input()
#Check if the input given is Y or N
if input == "Y" or input == "y":
return True
#Also accept an empty string in place of N
elif input == "N" or input == "n" or input == "":
return False
print "ERROR: Invalid Input"
if __name__ == "__main__":
print ""
print ""
print " #######################################"
print " ## Breadth First Search Queen Solver ##"
print " ## By: Michael Fiford - COMF3 ##"
print " ## Date: 03/12/2013 ##"
print " #######################################"
#Run the script, and prompt them after if they want to run it again
shouldRun = True
while(shouldRun):
run()
shouldRun = prompt()
The difference between DFS and BFS is in the way you are exploring the nodes of the graph.
In the DFS algorithm, you are first exploring the last node added into the stack (last in first out) whereas in the BFS algorithm, you are exploring it on the basis of first in first out (queue).
The resulting change is the code shoud be quite small: in the BFS algorithm, you could use a list to implement the stack, appending new node at the top of the stack and then exploring them:
l=[]
while len(l)>0:
new_node=l.pop()
l.extend(new_node.get_neighbors())
The change is quite small to switch to the BFS algorithm: you switch from a stack to queue. This is implemented in Python in the collections module as a deque (with an efficient implementation of popleft (getting the first item of the list and remove it) and append (appending an item at the end of the queue):
import collections
l=collections.deque()
while len(l)>0:
new_node=l.popleft()
l.extend(new_node.get_neighbors())
Your code can be rewritten to fit with the previous description:
while len(self.queue):
#Create a new empty queue
#queue2 = []
#Update status
print col, "Queens Placed"
#Loop the queue, looking for positions from each status
#s is an array containing the current queen positions for this status
s=queue.pop()
#Get what moves are available from this status
availableMoves = self.getPositions(s, col)
#If we are placing the last queen, and there are solutions available, finish
if col == self.tableSize -1 and len(availableMoves):
#Clear queue
self.queue = []
#Get the solution (or one of them, we only care about the first one)
s = availableMoves[0]
break;
#Add the possible moves to the new queue
#This a table containing all queens now placed
#if len(availableMoves):
# queue2 += availableMoves
queue.extend(availableMoves)
#Replace the old queue with the new one
#self.queue = queue2
#Increase Queen/col counter
col += 1
Let me know if you need more explanations. Hope this helps.

Categories