Problem Description
This is the Interpreter problem. The idea is it's a computer where a list of commands are read from RAM and processed with a set of instructions and registers.
The input file is a list of commands read into RAM that are then processed according to these rules
Solution
I have main do a little bit of the work in this problem. It basically iterates through the commands in RAM, the trouble is some of the commands change the instruction pointer to a new location in RAM. I feel like my logic is a little messy with those tasks. There is a class called RamProcessor that handles each command, but the instance also keeps track of the instruction pointer.
I just treated the commands as regular integers, and then every result was processed as modulo 1000 to keep it to three digits, or roll-over. class RamProcessor: def __init__(self): self.register = [0 for i in range(10)] self.ram = [0 for i in range(1000)] self.instruction = 0 self.instruction_digit1 = 0 self.instruction_digit2 = 0 self.instruction_digit3 = 0 self.ram_counter = 0 def read_ram(self): file_reader = fr.FileReader("inputFile.txt") self.ram = file_reader.file_as_int_list() return self.ram def instruction_router(self, instruction): self.instruction = instruction self.instruction_digit1 = int(self.instruction/100) self.instruction_digit2 = int((self.instruction % 100)/10) self.instruction_digit3 = int(((self.instruction % 100)% 10)) match self.instruction_digit1: case 0: if self.register[self.instruction_digit3] == 0: return 100 else: self.instruction = self.ram[self.register[self.instruction_digit2]] self.ram_counter = self.register[self.instruction_digit2] case 1: print("halt") case 2: self.register[self.instruction_digit2] = self.instruction_digit3 self.register[self.instruction_digit2] = (self.register[self.instruction_digit2] % 1000) case 3: self.register[self.instruction_digit2] += self.instruction_digit3 self.register[self.instruction_digit2] = (self.register[self.instruction_digit2] % 1000) case 4: self.register[self.instruction_digit2] *= self.instruction_digit3 self.register[self.instruction_digit2] = (self.register[self.instruction_digit2] % 1000) case 5: self.register[self.instruction_digit2] = self.register[self.instruction_digit3] self.register[self.instruction_digit2] = (self.register[self.instruction_digit2] % 1000) case 6: self.register[self.instruction_digit2] += self.register[self.instruction_digit3] self.register[self.instruction_digit2] = (self.register[self.instruction_digit2] % 1000) case 7: self.register[self.instruction_digit2] *= self.register[self.instruction_digit3] self.register[self.instruction_digit2] = (self.register[self.instruction_digit2] % 1000) case 8: self.register[self.instruction_digit2] = self.ram[self.register[self.instruction_digit3]] self.register[self.instruction_digit2] = (self.register[self.instruction_digit2] % 1000) case 9: self.ram[self.instruction_digit3] = self.register[self.instruction_digit2] self.ram[self.instruction_digit3] = (self.ram[self.instruction_digit3] % 1000) return 0 def get_ram_contents(self): return self.ram def update_ram_counter(self): return self.ram_counter
See full code on my GitHub
0 Comments
Problem Description
This is the graphical editor problem. It's sort of a text version of the Microsoft Paint program. This one doesn't read in a file, it takes user input of commands to change the "image."
The commands to implement are as follows:
Solution
This is another 2D array problem, but again in Python it's a list of lists.
I'm not sure how clean I got the object design aspects of this, I have a class called Interface and a class called Drawing that handle the user input processing and the drawing of the image. Trouble is I kind of have some interface aspects in the main function. It seems to work, but probably could be cleaner. The Interface class is a while loop that will allow you to continue to read commands until the exit command is given. I also implemented a commend to output a text menu of choices, although that wasn't really in the problem. Here is the menu.
Here is the Interface class, interface method. It's a loop that checks if you made a valid selection and returns your selection. (Here's the bad job by me, the X command is actually handled in the main function. So, that's where the design could be better. Maybe I'll still fix it)
def interface(self): valid_entry = {"C":"valid","I":"valid", "L":"valid", "V":"valid", "H":"valid", "K":"valid", "F":"valid", "S":"valid", "X":"valid", "M":"valid"} while True: self.selection = "" self.selection = input("Select a command or enter M to see the menu:") try: valid_entry[self.selection[0]] == "valid" except KeyError: print("Please make a valid selection, enter M to see menu") continue if self.selection == "M": print(self.command_menu) elif self.selection == "X": print("Exiting") return self.selection break elif valid_entry[self.selection[0]] == "valid": print("valid selction") return self.selection else: print("Please make a valid selection, enter M to see menu")
The main function runs a loop that calls the interface and returns the command to be processed
def execute_main(): return_command = "" image = None problem4_interface = Inter.Interface() process_drawing = Drawing() while return_command != "X": return_command = problem4_interface.interface() if return_command != "X": image = process_drawing.command_router(return_command, image) else: continue
It took a long time to write all the methods to process all the lists (maybe that's why I've posted this with some problems - haha) Here is the method to fill a region in the Drawing class. It determines what color you select as input and changes all of that color to a the new color.
def fill_region(self, image): self.image = image if self.image == None: print("No image has been created, run command I M N") else: self.target_color = self.image[int(self.command[2])-1][int(self.command[4])-1] print(f"target {self.target_color}") for index, num_row in enumerate(self.image): for index2, color_val in enumerate(num_row): if color_val == self.target_color: self.image[index][index2] = self.command[6] else: None print(self.image) return self.image
See the full code on my Github
Problem Description
This problem called the LCD Display. The idea is to take a number as an input and output the same number written with vertical and horizontal dashes. So, input looks like this, where the first number is the segment size and the second number is the number to convert:
The output looks like this, in dashes with each segment being made of two dashes (the first number of the input)
Solution
This seemed kind of silly but still a couple tricky things to solve.
I couldn't think of a way to just create each digit and stitch the strings together (I don't think there is a way to do that). So, I broke it apart into five parts that could be written as normal strings and added together.
Then, there's a method for each portion that will decide what blanks or dashes are needed for the current number. For example, here is the build_top() method. If you need a 1 or 4, it's blank, otherwise it's a line.
def build_top(self): for i in self.number_to_convert: if i == "1" or i == "4": self.top_string += " "*(self.segment_size+2)+ " " else: self.top_string += " " + "-"*self.segment_size + " " return self.top_string
The main function does the following:
def execute_main(): input_file = fr.FileReader("inputFile.txt") raw_input = input_file.file_read_all_str_list() #calculate position strings exe_problem2 = Problem3(raw_input[0], raw_input[2:]) top = exe_problem2.build_top() for i in range(int(raw_input[0])): upper = exe_problem2.build_upper() upper += "\n"+ upper middle = exe_problem2.build_middle() for i in range(int(raw_input[0])): lower = exe_problem2.build_lower() lower += "\n" + lower bottom = exe_problem2.build_bottom() #combine position strings output_string = top + "\n" + upper + "\n" + middle + "\n" + lower +"\n" + bottom output_file = fw.FileWriter("PyProblem3-Output.txt") output_file.file_write_all_str(output_string)
See the full code on my Github
Problem Description
This problem is taken from the game Minesweeper on Windows. The input is a static board of mines and blank locations (* and .)
Like this:
The objective is to create an output file with the same game board only with the blanks replaced with a count of the adjacent count.
Like this: Solution
I think the intention of this problem was to solve a 2D array problem. Well, there's not really arrays in Python, so I used a list of lists. (Lists are pretty much arrays)
The tricky thing about this problem was thinking of a way to iterate the list and perform the calculation without writing out of bounds. Here's how I did it:
Couple things, I used list comprehensions to initialize the list of empty lists like this: self.game_space = [[] for i in range(self.rows)]
Then I could just append to the lists like this and didn't need to know the number of columns of the game board to do it.
This is the more Pythonic way to do this (I think). Adding the index variable and enumerate keyword allows using the lists as iterators in the for loops. You could use nested for loops with counters like i and j along with the range() function. That would look more like C++ but is not the thing. (I guess I could have skipped the elif part, but I like how this reads) def process_gameboard(self, input_game): #convert strings to ints, use 88 as the sentinal for * for index, row in enumerate(input_game): for char in row: if char == "*": self.game_space[index].append(88) elif char == ".": self.game_space[index].append(0) else: None
See the full code on my Github
Problem Description
Python Problem 1 is called the 3n+1 problem. This is an actual famous math/CS problem (search for Collatz conjecture). The objective here is to read in an input that consists of a pair of numbers. The first number is the starting point in a consecutive sequence of integers extending to the ending number. Each number is processed through the 3n+1 algorithm keeping track of the cycle time for each input to cycle to n=1.
Here is the calculation, if the number n is even, divide by 2. If the number is odd, multiply by 3 and add 1. The result of that is the new n, continue until you get to n=1. Keep track of how many cycles it takes to get to n=1 For example, an input might be 1 10 n=1 and done right away. Cycle time is 1 n=2, 2/2=1. Cycle time is 2 n=3 … n=10 The desired output is the input plus the longest cycle time. Input: 1 10 Output: 1 10 20 Solution
This problem is pretty straight forward. I created a class for the problem solution, file input and file output. There is a method that solves the actual 3n+1 calculation from input to n=1 and returns the number of cycles.
The main loop just keeps track of the longest cycle count and formats the output string. I'm still learning the best way to structure things, but I run with a main function like this: if __name__ == "__main__": execute_main()
They call this "dunder name, dunder main" and it's a way to either run your code from a terminal or import it like a script. (dunder is a way to say double underscore out loud - I guess I'm typing - oh well)
Here is an image of running the code like a script. Note that I added a print statement for this to work, the output is supposed to just go to a file
Look at that!
Other notes, I'm using VS Code on Linux for development. I also have been setting up a virtual environment for loading packages and keeping my install clean. I only used native Python for this, but it a good practice. See the full code on my Github
This is the LabVIEW code to create a trace graph display for an Agilent U2001A power sensor. Here is the write up
This is the DOT-TE code as written up
|
Archives
December 2022
Categories |