Need help on past acsl program from 2013

189 Views Asked by At

My teacher is making us do an old ACSL program for practice, and he said that we can use any resources we want. The program is from 2013. link here: https://s3.amazonaws.com/iedu-attachments-question/5a989d787772b7fd88c063aff8393d34_1bee2d300c35eec13edf0a3af515a5a5.pdf

We started the program, but we ran into a wall, and we don't know what to do from here:

board = [
    [ 1,  2,  3,  4,  5],
    [ 6,  7,  8,  9, 10],
    [11, 12, 13, 14, 15],
    [16, 17, 18, 19, 20],
    [21, 22, 23, 24, 25]
]

for i in range(1, 6):
    pieces = input("%d. "%(i)).split(",")
    white = []
    black = []

    black_start = int(pieces[0])+1

    for j in range(1, black_start):
        white.append(int(pieces[j]))

    for k in range(black_start+1, len(pieces)):
        black.append(int(pieces[k]))

    print(white)
    print(black)

    for pair in board:

can anyone give us some tips? we are coding in Python.

1

There are 1 best solutions below

1
On

I don't think board actually serves any purpose.

Your code for parsing input to black and white piece-locations looks good, and should probably be made into a function.

For debugging, it would be useful to have a function which takes black and white piece-locations and prints the board - for example using the characters # for black, O for white, and . for empty. This will help you to see what your program is doing.

For each direction, you should have a function (ie left) which returns the next location (or None if it is on the edge of the board) and another (ie left_lst) which returns a list of consecutive locations in that direction. So left(17) returns 16, left(16) returns None, and left_lst(19) returns [18, 17, 16]. Hint: how can you implement left_lst in terms of left?

Then: for each white piece, check what can be captured by moving toward each direction or away from each direction. You know that there should only be one solution, so as soon as you find it you can return it; if you do not find any, return None.

Hope that helps!


For fun and interest, here's the solution I came up with. Hope you learn lots!

# https://s3.amazonaws.com/iedu-attachments-question/5a989d787772b7fd88c063aff8393d34_1bee2d300c35eec13edf0a3af515a5a5.pdf
NUM_PROBS = 5

# Board looks like
#    1  2  3  4  5
#    6  7  8  9 10
#   11 12 13 14 15
#   16 17 18 19 20
#   21 22 23 24 25
WIDTH = 5
HEIGHT = 5

# display characters for printing:
WHITE = 'O'
BLACK = '#'
EMPTY = '.'

from itertools import product

def parse(s):
    """
    Input:  string of comma-delimited integers
              ex: "3, 12, 17, 22, 3, 9, 14, 10"
            format is num_white, *[white locations], num_black, *[black locations]

    Output: [white locations], [black locations]
              ex: [12, 17, 22], [9, 14, 10]
    """
    ints = [int(i) for i in s.split(',')]
    num_white = ints[0]
    num_black = ints[num_white + 1]
    return ints[1:num_white + 1], ints[-num_black:]

def location_to_coords(location):
    """
    Given a location on the board,
    return 0-based (y,x) coordinates

    ex: location_to_coords(16) returns (3, 0)
    """
    return divmod(location - 1, WIDTH)

def coords_to_location(y, x):
    """
    Given (y, x) coordinates,
    return a location on the board

    ex: coords_to_location(3, 0) returns 16
    """
    return y * WIDTH + x + 1

def print_board(whites, blacks):
    # make an empty board
    board = [[EMPTY] * WIDTH for row in range(HEIGHT)]
    # add white pieces
    for location in whites:
        y, x = location_to_coords(location)
        board[y][x] = WHITE
    # add black pieces
    for location in blacks:
        y, x = location_to_coords(location)
        board[y][x] = BLACK
    # show the result
    print('\n'.join(''.join(row) for row in board))

def make_dir_fn(dy, dx):
    """
    Given a direction, make a function
      which, given a location, returns
      the next location in that direction
      (or None if no such location exists)
    """
    def dir_fn(location):
        y, x = location_to_coords(location)
        if 0 <= y + dy < HEIGHT and 0 <= x + dx < WIDTH:
            return coords_to_location(y + dy, x + dx)
        else:
            return None
    return dir_fn

def make_lst_fn(dir_fn):
    """
    Given a direction function, make a function
      which, given a location, returns a list
      of all consecutive locations in that direction
      to the edge of the board
    """
    def lst_fn(location):
        result = []
        while True:
            location = dir_fn(location)
            if location is None:
                break
            else:
                result.append(location)
        return result
    return lst_fn

# direction functions (one step in the named direction)
left  = make_dir_fn( 0, -1)
right = make_dir_fn( 0,  1)
up    = make_dir_fn(-1,  0)
down  = make_dir_fn( 1,  0)

# relationships between direction functions
dir_fns = [left, right, up, down]
lst_fn  = {dir_fn: make_lst_fn(dir_fn) for dir_fn in dir_fns}
opposite_dir_fn = {left: right, right: left, up: down, down: up}

def attack_toward(location, dir_fn, whites, blacks):
    """
    Return a list of pieces captured by attacking toward given direction
    """
    # make sure attacker is white (swap if needed)
    if location in blacks:
        whites, blacks = blacks, whites
    # make sure we have a valid attacker
    if location not in whites:
        return []
    # make sure we have a space to move to
    next_location = dir_fn(location)
    if (next_location is None) or (next_location in whites) or (next_location in blacks):
        return []
    # get list of attacked locations
    attacked = lst_fn[dir_fn](next_location)
    captured = []
    for location in attacked:
        if location in blacks:
            captured.append(location)
        else:
            break
    return captured

def attack_away(location, dir_fn, whites, blacks):
    """
    Return a list of pieces captured by attacking away from given direction
    """
    # make sure attacker is white (swap if needed)
    if location in blacks:
        whites, blacks = blacks, whites
    # make sure we have a valid attacker
    if location not in whites:
        return []
    # make sure we have a space to move to
    next_location = opposite_dir_fn[dir_fn](location)
    if (next_location is None) or (next_location in whites) or (next_location in blacks):
        return []
    # get list of attacked locations
    attacked = lst_fn[dir_fn](location)
    captured = []
    for location in attacked:
        if location in blacks:
            captured.append(location)
        else:
            break
    return captured

attack_fns = [attack_toward, attack_away]

def main():
    for prob in range(NUM_PROBS):
        # get problem
        whites, blacks = parse(input())
        # pick an attacker, a direction, and an attack method
        for location, dir_fn, attack_fn in product(whites, dir_fns, attack_fns):
            captured = attack_fn(location, dir_fn, whites, blacks)
            # stop when a successful attack is found!
            if captured: break
        # display results
        if captured:
            print(", ".join(str(i) for i in sorted(captured)))
        else:
            print("NONE")

if __name__ == "__main__":
    main()