Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added 3 questions with solutions #17

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

chaitanyatekane
Copy link

Added practice questions and solutions for midterm 1

Copy link
Owner

@tsani tsani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for developing some more problems Chaitanya!

I left some feedback on how to improve them. In their current form they would not be suitable as good practice for midterm 1. It's a little late now to improve them in time, but it will be useful for next semester, so I would like you to apply the changes I'm suggesting.

In the solution file, everything you added is commented out. Please uncomment the solutions and try to move the problems and solutions into an appropriate place in the file. The file is more or less organized by topic with one module for each.


(2). Create a higher-order function `process_path` with the following signature:

val process_path : (int * int -> unit) -> int -> bool array array -> unit
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Midterm 1 doesn't cover any effectful programming, so students would not in general be familiar with functions returning unit that are expected to perform effects.

The name and description of the function are a bit misleading too: process_path sounds like it should accept a path as input, but from looking at the solution, the given function is called by process_path on the coordinates of many squares, not arranged into a path.

Also, the int parameter is redundant with the information in the array, no? In other words, the size of the board doesn't need to be separately specified because it can be calculated from the board.

I'm not sure how to adjust this problem to be helpful study for midterm 1.


Your task is to implement a decoding algorithm following the provided instructions.

(1). Implement a recursive function `decode_message` with the following signature:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good problem but it needs more scaffolding. These questions are intended to be suitable as practice for a midterm, so they should not require the students to look up lots of library functions. Rather, minimal library functions should be required to implement the solution, and the required ones should be specified in the question.

Most of the implementations you wrote as solutions are converting to/from lists/sequences to then work with lists, so the problem can be adjusted to just operate on lists of characters and hence avoid all these conversions.

This function should take an encoded message as a string and recursively decode it following the
instructions embedded in the message. The decoding instructions are as follows:

- Whenever the message contains a number `n`, it indicates that the next `n` characters should be reversed.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specify whether the number can span multiple characters. I wasn't sure just from reading the description and I needed to look at the solution to see whether that was expected or not.

In fact, you can split up the problem into two versions of increasing difficulty: first consider only that the numbers can consist of a single digit, and second that they might consist of multiple digits.

As a hint / guidance on how to solve the problem, mention that the student should implement a function

val rev_first : int -> 'a list -> 'a list

such that rev_take n l reverses the first n elements of l.

instructions embedded in the message. The decoding instructions are as follows:

- Whenever the message contains a number `n`, it indicates that the next `n` characters should be reversed.
- Any character that is not followed by a number should remain unchanged.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be rephrased, since the numbers come before the parts to reverse. Perhaps "characters not following a number are reproduced unchanged into the output".

Comment on lines +1102 to +1107
(2). Create a higher-order function `process_instructions` with the following signature:

val process_instructions : (char -> char) list -> string -> string

This function should take a list of character transformation functions, a string, and apply each transformation function
to the string in sequence, returning the final result. Use higher-order functions to process the transformations.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good problem. Can you generalize this into a more abstract problem on higher-order functions

val maps : ('a -> 'a) list -> 'a list -> 'a list

such that maps [f1; ...; fn] l computes map fn (map f(n-1) ... (map f1 l)).
Ask the student to implement this using List.fold_left.

Comment on lines +1109 to +1113
(3). Implement a function reverse_message with the following signature:

val reverse_message : string -> string

This function should take a string and reverse it without using built-in functions for string reversal.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be dropped since you would ask them to implement rev_first earlier, and that's really what they need when the problem is changed to be about lists.

Comment on lines +1115 to +1117
(4). Write a program that demonstrates the usage of these functions. Provide an encoded message as input, decode it using
the `decode_message` function, reverse it using the `reverse_message` function, and display the final decoded and reversed message.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be dropped.

- You cannot move through blocked squares.
- You cannot visit the same square twice.

(1). Implement a recursive function `explore_chessboard` with the following signature:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of this question is overall good, but we have to get rid of the effectful programming concepts like arrays and mutable variables to make it a suitable question for midterm 1.

Replace the board representation from using arrays to instead use lists bool list list. Then, the pattern of recursion becomes very interesting because the answer to the question "is there a path from the current square to the square (n-1, n-1)" is obtained by trying to solve two subproblems: one where we drop the current column from the chess board, and one where we drop the current row from the chess board.

The challenge in this approach becomes how to avoid looking over the same squares over and over. The solution in that case is probably to use dynamic programming to eliminate the overlap in the solution space.
For a midterm problem that would be too challenging, since many students in 302 are only simultaneously taking the data structures and algorithms course that introduces dynamic programming.
So rather than insist on having the student write an efficient algorithm, adjust the problem to say that efficiency doesn't matter and that this algorithm is meant to be a brute-force backtracking search.

Finally, rather than just return whether whether the path exists or not, the function should return the path. This makes the backtracking search for the path more interesting because the algorithm will return path option where type path = direction list and type direction = Down | Right. Therefore, the results of recursive calls have to be matched on to extend the path with an additional direction.

Comment on lines +1071 to +1081
(3). Implement a function `print_chessboard` with the following signature:

val print_chessboard : bool array array -> unit

This function should take a 2D boolean array representing the chessboard and print it to the console, using `X` to represent
blocked squares and `.` to represent empty squares.

(4). Write a program that demonstrates the usage of these functions. Create a chessboard, print it, explore it using the `explore_chessboard` function
and print the path if a valid path exists.


Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these two should be dropped

Comment on lines +922 to +1008
(*
QUESTION#1 :-

[Topics included :-
- List Manipulation
- Recursion
- Test Cases
]

In this question, you will work with lists in OCaml.
Your task is to write a function reverse_list that takes a list of integers and
returns a new list containing the same elements in reverse order.

Here are the properties you should consider:

- Reversing a list twice should yield the original list.
- Reversing an empty list should still result in an empty list.
- The order of elements within the list should be preserved.

First, write a set of tests for the reverse_list function in the list named reverse_list_tests.
Then, implement the reverse_list function.
*)

(*
QUESTION#2 :-

[Topics included :-
- Pattern Matching
- Integer Operations
- Recursion
- Data Types
- Integer Operations
]

Implementing Unary Natural Number Operations (OCaml)
In this question, you will work with unary representations of natural numbers
and implement various operations on them. You need to write three functions: to_unary, from_unary and add_unary,
which operate on the unary representation of natural numbers.

- to_unary : int -> unary
Implement a function to_unary that takes an OCaml integer and converts it into its representation in unary.
Your implementation must be recursive and should use an inner helper function with an additional parameter.

- from_unary : unary -> int
Implement a function from_unary that converts a unary representation unary into a native OCaml integer.
Your implementation must also be recursive.

- add_unary : unary -> unary -> unary
Implement a function add_unary to add two unary values together. Your implementation should not
convert the unary values into integers, add them, and then convert them back to unary.
Instead, your implementation should be based on recursive calls to add_unary.

By following these instructions, ensure that your implementation adheres to the specified concepts
without making any non-recursive function calls.
*)

(*
QUESTION#3 :-
[Topics included :-
- Higher Order Functions
- Function Types
- Pattern Matching
- Function Application
- Lists
]

In OCaml, higher-order functions are functions that can take other functions as arguments or return functions as results.
This question explores the concept of higher-order functions.

Implement a higher-order function called `apply_to_list` that takes a function f and a list `lst`.
The function `apply_to_list` should apply the function `f` to each element of the list `lst`
and return a new list containing the results.

Here are the specific tasks:

- Define a higher-order function apply_to_list with the following type signature
val apply_to_list : ('a -> 'b) -> 'a list -> 'b list
The function `apply_to_list` should take a function `f` that maps values of type `'a to 'b`, and a list of values of type `'a`.
It should return a list of values of type `'b`.

- Write at least two example functions `f1` and `f2`, each with different type signatures. For instance, `f1` could be a function
that squares an integer, and `f2` could be a function that converts a string to uppercase.

- Apply the apply_to_list function to each of the example functions f1 and f2, and a list of values.
Provide examples of the input list and the expected output for each function.

*)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove these problems since they're already covered either in the problem set or in the homework

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants