A document from MCS 275 Spring 2023, instructor David Dumas. You can also get the notebook file.

MCS 275 Spring 2023 Homework 1 Solutions

  • Course Instructor: David Dumas

  • Contributors to this document: Johnny Joyce

Instructions:

  • Complete the problems below, which ask you to write Python scripts.
  • Upload your python code directly to gradescope, i.e. upload the .py files containing your work. (If you upload a screenshot or other file format, you won't get credit.)

Deadline

This homework assignment must be submitted in Gradescope by Noon central time on Wednesday 18 January 2023.

(Note:That's a deviation from the usual schedule where homework is due on Tuesdays.)

Collaboration

Collaboration is prohibited, and you may only access resources (books, online, etc.) listed below.

Content

This assignment is based on the first week of lecture, so it's basically some MCS 260-level coding exercises. Homework 2 will be similar, but more challenging. Homework 3 will be about new material.

Resources you may consult

The course materials you may refer to for this homework are:

Point distribution

This homework assignment has 2 problems, numbered 2 and 3. The grading breakdown is:

Points Item
3 Autograder
6 Problem 2
6 Problem 3
15 Total

The part marked "autograder" reflects points assigned to your submission based on some simple automated checks for Python syntax, etc. The result of these checks is shown immediately after you submit.

What to do if you're stuck

Ask your instructor or TA a question by email, in office hours, or on discord.

Problem 1 doesn't exist

In Gradescope, the score assigned to your homework submission by the autograder (checking for syntax and docstrings) will be recorded as "Problem 1". Therefore, the numbering of the actual problems begins with 2.

This will happen on every assignment this semester.

Problem 2: Grid window

One of the exercises on worksheet 1 asked you to make a program to draw a box using unicode box-drawing characters. A 10x5 box (width x height) of that type looks like this:

╔════════╗ 
║        ║
║        ║
║        ║
╚════════╝

In this problem you'll modify this program in a few ways. First, we'll deal with a simpler version of box-drawing that doesn't involve so many unusual characters. Instead, + will be used for corners and - or | will be used for edges. The box above would be rendered this way as follows:

+--------+ 
|        |
|        |
|        |
+--------+ 

In addition to changing the box-drawing symbols, for this problem you will want to think of the box drawn by the other program as a window (as you might have on the wall to look outside), to which we'll be adding a grid that subdivides that window into smaller panes. For example, if the box above were subdivided into a 3x2 grid (horizontal count x vertical count), we'd get this:

+--+--+--+ 
|  |  |  |
+--+--+--+
|  |  |  |
+--+--+--+ 

Notice that + is used for corners and for all 3- and 4-way junctions.

Now, critically, we fix terminology to describe this situation. The grid window shown above would be called a 3x2 grid of 4x3 panes because:

  • The smallest rectangles in the picture are 4x3 when you include the outline, like this:
+--+  4 characters wide
|  |  3 lines tall
+--+
  • It's described as a 3x2 grid because there are 3 rectangles horizontally, and 2 rectangles vertically.

Write a program called hwk1prob2.py that contains the following:

  • A function gridwindow that accepts four integer arguments nx,ny, xsize, ysize and returns a string. If printed to the screen, that string should look like a nx x ny grid of xsize x ysize panes.
  • A main program that calls the function gridwindow, using the first four command line arguments to get the function arguments (which need conversion to integers), and which prints the return value to the terminal.

So for example

python3 hwk1prob2.py 2 5 4 3

means "2x5 grid of 4x3 panes" and should print the following to the terminal and exit:

+--+--+
|  |  |
+--+--+
|  |  |
+--+--+
|  |  |
+--+--+
|  |  |
+--+--+
|  |  |
+--+--+

Notes and tricky spots

  • This program shouldn't do any file input or output. That's a difference from worksheet 1 which also changes which command line arguments you need to use for the dimensions.
  • Note that xsize and ysize are the sizes of the smallest rectangles you see, not the overall window.
  • We don't duplicate the edges of adjacent rectangles, i.e. this would be incorrect:
+--++--++--+
|  ||  ||  |
+--++--++--+   INCORRECT!
+--++--++--+
|  ||  ||  |
+--++--++--+
  • You can assume nx and ny are at least 1, and that xsize and ysize are at least 2.

Solution

In [ ]:
import sys


def gridwindow(nx, ny, xsize, ysize):
    """Prints out a (nx * ny) grid of windows, each of size (xsize * ysize)"""

    # First, let's construct some strings that will represent a single row.
    # A row may either contain some pluses and minuses or contain some vertical bars and spaces.

    # This will represent the tops and bottoms of boxes.
    row_top_bottom = "+" + "-"*(xsize - 2) # A plus followed by some minuses reprents a single box (avoid duplicating the plus)
    row_top_bottom *= nx # Multiply it by the number of boxes that we need
    row_top_bottom += "+" # Add a final plus to finish off the last box

    # Similarly, this represents the sides of a row of boxes
    row_sides = "|" + " "*(xsize - 2)
    row_sides *= nx
    row_sides += "|"

    for row in range(ny):

        # Print the top line of a single row of boxes
        print(row_top_bottom)

        # Print the left and right sides of a single row of boxes
        for y in range(ysize - 2):
            print(row_sides)

    # Finally, print the bottom of the final row of boxes
    print(row_top_bottom)
    
    
nx = int(sys.argv[1])
ny = int(sys.argv[2])
xsize = int(sys.argv[3])
ysize = int(sys.argv[4])

gridwindow(nx, ny, xsize, ysize)

Problem 3: All-digit square

Write a program that will find and print the smallest integer perfect square (a number of the form a**2, with a an integer) whose expression in base 10 (decimal) contains every one of the digits 0, 1, 2, ..., 9.

Note you're printing a**2 (the square), not the number a whose square has this property.

Submit this program as hwk1prob3.py.

Solution

This solution is split into two parts: a helper function to check whether a given number contains all digits, and a main loop to call the helper function on different numbers.

In [1]:
def contains_all_digits(a: int):
    """Returns True if argument `a` contains all digits 0-9. Otherwise, returns False."""
    
    # A list of all digits as strings so that we can check if they are in `a`
    digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
    
    for digit in digits:
        # Convert `a` to a string so that we can view each of its individual digits as a single substring.
        if digit not in str(a):
            return False
    
    return True


a = 0
while True: # Infinite while loop
    if contains_all_digits(a ** 2):
        print(a ** 2)
        break
    a += 1
1026753849

Alternatively, here's a super-condensed version:

In [2]:
a = 0
while not all([digit in str(a**2) for digit in "0123456789"]):
    a += 1
print(a**2)
1026753849

So our solution is that 1026753849 is the first integer that is both a perfect square (1026753849 = 32043^2) and contains all digits 0-9.

Revision history

  • 2023-01-12 Initial publication