├── LICENSE
├── README.md
├── assignments
├── week_0
│ └── pset0
│ │ └── README.md
├── week_1
│ ├── lab_1
│ │ ├── hello
│ │ │ ├── README.md
│ │ │ └── hello.c
│ │ └── population
│ │ │ ├── README.md
│ │ │ └── population.c
│ └── pset1
│ │ ├── cash
│ │ ├── README.md
│ │ └── cash.c
│ │ ├── credit
│ │ ├── README.md
│ │ └── credit.c
│ │ └── mario
│ │ ├── less
│ │ ├── README.md
│ │ └── mario.c
│ │ └── more
│ │ ├── README.md
│ │ └── mario.c
└── week_2
│ ├── lab_2
│ └── scrabble
│ │ └── README.md
│ └── pset2
│ ├── caesar
│ └── README.md
│ ├── readability
│ └── README.md
│ └── substitution
│ └── README.md
└── cs50x.jpeg
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 HawksSpawn
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CS50's Introduction to Computer Science
2 |
3 |
4 |
5 | > Demanding, but definitely doable.
6 | > Social, but educational.
7 | > A focused topic, but broadly applicable skills.
8 | > CS50 is the quintessential Harvard course.
9 |
10 | ## Instructor
11 |
12 | [David J. Malan](https://cs.harvard.edu/malan/)
13 | [malan@harvard.edu](mailto:malan@harvard.edu)
14 | [
](https://www.facebook.com/dmalan)
15 | [
](https://github.com/dmalan)
16 | [
](https://www.instagram.com/davidjmalan/)
17 | [
](https://www.linkedin.com/in/malan/)
18 | [
](https://orcid.org/0000-0001-5338-2522)
19 | [
](https://www.quora.com/profile/David-J-Malan)
20 | [
](https://www.reddit.com/user/davidjmalan)
21 | [
](https://twitter.com/davidjmalan)
22 |
23 | ## Syllabus
24 |
25 | Introduction to the intellectual enterprises of computer science and the art of programming. This course teaches students how to think algorithmically and solve problems
26 | efficiently. Topics include abstraction, algorithms, data structures, encapsulation, resource management, security, software engineering, and web programming. Languages include
27 | C, Python, and SQL plus HTML, CSS, and JavaScript. Problem sets inspired by the arts, humanities, social sciences, and sciences. Course culminates in a final project. Designed
28 | for concentrators and non-concentrators alike, with or without prior programming experience. Two thirds of CS50 students have never taken CS before. Among the overarching goals
29 | of this course are to inspire students to explore unfamiliar waters, without fear of failure, create an intensive, shared experience, accessible to all students, and build
30 | community among students.
31 |
32 | ## Expectations
33 |
34 | You are expected to
35 |
36 | • submit ten problem sets,
37 | • submit ten labs, and
38 | • submit a final project.
39 |
40 | ## Websites
41 |
42 | * [CS50's Introduction to Computer Science - **Edx**](https://www.edx.org/course/cs50s-introduction-to-computer-science)
43 | * [CS50's Introduction to Computer Science - **OpenCourseWare**](https://cs50.harvard.edu/x/2021/)
44 |
45 | ## Certificates
46 |
47 | CS50x is free to take, and you are welcome to submit the course’s ten problem sets and final project for automated feedback. To be eligible for a
48 | [verified certificate](https://www.edx.org/verified-certificate) from edX, however, you must receive a satisfactory score (at least 70%) on each problem you submit as part of
49 | one of the course’s ten problem sets as well as on the course’s final project.
50 |
51 | Problems are evaluated along axes of correctness (as determined by a program called `check50`) and style (as determined by a program called `style50`), with scores ordinarily
52 | computed as 3 × correctness + 1 × style.
53 |
54 | ## Books
55 |
56 | No books are required or recommended for this course. However, you might find the below books of interest. Realize that free, if not superior, resources can be found on the
57 | course’s website.
58 |
59 | *Hacker’s Delight*, Second Edition
60 | Henry S. Warren Jr.
61 | Pearson Education, 2013
62 | ISBN 0-321-84268-5
63 |
64 | *How Computers Work*, Tenth Edition
65 | Ron White
66 | Que Publishing, 2014
67 | ISBN 0-7897-4984-X
68 |
69 | *Programming in C*, Fourth Edition
70 | Stephen G. Kochan
71 | Pearson Education, 2015
72 | ISBN 0-321-77641-0
73 |
74 | ## Lectures
75 |
76 | [Week 0](https://cs50.harvard.edu/x/2021/weeks/0/) Scratch
77 | [Week 1](https://cs50.harvard.edu/x/2021/weeks/1/) C
78 | [Week 2](https://cs50.harvard.edu/x/2021/weeks/2/) Arrays
79 | [Week 3](https://cs50.harvard.edu/x/2021/weeks/3/) Algorithms
80 | [Week 4](https://cs50.harvard.edu/x/2021/weeks/4/) Memory
81 | [Week 5](https://cs50.harvard.edu/x/2021/weeks/5/) Data Structures
82 | [Week 6](https://cs50.harvard.edu/x/2021/weeks/6/) Python
83 | [Week 7](https://cs50.harvard.edu/x/2021/weeks/7/) SQL
84 | [Week 8](https://cs50.harvard.edu/x/2021/weeks/8/) HTML, CSS, JavaScript
85 | [Week 9](https://cs50.harvard.edu/x/2021/weeks/9/) Flask
86 | [Week 10](https://cs50.harvard.edu/x/2021/weeks/10/) Ethics
87 |
88 | [Security](https://cs50.harvard.edu/x/2021/weeks/security/)
89 | [Artificial Intelligence](https://cs50.harvard.edu/x/2021/weeks/ai/)
90 |
91 | ## Problem Sets
92 |
93 | **Week 0**
94 | [Scratch](https://github.com/HawksSpawn/cs50-introduction-to-computer-science/tree/main/assignments/week_0/pset0#project) - 100%
95 |
96 | **Week 1**
97 | [Lab 1: Population Growth](assignments/week_1/lab_1/population/population.c) - 100%
98 | [Hello](assignments/week_1/lab_1/hello/hello.c) - 100%
99 | [Mario (Less)](assignments/week_1/pset1/mario/less/mario.c) - 100%
100 | [Mario (More)](assignments/week_1/pset1/mario/more/mario.c) - 100%
101 | [Cash](assignments/week_1/pset1/cash/cash.c) - 100%
102 | [Credit](assignments/week_1/pset1/credit/credit.c) - 100%
103 |
104 | **Week 2**
105 | Lab 2: Scrabble
106 | Readability
107 | Caesar
108 | Substitution
109 |
110 | **Week 3**
111 | Lab 3: Sort
112 | Plurality
113 | Runoff
114 | Tideman
115 |
116 | **Week 4**
117 | Lab 4: Volume
118 | Filter (Less)
119 | Filter (More)
120 | Recover
121 |
122 | **Week 5**
123 | Lab 5: Inheritance
124 | Speller
125 |
126 | **Week 6**
127 | Lab 6: World Cup
128 | Sentimental / Hello
129 | Sentimental / Mario (Less)
130 | Sentimental / Mario (More)
131 | Sentimental / Cash
132 | Sentimental / Credit
133 | Sentimental / Readability
134 | DNA
135 |
136 | **Week 7**
137 | Lab 7: Songs
138 | Movies
139 | Fiftyville
140 |
141 | **Week 8**
142 | Lab 8: Trivia
143 | Homepage
144 |
145 | **Week 9**
146 | Lab 9: Birthdays
147 | Finance
148 |
149 | **Week 10**
150 | Lab 10: Ethics
151 |
152 | **Final Project**
153 | Final Project
154 |
155 | ## Academic Honesty
156 |
157 | This course’s philosophy on academic honesty is best stated as “be reasonable.” The course recognizes that interactions with classmates and others can facilitate mastery of the
158 | course’s material. However, there remains a line between enlisting the help of another and submitting the work of another. This policy characterizes both sides of that line.
159 |
160 | The essence of all work that you submit to this course must be your own. Collaboration on problem sets is not permitted except to the extent that you may ask classmates and
161 | others for help so long as that help does not reduce to another doing your work for you. Generally speaking, when asking for help, you may show your code to others, but you may
162 | not view theirs, so long as you and they respect this policy’s other constraints. Collaboration on the course’s final project is permitted to the extent prescribed by its
163 | specification.
164 |
165 | Below are rules of thumb that (inexhaustively) characterize acts that the course considers reasonable and not reasonable. If in doubt as to whether some act is reasonable, do
166 | not commit it. If the course determines that you have commited an act that is not reasonable, you may be deemed ineligible for a certificate. If you commit some act that is not
167 | reasonable but bring it to the attention of the course’s instructor within 72 hours, the course may reconsider that outcome.
168 |
169 | ### Reasonable
170 |
171 | * Communicating with classmates about problem sets’ problems in English (or some other spoken language).
172 | * Discussing the course’s material with others in order to understand it better.
173 | * Helping a classmate identify a bug in his or her code in person or online, as by viewing, compiling, or running his or her code, even on your own computer.
174 | * Incorporating a few lines of code that you find online or elsewhere into your own code, provided that those lines are not themselves solutions to assigned problems and that
175 | you cite the lines’ origins.
176 | * Sending or showing code that you’ve written to someone, possibly a classmate, so that he or she might help you identify and fix a bug.
177 | * Sharing a few lines of your own code online so that others might help you identify and fix a bug.
178 | * Turning to the web or elsewhere for instruction beyond the course’s own, for references, and for solutions to technical difficulties, but not for outright solutions to
179 | problem set’s problems or your own final project.
180 | * Whiteboarding solutions to problem sets with others using diagrams or pseudocode but not actual code.
181 | * Working with (and even paying) a tutor to help you with the course, provided the tutor does not do your work for you.
182 |
183 | ### Not Reasonable
184 |
185 | * Accessing a solution to some problem prior to (re-)submitting your own.
186 | * Asking a classmate to see his or her solution to a problem set’s problem before (re-)submitting your own.
187 | * Decompiling, deobfuscating, or disassembling the staff’s solutions to problem sets.
188 | * Failing to cite (as with comments) the origins of code or techniques that you discover outside of the course’s own lessons and integrate into your own work, even while
189 | respecting this policy’s other constraints.
190 | * Giving or showing to a classmate a solution to a problem set’s problem when it is he or she, and not you, who is struggling to solve it.
191 | * Paying or offering to pay an individual for work that you may submit as (part of) your own.
192 | * Searching for or soliciting outright solutions to problem sets online or elsewhere.
193 | * Splitting a problem set’s workload with another individual and combining your work.
194 | * Submitting (after possibly modifying) the work of another individual beyond the few lines allowed herein.
195 | * Submitting the same or similar work to this course that you have submitted or will submit to another.
196 | * Viewing another’s solution to a problem set’s problem and basing your own solution on it.
197 |
--------------------------------------------------------------------------------
/assignments/week_0/pset0/README.md:
--------------------------------------------------------------------------------
1 | # Scratch
2 |
3 | It’s time to choose your own adventure! Your assignment, quite simply, is to implement in Scratch any project of your choice, be it an interactive story, game, animation, or
4 | anything else, subject only to the following requirements:
5 |
6 | - Your project must have at least two sprites, at least one of which must resemble something other than a cat.
7 | - Your project must have at least three scripts total (i.e., not necessarily three per sprite).
8 | - Your project must use at least one condition.
9 | - Your project must use at least one loop.
10 | - Your project must use at least one variable.
11 | - Your project must use at least one sound.
12 | - Your project should be more complex than most of those demonstrated in lecture (many of which, though instructive, were quite short) but it can be less complex than
13 | *Ivy’s Hardest Game*. As such, your project should probably use a few dozen puzzle pieces overall.
14 |
15 | If you’d like to try out some Scratch projects from past students, here are a few:
16 |
17 | - [It’s Raining Men](https://scratch.mit.edu/projects/37412/), from lecture
18 | - [Ivy’s Hardest Game](https://scratch.mit.edu/projects/326129587/), a game, Harvard edition
19 | - [Soccer](https://scratch.mit.edu/projects/37413/), a game
20 | - [Cookie Love Story](https://scratch.mit.edu/projects/26329196/), an animation
21 | - [Gingerbread tales](https://scratch.mit.edu/projects/277536784/), an interactive story
22 | - [Intersection](https://scratch.mit.edu/projects/75390754/), a game
23 | - [Oscartime](https://scratch.mit.edu/projects/277537196/), a game
24 |
25 | You might find these [tutorials](https://scratch.mit.edu/projects/editor/?tutorial=all) or [starter projects](https://scratch.mit.edu/starter-projects) helpful.
26 | And you’re welcome to explore [scratch.mit.edu](https://scratch.mit.edu/explore/projects/all) for inspiration. But try to think of an idea on your own, and then set out to
27 | implement it. However, don’t try to implement the entirety of your project all at once: pluck off one piece at a time. In other words, take baby steps: write a bit of code
28 | (i.e., drag and drop a few puzzle pieces), test, write a bit more, test, and so forth. And select **File** > **Save now** every few minutes so that you don’t lose any work!
29 |
30 | If, along the way, you find it too difficult to implement some feature, try not to fret; alter your design or work around the problem.
31 | If you set out to implement an idea that you find fun, odds are you won’t find it too hard to satisfy the above requirements.
32 |
33 | Alright, off you go. Make us proud!
34 |
35 | Once finished with your project, select **File** > **Save now** one last time. Then select **File** > **Save to your computer** and keep that file so that you can submit it.
36 | If prompted by your computer to **Open** or **Save** the file, be sure to **Save** it.
37 |
38 | ## How to Submit
39 |
40 | Be sure to complete both steps below, in order!
41 |
42 | ### Step 1 of 2
43 |
44 | Submit [this form](https://forms.cs50.io/b4e8bd58-1dd6-4a98-91a4-0d95143d63c6).
45 |
46 | ### Step 2 of 2
47 |
48 | This step assumes that you’ve downloaded your Scratch project as a file whose name ends in `.sb3`. And this step also assumes that you’ve
49 | [signed up for a GitHub account](https://github.com/join), per the above form.
50 |
51 | 1. Visit [this link](https://submit.cs50.io/invites/9770b67479384c4d8c37790779e466d9), log in with your GitHub account, and click **Authorize cs50**.
52 | 2. Check the box indicating that you’d like to grant course staff access to your submissions, and click **Join course**.
53 | 3. Go to [https://submit.cs50.io/upload/cs50/problems/2021/x/scratch](https://submit.cs50.io/upload/cs50/problems/2021/x/scratch).
54 | 4. Click “Choose File” and choose your `.sb3` file. Click **Submit**.
55 |
56 | That’s it! Once your submission uploads, you should be redirected to your submission page. Click the submission link and then the **check50** link to see which requirements your
57 | project met. You are welcome to resubmit as many times as you’d like (before the deadline)!
58 |
59 | To view your current progress in the course, visit the course gradebook at [cs50.me/cs50x](https://cs50.me/cs50x)!
60 |
61 | ## Project
62 |
63 | - [Shark!!!](https://scratch.mit.edu/projects/421547141/)
64 |
--------------------------------------------------------------------------------
/assignments/week_1/lab_1/hello/README.md:
--------------------------------------------------------------------------------
1 | # Hello
2 |
3 | ## Getting Started
4 |
5 | CS50 IDE is a web-based “integrated development environment” that allows you to program “in the cloud,” without installing any software locally. Indeed, CS50 IDE provides you
6 | with your very own “workspace” (i.e., storage space) in which you can save your own files and folders (aka directories).
7 |
8 | ### Logging In
9 |
10 | Head to [ide.cs50.io](https://ide.cs50.io/) and click “Sign in with GitHub” to access your CS50 IDE. Once your IDE loads, you should see that (by default) it’s divided into
11 | three parts. Toward the top of CS50 IDE is your “text editor”, where you’ll write all of your programs. Toward the bottom of is a “terminal window” (light blue, by default), a
12 | command-line interface (CLI) that allows you to explore your workspace’s files and directories, compile code, run programs, and even install new software. And on the left is
13 | your “file browser”, which shows you all of the files and folders currently in your IDE.
14 |
15 | Start by clicking inside your terminal window. You should find that its “prompt” resembles the below.
16 |
17 | ~/ $
18 |
19 | Click inside of that terminal window and then type
20 |
21 | mkdir ~/pset1/
22 |
23 | followed by Enter in order to make a directory (i.e., folder) called `pset1` inside of your home directory. Take care not to overlook the space between `mkdir` and `~/pset1` or
24 | any other character for that matter! Keep in mind that `~` always denotes your home directory and `~/pset1` denotes a directory called `pset1`, which is inside of `~`.
25 |
26 | Here on out, to execute (i.e., run) a command means to type it into a terminal window and then hit Enter. Commands are “case-sensitive,” so be sure not to type in uppercase
27 | when you mean lowercase or vice versa.
28 |
29 | Now execute
30 |
31 | cd ~/pset1/
32 |
33 | to move yourself into (i.e., open) that directory. Your prompt should now resemble the below.
34 |
35 | ~/pset1/ $
36 |
37 | If not, retrace your steps and see if you can determine where you went wrong.
38 |
39 | Now execute
40 |
41 | mkdir ~/pset1/hello
42 |
43 | to create a new directory called `hello` inside of your `pset1` directory. Then execute
44 |
45 | cd ~/pset1/hello
46 |
47 | to move yourself into that directory.
48 |
49 | Shall we have you write your first program? From the *File* menu, click *New File*, and save it (as via the *Save* option in the *File* menu) as `hello.c` inside of your
50 | `~/pset1/hello` directory. Proceed to write your first program by typing precisely these lines into the file:
51 |
52 | ```c
53 | #include
54 |
55 | int main(void)
56 | {
57 | printf("hello, world\n");
58 | }
59 | ```
60 |
61 | Notice how CS50 IDE adds “syntax highlighting” (i.e., color) as you type, though CS50 IDE’s choice of colors might differ from this problem set’s. Those colors aren’t actually
62 | saved inside of the file itself; they’re just added by CS50 IDE to make certain syntax stand out. Had you not saved the file as `hello.c` from the start, CS50 IDE wouldn’t know
63 | (per the filename’s extension) that you’re writing C code, in which case those colors would be absent.
64 |
65 | ## Listing Files
66 |
67 | Next, in your terminal window, immediately to the right of the prompt (`~/pset1/hello/$`), execute
68 |
69 | ls
70 |
71 | You should see just `hello.c`? That’s because you’ve just listed the files in your `hello` folder. In particular, you *executed* (i.e., ran) a command called `ls`, which is
72 | shorthand for “list.” (It’s such a frequently used command that its authors called it just `ls` to save keystrokes.) Make sense?
73 |
74 | ## Compiling Programs
75 |
76 | Now, before we can execute the `hello.c` program, recall that we must *compile* it with a *compiler* (e.g., `clang`), translating it from *source code* into *machine code*
77 | (i.e., zeroes and ones). Execute the command below to do just that:
78 |
79 | clang hello.c
80 |
81 | And then execute this one again:
82 |
83 | ls
84 |
85 | This time, you should see not only `hello.c` but `a.out` listed as well? (You can see the same graphically if you click that folder icon again.) That’s because `clang` has
86 | translated the source code in `hello.c` into machine code in `a.out`, which happens to stand for “assembler output,” but more on that another time.
87 |
88 | Now run the program by executing the below.
89 |
90 | ./a.out
91 |
92 | Hello, world, indeed!
93 |
94 | ## Naming Programs
95 |
96 | Now, `a.out` isn’t the most user-friendly name for a program. Let’s compile `hello.c` again, this time saving the machine code in a file called, more aptly, `hello`. Execute
97 | the below.
98 |
99 | clang -o hello hello.c
100 |
101 | Take care not to overlook any of those spaces therein! Then execute this one again:
102 |
103 | ls
104 |
105 | You should now see not only `hello.c` (and `a.out` from before) but also `hello` listed as well? That’s because `-o` is a *command-line argument*, sometimes known as a *flag*
106 | or a *switch*, that tells `clang` to output (hence the `o`) a file called `hello`. Execute the below to try out the newly named program.
107 |
108 | ./hello
109 |
110 | Hello there again!
111 |
112 | ## Making Things Easier
113 |
114 | Recall that we can automate the process of executing `clang`, letting `make` figure out how to do so for us, thereby saving us some keystrokes. Execute the below to compile
115 | this program one last time.
116 |
117 | make hello
118 |
119 | You should see that `make` executes `clang` with even more command-line arguments for you? More on those, too, another time!
120 |
121 | Now execute the program itself one last time by executing the below.
122 |
123 | ./hello
124 |
125 | Phew!
126 |
127 | ## Getting User Input
128 |
129 | Suffice it to say, no matter how you compile or execute this program, it only ever prints `hello, world`. Let’s personalize it a bit, just as we did in class.
130 |
131 | Modify this program in such a way that it first prompts the user for their name and then prints `hello, so-and-so`, where `so-and-so` is their actual name.
132 |
133 | As before, be sure to compile your program with:
134 |
135 | make hello
136 |
137 | And be sure to execute your program, testing it a few times with different inputs, with:
138 |
139 | ./hello
140 |
141 | ### Hints
142 |
143 | **Don’t recall how to prompt the user for their name?**
144 |
145 | Recall that you can use `get_string` as follows, storing its *return value* in a variable called `name` of type `string`.
146 |
147 | ```c
148 | string name = get_string("What is your name?\n");
149 | ```
150 |
151 | **Don’t recall how to format a string?**
152 |
153 | Don’t recall how to join (i.e., concatenate) the user’s name with a greeting? Recall that you can use `printf` not only to print but to format a string (hence, the `f` in
154 | `printf`), a la the below, wherein `name` is a `string`.
155 |
156 | ```c
157 | printf("hello, %s\n", name);
158 | ```
159 |
160 | **Use of undeclared identifier?**
161 |
162 | Seeing the below, perhaps atop other errors?
163 |
164 | error: use of undeclared identifier 'string'; did you mean 'stdin'?
165 |
166 | Recall that, to use `get_string`, you need to include `cs50.h` (in which `get_string` is *declared*) atop a file, as with:
167 |
168 | ```c
169 | #include
170 | ```
171 |
172 | ### How to Test Your Code
173 |
174 | Execute the below to evaluate the correctness of your code using `check50`. But be sure to compile and test it yourself as well!
175 |
176 | check50 cs50/problems/2021/x/hello
177 |
178 | Execute the below to evaluate the style of your code using `style50`.
179 |
180 | style50 hello.c
181 |
182 | ## How to Submit
183 |
184 | Execute the below, logging in with your GitHub username and password when prompted. For security, you’ll see asterisks (`*`) instead of the actual characters in your password.
185 |
186 | submit50 cs50/problems/2021/x/hello
187 |
--------------------------------------------------------------------------------
/assignments/week_1/lab_1/hello/hello.c:
--------------------------------------------------------------------------------
1 | // Print "hello, name", where 'name' is the user's name
2 |
3 | #include
4 | #include
5 |
6 | int main(void)
7 | {
8 | string name = get_string("What is your name?\n");
9 | printf("hello, %s\n", name);
10 | }
11 |
--------------------------------------------------------------------------------
/assignments/week_1/lab_1/population/README.md:
--------------------------------------------------------------------------------
1 | # Lab 1: Population Growth
2 |
3 | Determine how long it takes for a population to reach a particular size.
4 |
5 | ```
6 | $ ./population
7 | Start size: 100
8 | End size: 200
9 | Years: 9
10 | ```
11 |
12 | ## Background
13 |
14 | Say we have a population of `n` llamas. Each year, `n / 3` new llamas are born, and `n / 4` llamas pass away.
15 |
16 | For example, if we were to start with `n = 1200` llamas, then in the first year, `1200 / 3 = 400` new llamas would be born and `1200 / 4 = 300` llamas would pass away.
17 | At the end of that year, we would have `1200 + 400 - 300 = 1300` llamas.
18 |
19 | To try another example, if we were to start with `n = 1000` llamas, at the end of the year, we would have `1000 / 3 = 333.33` new llamas. We can’t have a decimal portion of a
20 | llama, though, so we’ll truncate the decimal to get `333` new llamas born. `1000 / 4 = 250` llamas will pass away, so we’ll end up with a total of `1000 + 333 - 250 = 1083`
21 | llamas at the end of the year.
22 |
23 | ## Getting Started
24 |
25 | - Copy the “distribution code” (i.e., starter code) from [cdn.cs50.net/2020/fall/labs/1/population.c](https://cdn.cs50.net/2020/fall/labs/1/population.c) into a new file in
26 | your IDE called `population.c`.
27 |
28 | ## Implementation Details
29 |
30 | Complete the implementation of `population.c`, such that it calculates the number of years required for the population to grow from the start size to the end size.
31 |
32 | - Your program should first prompt the user for a starting population size.
33 | - If the user enters a number less than 9 (the minimum allowed population size), the user should be re-prompted to enter a starting population size until they enter a
34 | number that is greater than or equal to 9. (If we start with fewer than 9 llamas, the population of llamas will quickly become stagnant!)
35 | - Your program should then prompt the user for an ending population size.
36 | - If the user enters a number less than the starting population size, the user should be re-prompted to enter an ending population size until they enter a number that is
37 | greater than or equal to the starting population size. (After all, we want the population of llamas to grow!)
38 | - Your program should then calculate the (integer) number of years required for the population to reach at least the size of the end value.
39 | - Finally, your program should print the number of years required for the llama population to reach that end size, as by printing to the terminal `Years: n`, where `n` is the
40 | number of years.
41 |
42 | ### Hints
43 |
44 | - If you want to repeatedly re-prompt the user for the value of a variable until some condition is met, you might want to use a `do ... while` loop. For example, recall the
45 | following code from lecture, which prompts the user repeatedly until they enter a positive integer.
46 |
47 | ```c
48 | int n;
49 | do
50 | {
51 | n = get_int("Positive Integer: ");
52 | }
53 | while (n < 1);
54 | ```
55 | How might you adapt this code to ensure a start size of at least 9, and an end size of at least the start size?
56 | - To declare a new variable, be sure to specify its data type, a name for the variable, and (optionally) what its initial value should be.
57 | - For example, you might want to create a variable to keep track of how many years have passed.
58 | - To calculate how many years it will take for the population to reach the end size, another loop might be helpful! Inside the loop, you’ll likely want to update the population
59 | size according to the formula in the Background, and update the number of years that have passed.
60 | - To print an integer `n` to the terminal, recall that you can use a line of code like
61 |
62 | ```c
63 | printf("The number is %i\n", n);
64 | ```
65 |
66 | to specify that the variable `n` should fill in for the placeholder `%i`.
67 |
68 | ### How to Test Your Code
69 |
70 | Your program should behave per the examples below.
71 |
72 | ```
73 | $ ./population
74 | Start size: 1200
75 | End size: 1300
76 | Years: 1
77 | ```
78 |
79 | ```
80 | $ ./population
81 | Start size: -5
82 | Start size: 3
83 | Start size: 9
84 | End size: 5
85 | End size: 18
86 | Years: 8
87 | ```
88 |
89 | ```
90 | $ ./population
91 | Start size: 20
92 | End size: 1
93 | End size: 10
94 | End size: 100
95 | Years: 20
96 | ```
97 |
98 | ```
99 | $ ./population
100 | Start size: 100
101 | End size: 1000000
102 | Years: 115
103 | ```
104 |
105 | Execute the below to evaluate the correctness of your code using `check50`. But be sure to compile and test it yourself as well!
106 |
107 | check50 cs50/labs/2021/x/population
108 |
109 | Execute the below to evaluate the style of your code using `style50`.
110 |
111 | style50 population.c
112 |
113 | ## How to Submit
114 |
115 | Execute the below, logging in with your GitHub username and password when prompted. For security, you’ll see asterisks (`*`) instead of the actual characters in your password.
116 |
117 | submit50 cs50/labs/2021/x/population
118 |
--------------------------------------------------------------------------------
/assignments/week_1/lab_1/population/population.c:
--------------------------------------------------------------------------------
1 | // Calculate the number of years required for the population to grow from the start size to the end size
2 |
3 | #include
4 | #include
5 |
6 | int get_start_size(string prompt);
7 | int get_end_size(string prompt, int start);
8 | int get_years(int start, int end);
9 |
10 | int main(void)
11 | {
12 | int start = get_start_size("Start size: ");
13 | int end = get_end_size("End size: ", start);
14 | int years = get_years(start, end);
15 |
16 | printf("Years: %i\n", years);
17 | }
18 |
19 | // Prompt user for a starting population size greater than or equal to 9
20 | int get_start_size(string prompt)
21 | {
22 | int start;
23 | do
24 | {
25 | start = get_int("%s", prompt);
26 | }
27 | while (start < 9);
28 |
29 | return start;
30 | }
31 |
32 | // Prompt user for an ending population size greater than or equal to the starting population size
33 | int get_end_size(string prompt, int start)
34 | {
35 | int end;
36 | do
37 | {
38 | end = get_int("%s", prompt);
39 | }
40 | while (end < start);
41 |
42 | return end;
43 | }
44 |
45 | // Calculate the number of years required for the population to reach at least the size of the end value
46 | int get_years(int start, int end)
47 | {
48 | int years = 0;
49 | while (start < end)
50 | {
51 | // Each year, n / 3 new (people/animals) are born, and n / 4 (people/animals) pass away.
52 | start = start + (start / 3) - (start / 4);
53 | years++;
54 | }
55 |
56 | return years;
57 | }
58 |
--------------------------------------------------------------------------------
/assignments/week_1/pset1/cash/README.md:
--------------------------------------------------------------------------------
1 | # Cash
2 |
3 | ## Greedy Algorithms
4 |
5 | 
6 |
7 | When making change, odds are you want to minimize the number of coins you’re dispensing for each customer, lest you run out (or annoy the customer!). Fortunately, computer
8 | science has given cashiers everywhere ways to minimize numbers of coins due: greedy algorithms.
9 |
10 | According to the National Institute of Standards and Technology (NIST), a greedy algorithm is one “that always takes the best immediate, or local, solution while finding an
11 | answer. Greedy algorithms find the overall, or globally, optimal solution for some optimization problems, but may find less-than-optimal solutions for some instances of other
12 | problems.”
13 |
14 | What’s all that mean? Well, suppose that a cashier owes a customer some change and in that cashier’s drawer are quarters (25¢), dimes (10¢), nickels (5¢), and pennies (1¢).
15 | The problem to be solved is to decide which coins and how many of each to hand to the customer. Think of a “greedy” cashier as one who wants to take the biggest bite out of
16 | this problem as possible with each coin they take out of the drawer. For instance, if some customer is owed 41¢, the biggest first (i.e., best immediate, or local) bite that
17 | can be taken is 25¢. (That bite is “best” inasmuch as it gets us closer to 0¢ faster than any other coin would.) Note that a bite of this size would whittle what was a 41¢
18 | problem down to a 16¢ problem, since 41 - 25 = 16. That is, the remainder is a similar but smaller problem. Needless to say, another 25¢ bite would be too big (assuming the
19 | cashier prefers not to lose money), and so our greedy cashier would move on to a bite of size 10¢, leaving him or her with a 6¢ problem. At that point, greed calls for one 5¢
20 | bite followed by one 1¢ bite, at which point the problem is solved. The customer receives one quarter, one dime, one nickel, and one penny: four coins in total.
21 |
22 | It turns out that this greedy approach (i.e., algorithm) is not only locally optimal but also globally so for America’s currency (and also the European Union’s). That is, so
23 | long as a cashier has enough of each coin, this largest-to-smallest approach will yield the fewest coins possible. How few? Well, you tell us!
24 |
25 | ## Implementation Details
26 |
27 | Implement, in a file called `cash.c` in a `~/pset1/cash` directory, a program that first asks the user how much change is owed and then prints the minimum number of coins with
28 | which that change can be made.
29 |
30 | - Use `get_float` to get the user’s input and `printf` to output your answer. Assume that the only coins available are quarters (25¢), dimes (10¢), nickels (5¢), and pennies
31 | (1¢).
32 | - We ask that you use `get_float` so that you can handle dollars and cents, albeit sans dollar sign. In other words, if some customer is owed $9.75 (as in the case where a
33 | newspaper costs 25¢ but the customer pays with a $10 bill), assume that your program’s input will be `9.75` and not `$9.75` or `975`. However, if some customer is owed $9
34 | exactly, assume that your program’s input will be `9.00` or just `9` but, again, not `$9` or `900`. Of course, by nature of floating-point values, your program will
35 | likely work with inputs like `9.0` and `9.000` as well; you need not worry about checking whether the user’s input is “formatted” like money should be.
36 | - You need not try to check whether a user’s input is too large to fit in a `float`. Using `get_float` alone will ensure that the user’s input is indeed a floating-point (or
37 | integral) value but not that it is non-negative.
38 | - If the user fails to provide a non-negative value, your program should re-prompt the user for a valid amount again and again until the user complies.
39 | - So that we can automate some tests of your code, be sure that your program’s last line of output is only the minimum number of coins possible: an integer followed by `\n`.
40 | - Beware the inherent imprecision of floating-point values. Recall `floats.c` from class, wherein, if `x` is `2`, and `y` is `10`, `x / y` is not precisely two tenths! And so,
41 | before making change, you’ll probably want to convert the user’s inputted dollars to cents (i.e., from a `float` to an `int`) to avoid tiny errors that might otherwise add up!
42 | - Take care to round your cents to the nearest penny, as with `round`, which is declared in `math.h`. For instance, if `dollars` is a `float` with the user’s input
43 | (e.g., `0.20`), then code like
44 |
45 | ```
46 | int cents = round(dollars * 100);
47 | ```
48 |
49 | will safely convert `0.20` (or even `0.200000002980232238769531250`) to `20`.
50 |
51 | Your program should behave per the examples below.
52 |
53 | ```
54 | $ ./cash
55 | Change owed: 0.41
56 | 4
57 | ```
58 |
59 | ```
60 | $ ./cash
61 | Change owed: -0.41
62 | Change owed: foo
63 | Change owed: 0.41
64 | 4
65 | ```
66 |
67 | ### How to Test Your Code
68 |
69 | Does your code work as prescribed when you input
70 |
71 | - `-1.00` (or other negative numbers)?
72 | - `0.00`?
73 | - `0.01` (or other positive numbers)?
74 | - letters or words?
75 | - no input at all, when you only hit Enter?
76 |
77 | You can also execute the below to evaluate the correctness of your code using `check50`. But be sure to compile and test it yourself as well!
78 |
79 | check50 cs50/problems/2021/x/cash
80 |
81 | Execute the below to evaluate the style of your code using `style50`.
82 |
83 | style50 cash.c
84 |
85 | ## How to Submit
86 |
87 | Execute the below, logging in with your GitHub username and password when prompted. For security, you’ll see asterisks (`*`) instead of the actual characters in your password.
88 |
89 | submit50 cs50/problems/2021/x/cash
90 |
--------------------------------------------------------------------------------
/assignments/week_1/pset1/cash/cash.c:
--------------------------------------------------------------------------------
1 | // Print how many coins the customer receives as change
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | float get_change(string prompt);
8 | int get_coins(int cents);
9 |
10 | int main(void)
11 | {
12 | float dollars = get_change("Change owed: ");
13 | // Dollars entered by the user are converted to cents (i.e. from a float to an int)
14 | // to avoid tiny errors that might otherwise add up!
15 | int cents = round(dollars * 100);
16 | int coins = get_coins(cents);
17 |
18 | printf("%i\n", coins);
19 | }
20 |
21 | // Prompt user how much change is owed
22 | float get_change(string prompt)
23 | {
24 | float change;
25 | do
26 | {
27 | change = get_float("%s", prompt);
28 | }
29 | while (change < 0);
30 |
31 | return change;
32 | }
33 |
34 | // Calculate the minimum number of coins with which that change can be made
35 | int get_coins(int cents)
36 | {
37 | // It is assumed that the only coins available are quarters (25¢), dimes (10¢), nickels (5¢), and pennies (1¢)
38 | int quarters = 25, dimes = 10, nickels = 5, pennies = 1;
39 | int total_coins = 0;
40 | int coins;
41 |
42 | if (cents >= quarters)
43 | {
44 | // Compute how many quarters you can give
45 | coins = cents / quarters;
46 | // Keeps track of coins used
47 | total_coins += coins;
48 | // Compute the remaining change owed
49 | cents -= coins * quarters;
50 | }
51 |
52 | if (cents >= dimes)
53 | {
54 | coins = cents / dimes;
55 | total_coins += coins;
56 | cents -= coins * dimes;
57 | }
58 |
59 | if (cents >= nickels)
60 | {
61 | coins = cents / nickels;
62 | total_coins += coins;
63 | cents -= coins * nickels;
64 | }
65 |
66 | if (cents >= pennies)
67 | {
68 | total_coins += cents / pennies;
69 | }
70 |
71 | return total_coins;
72 | }
73 |
--------------------------------------------------------------------------------
/assignments/week_1/pset1/credit/README.md:
--------------------------------------------------------------------------------
1 | # Credit
2 |
3 | A credit (or debit) card, of course, is a plastic card with which you can pay for goods and services. Printed on that card is a number that’s also stored in a database
4 | somewhere, so that when your card is used to buy something, the creditor knows whom to bill. There are a lot of people with credit cards in this world, so those numbers are
5 | pretty long: American Express uses 15-digit numbers, MasterCard uses 16-digit numbers, and Visa uses 13- and 16-digit numbers. And those are decimal numbers (0 through 9), not
6 | binary, which means, for instance, that American Express could print as many as 10^15 = 1,000,000,000,000,000 unique cards! (That’s, um, a quadrillion.)
7 |
8 | Actually, that’s a bit of an exaggeration, because credit card numbers actually have some structure to them. All American Express numbers start with 34 or 37; most MasterCard
9 | numbers start with 51, 52, 53, 54, or 55 (they also have some other potential starting numbers which we won’t concern ourselves with for this problem); and all Visa numbers
10 | start with 4. But credit card numbers also have a “checksum” built into them, a mathematical relationship between at least one number and others. That checksum enables
11 | computers (or humans who like math) to detect typos (e.g., transpositions), if not fraudulent numbers, without having to query a database, which can be slow. Of course, a
12 | dishonest mathematician could certainly craft a fake number that nonetheless respects the mathematical constraint, so a database lookup is still necessary for more rigorous
13 | checks.
14 |
15 | ## Luhn’s Algorithm
16 |
17 | So what’s the secret formula? Well, most cards use an algorithm invented by Hans Peter Luhn of IBM. According to Luhn’s algorithm, you can determine if a credit card number is
18 | (syntactically) valid as follows:
19 |
20 | 1. Multiply every other digit by 2, starting with the number’s second-to-last digit, and then add those products’ digits together.
21 | 2. Add the sum to the sum of the digits that weren’t multiplied by 2.
22 | 3. If the total’s last digit is 0 (or, put more formally, if the total modulo 10 is congruent to 0), the number is valid!
23 |
24 | That’s kind of confusing, so let’s try an example with David’s Visa: 4003600000000014.
25 |
26 | 1. For the sake of discussion, let’s first underline every other digit, starting with the number’s second-to-last digit:
27 |
28 | 4003600000000014
29 |
30 | Okay, let’s multiply each of the underlined digits by 2:
31 |
32 | 1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2
33 |
34 | That gives us:
35 |
36 | 2 + 0 + 0 + 0 + 0 + 12 + 0 + 8
37 |
38 | Now let’s add those products’ digits (i.e., not the products themselves) together:
39 |
40 | 2 + 0 + 0 + 0 + 0 + 1 + 2 + 0 + 8 = 13
41 |
42 | 2. Now let’s add that sum (13) to the sum of the digits that weren’t multiplied by 2 (starting from the end):
43 |
44 | 13 + 4 + 0 + 0 + 0 + 0 + 0 + 3 + 0 = 20
45 |
46 | 3. Yup, the last digit in that sum (20) is a 0, so David’s card is legit!
47 |
48 | So, validating credit card numbers isn’t hard, but it does get a bit tedious by hand. Let’s write a program.
49 |
50 | ## Implementation Details
51 |
52 | In a file called `credit.c` in a `~/pset1/credit/` directory, write a program that prompts the user for a credit card number and then reports (via `printf`) whether it is a
53 | valid American Express, MasterCard, or Visa card number, per the definitions of each’s format herein. So that we can automate some tests of your code, we ask that your
54 | program’s last line of output be `AMEX\n` or `MASTERCARD\n` or `VISA\n` or `INVALID\n`, nothing more, nothing less. For simplicity, you may assume that the user’s input will be
55 | entirely numeric (i.e., devoid of hyphens, as might be printed on an actual card). But do not assume that the user’s input will fit in an `int`! Best to use `get_long` from
56 | CS50’s library to get users’ input. (Why?)
57 |
58 | Consider the below representative of how your own program should behave when passed a valid credit card number (sans hyphens).
59 |
60 | ```
61 | $ ./credit
62 | Number: 4003600000000014
63 | VISA
64 | ```
65 |
66 | Now, `get_long` itself will reject hyphens (and more) anyway:
67 |
68 | ```
69 | $ ./credit
70 | Number: 4003-6000-0000-0014
71 | Number: foo
72 | Number: 4003600000000014
73 | VISA
74 | ```
75 |
76 | But it’s up to you to catch inputs that are not credit card numbers (e.g., a phone number), even if numeric:
77 |
78 | ```
79 | $ ./credit
80 | Number: 6176292929
81 | INVALID
82 | ```
83 |
84 | Test out your program with a whole bunch of inputs, both valid and invalid. (We certainly will!) Here are a
85 | [few card numbers](https://developer.paypal.com/docs/classic/payflow/payflow-pro/payflow-pro-testing/#credit-card-numbers-for-testing) that PayPal recommends for testing.
86 |
87 | If your program behaves incorrectly on some inputs (or doesn’t compile at all), time to debug!
88 |
89 | ### How to Test Your Code
90 |
91 | You can also execute the below to evaluate the correctness of your code using `check50`. But be sure to compile and test it yourself as well!
92 |
93 | check50 cs50/problems/2021/x/credit
94 |
95 | Execute the below to evaluate the style of your code using `style50`.
96 |
97 | style50 credit.c
98 |
99 | ## How to Submit
100 |
101 | Execute the below, logging in with your GitHub username and password when prompted. For security, you’ll see asterisks (`*`) instead of the actual characters in your password.
102 |
103 | submit50 cs50/problems/2021/x/credit
104 |
--------------------------------------------------------------------------------
/assignments/week_1/pset1/credit/credit.c:
--------------------------------------------------------------------------------
1 | // Report (via printf) whether it is a valid American Express, MasterCard,
2 | // or Visa card number, per the definitions of each’s format
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | int validate_credit_card(long number);
9 | int get_first_two_digits(long number);
10 | int get_length(long number);
11 | void print_credit_card_type(long number);
12 |
13 | int main(void)
14 | {
15 | long credit_card_number = get_long("Number: ");
16 | print_credit_card_type(credit_card_number);
17 | }
18 |
19 | // https://en.wikipedia.org/wiki/Luhn_algorithm
20 | // Determine if a credit card number is (syntactically) valid as follows:
21 | // 1. Multiply every other digit by 2, starting with the number’s second-to-last digit,
22 | // and then add those products’ digits together.
23 | // 2. Add the sum to the sum of the digits that weren’t multiplied by 2.
24 | // 3. If the total’s last digit is 0 (or, put more formally, if the total modulo 10 is congruent to 0),
25 | // the number is valid!
26 | int validate_credit_card(long number)
27 | {
28 | long tmp = number;
29 | int sum = 0;
30 |
31 | while (tmp > 0)
32 | {
33 | // Retrieve and add the rightmost digit to the sum the digits
34 | // that weren't multiplied by 2
35 | sum += tmp % 10;
36 | // Remove the rightmost digit
37 | tmp /= 10;
38 | int mul_digit = (tmp % 10) * 2;
39 | // If the result of the multiplied number is two digits
40 | // sum the number's digits (i.e. 13 become 4)
41 | sum += mul_digit >= 10 ? (mul_digit % 10) + (mul_digit / 10) : mul_digit;
42 | // Remove the rightmost digit
43 | tmp /= 10;
44 | }
45 |
46 | return sum % 10;
47 | }
48 |
49 | // Returns the first-two digits of the number (i.e. 4589 -> 45)
50 | int get_first_two_digits(long number)
51 | {
52 | long tmp = number;
53 | // Reduces the number to the first-two digits
54 | while (tmp >= 100)
55 | {
56 | // Remove the rightmost digit
57 | tmp /= 10;
58 | }
59 |
60 | return tmp;
61 | }
62 |
63 | // Returns the length of the number (i.e. 14568 -> 5)
64 | int get_length(long number)
65 | {
66 | return log10(number) + 1;
67 | }
68 |
69 | // Print the credit card type according to the following format definitions:
70 | // American Express uses 15-digit numbers, all American Express numbers start with 34 or 37;
71 | // MasterCard uses 16-digit numbers, most MasterCard numbers start with 51, 52, 53, 54, or 55
72 | // Visa uses 13- and 16-digit numbers, all Visa numbers start with 4
73 | // Note: MasterCard also have some other potential starting numbers
74 | // which we won’t concern ourselves with for this problem
75 | void print_credit_card_type(long number)
76 | {
77 | int is_valid = validate_credit_card(number);
78 | int start_number = get_first_two_digits(number);
79 | int len_number = get_length(number);
80 |
81 | // Check if the credit card number is (syntactically) valid,
82 | // if so, determine credit card type
83 | if (!is_valid && len_number == 15 && (start_number == 34 || start_number == 37))
84 | {
85 | printf("AMEX\n");
86 | }
87 | else if (!is_valid && len_number == 16 && (start_number >= 51 && start_number <= 55))
88 | {
89 | printf("MASTERCARD\n");
90 | }
91 | else if (!is_valid && (len_number == 13 || len_number == 16) && (start_number >= 40 && start_number < 50))
92 | {
93 | printf("VISA\n");
94 | }
95 | else
96 | {
97 | printf("INVALID\n");
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/assignments/week_1/pset1/mario/less/README.md:
--------------------------------------------------------------------------------
1 | # Mario
2 |
3 | ## World 1-1
4 |
5 | Toward the end of World 1-1 in Nintendo’s Super Mario Brothers, Mario must ascend right-aligned pyramid of blocks, a la the below.
6 |
7 | 
8 |
9 | Let’s recreate that pyramid in C, albeit in text, using hashes (`#`) for bricks, a la the below. Each hash is a bit taller than it is wide, so the pyramid itself is also be
10 | taller than it is wide.
11 |
12 | ```
13 | #
14 | ##
15 | ###
16 | ####
17 | #####
18 | ######
19 | #######
20 | ########
21 | ```
22 |
23 | The program we’ll write will be called `mario`. And let’s allow the user to decide just how tall the pyramid should be by first prompting them for a positive integer between,
24 | say, 1 and 8, inclusive.
25 |
26 | Here’s how the program might work if the user inputs `8` when prompted:
27 |
28 | ```
29 | $ ./mario
30 | Height: 8
31 | #
32 | ##
33 | ###
34 | ####
35 | #####
36 | ######
37 | #######
38 | ########
39 | ```
40 |
41 | Here’s how the program might work if the user inputs `4` when prompted:
42 |
43 | ```
44 | $ ./mario
45 | Height: 4
46 | #
47 | ##
48 | ###
49 | ####
50 | ```
51 |
52 | Here’s how the program might work if the user inputs `2` when prompted:
53 |
54 | ```
55 | $ ./mario
56 | Height: 2
57 | #
58 | ##
59 | ```
60 |
61 | And here’s how the program might work if the user inputs `1` when prompted:
62 |
63 | ```
64 | $ ./mario
65 | Height: 1
66 | #
67 | ```
68 |
69 | If the user doesn’t, in fact, input a positive integer between 1 and 8, inclusive, when prompted, the program should re-prompt the user until they cooperate:
70 |
71 | ```
72 | $ ./mario
73 | Height: -1
74 | Height: 0
75 | Height: 42
76 | Height: 50
77 | Height: 4
78 | #
79 | ##
80 | ###
81 | ####
82 | ```
83 |
84 | How to begin? Let’s approach this problem one step at a time.
85 |
86 | ## Pseudocode
87 |
88 | First, create a new directory (i.e., folder) called `mario` inside of your `pset1` directory, by executing
89 |
90 | ~/ $ mkdir ~/pset1/mario
91 |
92 | Add a new file called `pseudocode.txt` inside of your `mario` directory.
93 |
94 | Write in `pseudocode.txt` some pseudocode that implements this program, even if not (yet!) sure how to write it in code. There’s no one right way to write pseudocode, but short
95 | English sentences suffice. Recall how we wrote pseudocode for
96 | [finding Mike Smith](https://docs.google.com/presentation/d/17wRd8ksO6QkUq906SUgm17AqcI-Jan42jkY-EmufxnE/edit?usp=sharing). Odds are your pseudocode will use (or imply using!)
97 | one or more functions, conditions, Boolean expressions, loops, and/or variables.
98 |
99 |
100 | Spoiler
101 |
102 |
103 |
104 | There’s more than one way to do this, so here’s just one!
105 |
106 | 1. Prompt user for height
107 | 2. If height is less than 1 or greater than 8 (or not an integer at all), go back one step
108 | 3. Iterate from 1 through height:
109 | 1. On iteration *i*, print *i* hashes and then a newline
110 |
111 | It’s okay to edit your own after seeing this pseudocode here, but don’t simply copy/paste ours into your own!
112 |
113 |
114 |
115 | ## Prompting for Input
116 |
117 | Whatever your pseudocode, let’s first write only the C code that prompts (and re-prompts, as needed) the user for input. Create a new file called `mario.c` inside of your
118 | `mario` directory.
119 |
120 | Now, modify `mario.c` in such a way that it prompts the user for the pyramid’s height, storing their input in a variable, re-prompting the user again and again as needed if
121 | their input is not a positive integer between 1 and 8, inclusive. Then, simply print the value of that variable, thereby confirming (for yourself) that you’ve indeed stored the
122 | user’s input successfully, a la the below.
123 |
124 | ```
125 | $ ./mario
126 | Height: -1
127 | Height: 0
128 | Height: 42
129 | Height: 50
130 | Height: 4
131 | Stored: 4
132 | ```
133 |
134 |
135 | Hints
136 |
137 |
138 |
139 | - Recall that you can compile your program with `make`.
140 | - Recall that you can print an `int` with `printf` using `%i`.
141 | - Recall that you can get an integer from the user with `get_int`.
142 | - Recall that `get_int` is declared in `cs50.h`.
143 | - Recall that we prompted the user for a positive integer in class via `positive.c`.
144 |
145 |
146 |
147 | ## Building the Opposite
148 |
149 | Now that your program is (hopefully!) accepting input as prescribed, it’s time for another step.
150 |
151 | It turns out it’s a bit easier to build a left-aligned pyramid than right-, a la the below.
152 |
153 | ```
154 | #
155 | ##
156 | ###
157 | ####
158 | #####
159 | ######
160 | #######
161 | ########
162 | ```
163 |
164 | So let’s build a left-aligned pyramid first and then, once that’s working, right-align it instead!
165 |
166 | Modify `mario.c` at right such that it no longer simply prints the user’s input but instead prints a left-aligned pyramid of that height.
167 |
168 |
169 | Hints
170 |
171 | - Keep in mind that a hash is just a character like any other, so you can print it with `printf`.
172 | - Just as Scratch has a [Repeat](https://docs.google.com/presentation/d/17wRd8ksO6QkUq906SUgm17AqcI-Jan42jkY-EmufxnE/edit?usp=sharing) block, so does C have a
173 | [`for`](https://docs.google.com/presentation/d/191XW0DHWlW6WmAhYuFUYnZKUlDx0N4u4Fp81AeW-uNs/edit?usp=sharing) loop, via which you can iterate some number times.
174 | Perhaps on each iteration, *i*, you could print that many hashes?
175 | - You can actually “nest” loops, iterating with one variable (e.g., `i`) in the “outer” loop and another (e.g., `j`) in the “inner” loop. For instance, here’s how you might
176 | print a square of height and width `n`, below. Of course, it’s not a square that you want to print!
177 |
178 | ```c
179 | for (int i = 0; i < n; i++)
180 | {
181 | for (int j = 0; j < n; j++)
182 | {
183 | printf("#");
184 | }
185 | printf("\n");
186 | }
187 | ```
188 |
189 |
190 |
191 | ## Right-Aligning with Dots
192 |
193 | Let’s now right-align that pyramid by pushing its hashes to the right by prefixing them with dots (i.e., periods), a la the below.
194 |
195 | ```
196 | .......#
197 | ......##
198 | .....###
199 | ....####
200 | ...#####
201 | ..######
202 | .#######
203 | ########
204 | ```
205 |
206 | Modify `mario.c` in such a way that it does exactly that!
207 |
208 |
209 | Hint
210 |
211 |
212 |
213 | Notice how the number of dots needed on each line is the “opposite” of the number of that line’s hashes. For a pyramid of height 8, like the above, the first line has but 1
214 | hash and thus 7 dots. The bottom line, meanwhile, has 8 hashes and thus 0 dots. Via what formula (or arithmetic, really) could you print that many dots?
215 |
216 |
217 |
218 | ### How to Test Your Code
219 |
220 | Does your code work as prescribed when you input
221 |
222 | - `-1` (or other negative numbers)?
223 | - `0`?
224 | - `1` through `8`?
225 | - `9` or other positive numbers?
226 | - letters or words?
227 | - no input at all, when you only hit Enter?
228 |
229 | ## Removing the Dots
230 |
231 | All that remains now is a finishing flourish! Modify `mario.c` in such a way that it prints spaces instead of those dots!
232 |
233 | ### How to Test Your Code
234 |
235 | Execute the below to evaluate the correctness of your code using `check50`. But be sure to compile and test it yourself as well!
236 |
237 | check50 cs50/problems/2021/x/mario/less
238 |
239 | Execute the below to evaluate the style of your code using `style50`.
240 |
241 | style50 mario.c
242 |
243 |
244 | Hint
245 |
246 |
247 |
248 | A space is just a press of your space bar, just as a period is just a press of its key! Just remember that `printf` requires that you surround both with double quotes!
249 |
250 |
251 |
252 | ## How to Submit
253 |
254 | Execute the below, logging in with your GitHub username and password when prompted. For security, you’ll see asterisks (`*`) instead of the actual characters in your password.
255 |
256 | submit50 cs50/problems/2021/x/mario/less
257 |
--------------------------------------------------------------------------------
/assignments/week_1/pset1/mario/less/mario.c:
--------------------------------------------------------------------------------
1 | // Print a right-aligned pyramid of hashes
2 |
3 | #include
4 | #include
5 |
6 | int get_height(string prompt);
7 | void print_pyramid(int height);
8 |
9 | int main(void)
10 | {
11 | int height = get_height("Height: ");
12 | print_pyramid(height);
13 | }
14 |
15 | // Prompt user for positive integer between 1 and 8
16 | int get_height(string prompt)
17 | {
18 | int n;
19 | do
20 | {
21 | n = get_int("%s", prompt);
22 | }
23 | while (n < 1 || n > 8);
24 |
25 | return n;
26 | }
27 |
28 | // Print a right-aligned pyramid of hashes of height 'height'
29 | void print_pyramid(int height)
30 | {
31 | // Print n rows
32 | for (int i = 0; i < height; i++)
33 | {
34 | // Formatting for right-alignment
35 | for (int j = 0; j < height - i - 1; j++)
36 | {
37 | printf("%s", " ");
38 | }
39 |
40 | // Print k hashes on each row
41 | for (int k = 0; k <= i; k++)
42 | {
43 | printf("%s", "#");
44 | }
45 |
46 | printf("%s", "\n");
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/assignments/week_1/pset1/mario/more/README.md:
--------------------------------------------------------------------------------
1 | # Mario
2 |
3 | ## World 1-1
4 |
5 | Toward the beginning of World 1-1 in Nintendo’s Super Mario Brothers, Mario must hop over adjacent pyramids of blocks, per the below.
6 |
7 | 
8 |
9 | Let’s recreate those pyramids in C, albeit in text, using hashes (`#`) for bricks, a la the below. Each hash is a bit taller than it is wide, so the pyramids themselves are
10 | also be taller than they are wide.
11 |
12 | ```
13 | # #
14 | ## ##
15 | ### ###
16 | #### ####
17 | ```
18 |
19 | The program we’ll write will be called `mario`. And let’s allow the user to decide just how tall the pyramids should be by first prompting them for a positive integer between,
20 | say, 1 and 8, inclusive.
21 |
22 | Here’s how the program might work if the user inputs `8` when prompted:
23 |
24 | ```
25 | $ ./mario
26 | Height: 8
27 | # #
28 | ## ##
29 | ### ###
30 | #### ####
31 | ##### #####
32 | ###### ######
33 | ####### #######
34 | ######## ########
35 | ```
36 |
37 | Here’s how the program might work if the user inputs `4` when prompted:
38 |
39 | ```
40 | $ ./mario
41 | Height: 4
42 | # #
43 | ## ##
44 | ### ###
45 | #### ####
46 | ```
47 |
48 | Here’s how the program might work if the user inputs `2` when prompted:
49 |
50 | ```
51 | $ ./mario
52 | Height: 2
53 | # #
54 | ## ##
55 | ```
56 |
57 | And here’s how the program might work if the user inputs `1` when prompted:
58 |
59 | ```
60 | $ ./mario
61 | Height: 1
62 | # #
63 | ```
64 |
65 | If the user doesn’t, in fact, input a positive integer between 1 and 8, inclusive, when prompted, the program should re-prompt the user until they cooperate:
66 |
67 | ```
68 | $ ./mario
69 | Height: -1
70 | Height: 0
71 | Height: 42
72 | Height: 50
73 | Height: 4
74 | # #
75 | ## ##
76 | ### ###
77 | #### ####
78 | ```
79 |
80 | Notice that width of the “gap” between adjacent pyramids is equal to the width of two hashes, irrespective of the pyramids’ heights.
81 |
82 | Create a new directory (i.e., folder) called `mario` inside of your `pset1` directory, by executing
83 |
84 | ~/ $ mkdir ~/pset1/mario
85 |
86 | Create a new file called `mario.c` inside your `mario` directory. Modify `mario.c` in such a way that it implements this program as described!
87 |
88 | ### How to Test Your Code
89 |
90 | Does your code work as prescribed when you input
91 |
92 | - `-1` (or other negative numbers)?
93 | - `0`?
94 | - `1` through `8`?
95 | - `9` or other positive numbers?
96 | - letters or words?
97 | - no input at all, when you only hit Enter?
98 |
99 | You can also execute the below to evaluate the correctness of your code using `check50`. But be sure to compile and test it yourself as well!
100 |
101 | check50 cs50/problems/2021/x/mario/more
102 |
103 | Execute the below to evaluate the style of your code using `style50`.
104 |
105 | style50 mario.c
106 |
107 | ## How to Submit
108 |
109 | Execute the below, logging in with your GitHub username and password when prompted. For security, you’ll see asterisks (`*`) instead of the actual characters in your password.
110 |
111 | submit50 cs50/problems/2021/x/mario/more
112 |
--------------------------------------------------------------------------------
/assignments/week_1/pset1/mario/more/mario.c:
--------------------------------------------------------------------------------
1 | // Print an adjacent pyramids of hashes separated by a "gap"
2 |
3 | #include
4 | #include
5 |
6 | int get_height(string prompt);
7 | void print_pyramids(int height);
8 |
9 | int main(void)
10 | {
11 | int height = get_height("Height: ");
12 | print_pyramids(height);
13 | }
14 |
15 | // Prompt user for a positive integer between 1 and 8
16 | int get_height(string prompt)
17 | {
18 | int n;
19 | do
20 | {
21 | n = get_int("%s", prompt);
22 | }
23 | while (n < 1 || n > 8);
24 |
25 | return n;
26 | }
27 |
28 | // Print an adjacent pyramids of hashes of height 'height' separated by a "gap"
29 | void print_pyramids(int height)
30 | {
31 | // Print n rows
32 | for (int i = 0; i < height; i++)
33 | {
34 | // Formatting for right-alignment
35 | for (int j = 0; j < height - i - 1; j++)
36 | {
37 | printf("%s", " ");
38 | }
39 |
40 | // Print k hashes on each row of the first pyramid
41 | for (int k = 0; k <= i; k++)
42 | {
43 | printf("%s", "#");
44 | }
45 |
46 | // Print a “gap” between adjacent pyramids equal to the width of two hashes
47 | printf("%s", " ");
48 |
49 | // Print k hashes on each row of the second pyramid
50 | for (int k = 0; k <= i; k++)
51 | {
52 | printf("%s", "#");
53 | }
54 |
55 | printf("%s", "\n");
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/assignments/week_2/lab_2/scrabble/README.md:
--------------------------------------------------------------------------------
1 | # Lab 2: Scrabble
2 |
3 | Determine which of two Scrabble words is worth more.
4 |
5 | ```
6 | $ ./scrabble
7 | Player 1: COMPUTER
8 | Player 2: science
9 | Player 1 wins!
10 | ```
11 |
12 | ## Background
13 |
14 | In the game of [Scrabble](https://scrabble.hasbro.com/en-us/rules), players create words to score points, and the number of points is the sum of the point values of each letter
15 | in the word.
16 |
17 | ```
18 | A 1
19 | B 3
20 | C 3
21 | D 2
22 | E 1
23 | F 4
24 | G 2
25 | H 4
26 | I 1
27 | J 8
28 | K 5
29 | L 1
30 | M 3
31 | N 1
32 | O 1
33 | P 3
34 | Q 10
35 | R 1
36 | S 1
37 | T 1
38 | U 1
39 | V 4
40 | W 4
41 | X 8
42 | Y 4
43 | Z 10
44 | ```
45 |
46 | For example, if we wanted to score the word `Code`, we would note that in general Scrabble rules, the `C` is worth `3` points, the `o` is worth `1` point, the `d` is worth `2`
47 | points, and the `e` is worth `1` point. Summing these, we get that `Code` is worth `3 + 1 + 2 + 1 = 7` points.
48 |
49 | ## Getting Started
50 |
51 | - Copy the “distribution code” (i.e., starter code) from [cdn.cs50.net/2020/fall/labs/2/scrabble.c](https://cdn.cs50.net/2020/fall/labs/2/scrabble.c) into a new file in your
52 | IDE called `scrabble.c`.
53 | - You can also download the distribution code by running the command `wget https://cdn.cs50.net/2020/fall/labs/2/scrabble.c` in CS50 IDE.
54 |
55 | ## Implementation Details
56 |
57 | Complete the implementation of `scrabble.c`, such that it determines the winner of a short scrabble-like game, where two players each enter their word, and the higher scoring
58 | player wins.
59 |
60 | - Notice that we’ve stored the point values of each letter of the alphabet in an integer array named `POINTS`.
61 | - For example, `A` or `a` is worth 1 point (represented by `POINTS[0]`), `B` or `b` is worth 3 points (represented by `POINTS[1]`), etc.
62 | - Notice that we’ve created a prototype for a helper function called `compute_score()` that takes a string as input and returns an `int`. Whenever we would like to assign point
63 | values to a particular word, we can call this function. Note that this prototype is required for C to know that `compute_score()` exists later in the program.
64 | - In `main()`, the program prompts the two players for their words using the `get_string()` function. These values are stored inside variables named `word1` and `word2`.
65 | - In `compute_score()`, your program should compute, using the `POINTS` array, and return the score for the string argument. Characters that are not letters should be given
66 | zero points, and uppercase and lowercase letters should be given the same point values.
67 | - For example, `!` is worth `0` points while `A` and `a` are both worth `1` point.
68 | - Though Scrabble rules normally require that a word be in the dictionary, no need to check for that in this problem!
69 | - In `main()`, your program should print, depending on the players’ scores, `Player 1 wins!`, `Player 2 wins!`, or `Tie!`.
70 |
71 | ### Hints
72 |
73 | - You may find the functions `isupper()` and `islower()` to be helpful to you. These functions take in a character as the argument and return a nonzero value if the character
74 | is uppercase (for `isupper`) or lowercase (for `islower`).
75 | - To find the value at the `n`th index of an array called `arr`, we can write `arr[n]`. We can apply this to strings as well, as strings are arrays of characters.
76 | - Recall that computers represent characters using [ASCII](http://asciitable.com/), a standard that represents each character as a number.
77 |
78 | ### How to Test Your Code
79 |
80 | Your program should behave per the examples below.
81 |
82 | ```
83 | $ ./scrabble
84 | Player 1: Question?
85 | Player 2: Question!
86 | Tie!
87 | ```
88 |
89 | ```
90 | $ ./scrabble
91 | Player 1: Oh,
92 | Player 2: hai!
93 | Player 2 wins!
94 | ```
95 |
96 | ```
97 | $ ./scrabble
98 | Player 1: COMPUTER
99 | Player 2: science
100 | Player 1 wins!
101 | ```
102 |
103 | ```
104 | $ ./scrabble
105 | Player 1: Scrabble
106 | Player 2: wiNNeR
107 | Player 1 wins!
108 | ```
109 |
110 | Execute the below to evaluate the correctness of your code using `check50`. But be sure to compile and test it yourself as well!
111 |
112 | check50 cs50/labs/2021/x/scrabble
113 |
114 | Execute the below to evaluate the style of your code using `style50`.
115 |
116 | style50 scrabble.c
117 |
118 | ## How to Submit
119 |
120 | Execute the below, logging in with your GitHub username and password when prompted. For security, you’ll see asterisks (`*`) instead of the actual characters in your password.
121 |
122 | submit50 cs50/labs/2021/x/scrabble
123 |
--------------------------------------------------------------------------------
/assignments/week_2/pset2/caesar/README.md:
--------------------------------------------------------------------------------
1 | # Caesar
2 |
3 | Implement a program that encrypts messages using Caesar’s cipher, per the below.
4 |
5 | ```
6 | $ ./caesar 13
7 | plaintext: HELLO
8 | ciphertext: URYYB
9 | ```
10 |
11 | ## Background
12 |
13 | Supposedly, Caesar (yes, that Caesar) used to “encrypt” (i.e., conceal in a reversible way) confidential messages by shifting each letter therein by some number of places. For
14 | instance, he might write A as B, B as C, C as D, …, and, wrapping around alphabetically, Z as A. And so, to say HELLO to someone, Caesar might write IFMMP. Upon receiving such
15 | messages from Caesar, recipients would have to “decrypt” them by shifting letters in the opposite direction by the same number of places.
16 |
17 | The secrecy of this “cryptosystem” relied on only Caesar and the recipients knowing a secret, the number of places by which Caesar had shifted his letters (e.g., 1). Not
18 | particularly secure by modern standards, but, hey, if you’re perhaps the first in the world to do it, pretty secure!
19 |
20 | Unencrypted text is generally called *plaintext*. Encrypted text is generally called *ciphertext*. And the secret used is called a *key*.
21 |
22 | To be clear, then, here’s how encrypting `HELLO` with a key of 1 yields `IFMMP`:
23 |
24 | | plaintext | H | E | L | L | O |
25 | |:-------------|---|---|---|---|---|
26 | | + key | 1 | 1 | 1 | 1 | 1 |
27 | | = ciphertext | I | F | M | M | P |
28 |
29 | More formally, Caesar’s algorithm (i.e., cipher) encrypts messages by “rotating” each letter by *k* positions. More formally, if *p* is some plaintext (i.e., an unencrypted
30 | message), *p*i is the *i*th character in *p*, and *k* is a secret key (i.e., a non-negative integer), then each letter, *c*i, in the
31 | ciphertext, *c*, is computed as
32 |
33 | ci = (pi + k) % 26
34 |
35 | wherein `% 26` here means “remainder when dividing by 26.” This formula perhaps makes the cipher seem more complicated than it is, but it’s really just a concise way of
36 | expressing the algorithm precisely. Indeed, for the sake of discussion, think of A (or a) as 0, B (or b) as 1, …, H (or h) as 7, I (or i) as 8, …, and Z (or z) as 25.
37 | Suppose that Caesar just wants to say Hi to someone confidentially using, this time, a key, *k*, of 3. And so his plaintext, *p*, is Hi, in which case his plaintext’s first
38 | character, *p*0, is H (aka 7), and his plaintext’s second character, *p*1, is i (aka 8). His ciphertext’s first character, *c*0, is thus K, and
39 | his ciphertext’s second character, *c*1, is thus L. Can you see why?
40 |
41 | Let’s write a program called `caesar` that enables you to encrypt messages using Caesar’s cipher. At the time the user executes the program, they should decide, by providing a
42 | command-line argument, on what the key should be in the secret message they’ll provide at runtime. We shouldn’t necessarily assume that the user’s key is going to be a number;
43 | though you may assume that, if it is a number, it will be a positive integer.
44 |
45 | Here are a few examples of how the program might work. For example, if the user inputs a key of `1` and a plaintext of `HELLO`:
46 |
47 | ```
48 | $ ./caesar 1
49 | plaintext: HELLO
50 | ciphertext: IFMMP
51 | ```
52 |
53 | Here’s how the program might work if the user provides a key of `13` and a plaintext of `hello, world`:
54 |
55 | ```
56 | $ ./caesar 13
57 | plaintext: hello, world
58 | ciphertext: uryyb, jbeyq
59 | ```
60 |
61 | Notice that neither the comma nor the space were “shifted” by the cipher. Only rotate alphabetical characters!
62 |
63 | How about one more? Here’s how the program might work if the user provides a key of `13` again, with a more complex plaintext:
64 |
65 | ```
66 | $ ./caesar 13
67 | plaintext: be sure to drink your Ovaltine
68 | ciphertext: or fher gb qevax lbhe Binygvar
69 | ```
70 |
71 | Notice that the case of the original message has been preserved. Lowercase letters remain lowercase, and uppercase letters remain uppercase.
72 |
73 | And what if a user doesn’t cooperate?
74 |
75 | ```
76 | $ ./caesar HELLO
77 | Usage: ./caesar key
78 | ```
79 |
80 | Or really doesn’t cooperate?
81 |
82 | ```
83 | $ ./caesar
84 | Usage: ./caesar key
85 | ```
86 |
87 | Or even…
88 |
89 | ```
90 | $ ./caesar 1 2 3
91 | Usage: ./caesar key
92 | ```
93 |
94 |
95 | Try It
96 |
97 |
98 |
99 | To try out the staff’s implementation of this problem, execute
100 |
101 | ```
102 | ./caesar key
103 | ```
104 |
105 | substituting a valid integer in place of `key`, within [this sandbox](http://bit.ly/2Vwi8n0).
106 |
107 |
108 |
109 | ## Specification
110 |
111 | Design and implement a program, `caesar`, that encrypts messages using Caesar’s cipher.
112 |
113 | - Implement your program in a file called `caesar.c` in a directory called `caesar`.
114 | - Your program must accept a single command-line argument, a non-negative integer. Let’s call it *k* for the sake of discussion.
115 | - If your program is executed without any command-line arguments or with more than one command-line argument, your program should print an error message of your choice (with
116 | `printf`) and return from `main` a value of `1` (which tends to signify an error) immediately.
117 | - If any of the characters of the command-line argument is not a decimal digit, your program should print the message `Usage: ./caesar key` and return from `main` a value of
118 | `1`.
119 | - Do not assume that *k* will be less than or equal to 26. Your program should work for all non-negative integral values of *k* less than 2^31 - 26. In other words, you don’t
120 | need to worry if your program eventually breaks if the user chooses a value for *k* that’s too big or almost too big to fit in an `int`. (Recall that an `int` can overflow.)
121 | But, even if *k* is greater than 26, alphabetical characters in your program’s input should remain alphabetical characters in your program’s output. For instance, if *k* is
122 | 27, `A` should not become `[` even though `[` is 27 positions away from `A` in ASCII, per http://www.asciichart.com/[asciichart.com]; `A` should become `B`, since `B` is 27
123 | positions away from `A`, provided you wrap around from `Z` to `A`.
124 | - Your program must output `plaintext:` (without a newline) and then prompt the user for a `string` of plaintext (using `get_string`).
125 | - Your program must output `ciphertext:` (without a newline) followed by the plaintext’s corresponding ciphertext, with each alphabetical character in the plaintext “rotated”
126 | by *k* positions; non-alphabetical characters should be outputted unchanged.
127 | - Your program must preserve case: capitalized letters, though rotated, must remain capitalized letters; lowercase letters, though rotated, must remain lowercase letters.
128 | - After outputting ciphertext, you should print a newline. Your program should then exit by returning `0` from `main`.
129 |
130 | How to begin? Let’s approach this problem one step at a time.
131 |
132 | ### Pseudocode
133 |
134 | First, write some pseudocode that implements this program, even if not (yet!) sure how to write it in code. There’s no one right way to write pseudocode, but short English
135 | sentences suffice. Recall how we wrote pseudocode for [finding Mike Smith](https://cdn.cs50.net/2018/fall/lectures/0/lecture0.pdf). Odds are your pseudocode will use (or imply
136 | using!) one or more functions, conditions, Boolean expressions, loops, and/or variables.
137 |
138 |
139 | Spoiler
140 |
141 |
142 |
143 | There’s more than one way to do this, so here’s just one!
144 |
145 | 1. Check that program was run with one command-line argument
146 | 2. Iterate over the provided argument to make sure all characters are digits
147 | 3. Convert that command-line argument from a `string` to an `int`
148 | 4. Prompt user for plaintext
149 | 5. Iterate over each character of the plaintext:
150 | 1. If it is an uppercase letter, rotate it, preserving case, then print out the rotated character
151 | 2. If it is a lowercase letter, rotate it, preserving case, then print out the rotated character
152 | 3. If it is neither, print out the character as is
153 | 6. Print a newline
154 |
155 | It’s okay to edit your own after seeing this pseudocode here, but don’t simply copy/paste ours into your own!
156 |
157 |
158 |
159 | ### Counting Command-Line Arguments
160 |
161 | Whatever your pseudocode, let’s first write only the C code that checks whether the program was run with a single command-line argument before adding additional functionality.
162 |
163 | Specifically, modify `caesar.c` in such a way that: if the user provides exactly one command-line argument, it prints `Success`; if the user provides no command-line arguments,
164 | or two or more, it prints `Usage: ./caesar key`. Remember, since this key is coming from the command line at runtime, and not via `get_string`, we don’t have an opportunity to
165 | re-prompt the user. The behavior of the resulting program should be like the below.
166 |
167 | ```
168 | $ ./caesar 20
169 | Success
170 | ```
171 |
172 | or
173 |
174 | ```
175 | $ ./caesar
176 | Usage: ./caesar key
177 | ```
178 |
179 | or
180 |
181 | ```
182 | $ ./caesar 1 2 3
183 | Usage: ./caesar key
184 | ```
185 |
186 |
187 | Hints
188 |
189 |
190 |
191 | - Recall that you can compile your program with `make`.
192 | - Recall that you can print with `printf`.
193 | - Recall that `argc` and `argv` give you information about what was provided at the command line.
194 | - Recall that the name of the program itself (here, `./caesar`) is in `argv[0]`.
195 |
196 |
197 |
198 | ### Accessing the Key
199 |
200 | Now that your program is (hopefully!) accepting input as prescribed, it’s time for another step.
201 |
202 | Recall that in our program, we must defend against users who technically provide a single command-line argument (the key), but provide something that isn’t actually an
203 | integer, for example:
204 |
205 | $ ./caesar xyz
206 |
207 | Before we start to analyze the key for validity, though, let’s make sure we can actually read it. Further modify `caesar.c` such that it not only checks that the user has
208 | provided just one command-line argument, but after verifying that, prints out that single command-line argument. So, for example, the behavior might look like this:
209 |
210 | ```
211 | $ ./caesar 20
212 | Success
213 | 20
214 | ```
215 |
216 |
217 | Hints
218 |
219 |
220 |
221 | - Recall that `argc` and `argv` give you information about what was provided at the command line.
222 | - Recall that `argv` is an array of strings.
223 | - Recall that with `printf` we can print a string using `%s` as the placeholder.
224 | - Recall that computer scientists like counting starting from 0.
225 | - Recall that we can access individual elements of an array, such as `argv` using square brackets, for example: `argv[0]`.
226 |
227 |
228 |
229 | ### Validating the Key
230 |
231 | Now that you know how to read the key, let’s analyze it. Modify `caesar.c` such that instead of printing out the command-line argument provided, your program instead checks to
232 | make sure that each character of that command line argument is a decimal digit (i.e., `0`, `1`, `2`, etc.) and, if any of them are not, terminates after printing the message
233 | `Usage: ./caesar key`. But if the argument consists solely of digit characters, you should convert that string (recall that `argv` is an array of strings, even if those
234 | strings happen to look like numbers) to an actual integer, and print out the *integer*, as via `%i` with `printf`. So, for example, the behavior might look like this:
235 |
236 | ```
237 | $ ./caesar 20
238 | Success
239 | 20
240 | ```
241 |
242 | or
243 |
244 | ```
245 | $ ./caesar 20x
246 | Usage: ./caesar key
247 | ```
248 |
249 |
250 | Hints
251 |
252 |
253 |
254 | - Recall that `argv` is an array of strings.
255 | - Recall that a string, meanwhile, is just an array of `char`s.
256 | - Recall that the `string.h` header file contains a number of useful functions that work with strings.
257 | - Recall that we can use a loop to iterate over each character of a string if we know its length.
258 | - Recall that the `ctype.h` header file contains a number of useful functions that tell us things about characters.
259 | - Recall that we can `return` nonzero values from `main` to indicate that our program did not finish successfully.
260 | - Recall that with `printf` we can print an integer using `%i` as the placeholder.
261 | - Recall that the `atoi` function converts a string that looks like a number into that number.
262 |
263 |
264 |
265 | ### Peeking Underneath the Hood
266 |
267 | As human beings it’s easy for us to intuitively understand the formula described above, inasmuch as we can say “H + 1 = I”. But can a computer understand that same logic?
268 | Let’s find out. For now, we’re going to temporarily ignore the key the user provided and instead prompt the user for a secret message and attempt to shift all of its characters
269 | by just 1.
270 |
271 | Extend the functionality of `caesar.c` such that, after validating the key, we prompt the user for a string and then shift all of its characters by 1, printing out the result.
272 | We can also at this point probably remove the line of code we wrote earlier that prints `Success`. All told, this might result in this behavior:
273 |
274 | ```
275 | $ ./caesar 1
276 | plaintext: hello
277 | ciphertext: ifmmp
278 | ```
279 |
280 |
281 | Hints
282 |
283 |
284 |
285 | - Try to iterate over every character in the plaintext and literally add 1 to it, then print it.
286 | - If `c` is a variable of type `char` in C, what happens when you call `printf("%c", c + 1)`?
287 |
288 |
289 |
290 | ### Your Turn
291 |
292 | Now it’s time to tie everything together! Instead of shifting the characters by 1, modify `caesar.c` to instead shift them by the actual key value. And be sure to preserve
293 | case! Uppercase letters should stay uppercase, lowercase letters should stay lowercase, and characters that aren’t alphabetical should remain unchanged.
294 |
295 |
296 | Hints
297 |
298 |
299 |
300 | - Best to use the modulo (i.e., remainder) operator, `%`, to handle wraparound from Z to A! But how?
301 | - Things get weird if we try to wrap `Z` or `z` by 1 using the technique in the previous section.
302 | - Things get weird also if we try to wrap punctuation marks using that technique.
303 | - Recall that ASCII maps all printable characters to numbers.
304 | - Recall that the ASCII value of `A` is 65. The ASCII value of `a`, meanwhile, is 97.
305 | - If you’re not seeing any output at all when you call `printf`, odds are it’s because you’re printing characters outside of the valid ASCII range from 0 to 127.
306 | Try printing characters as numbers (using `%i` instead of `%c`) at first to see what values you’re printing, and make sure you’re only ever trying to print valid
307 | characters!
308 |
309 |
310 |
311 | ## How to Test Your Code
312 |
313 | Execute the below to evaluate the correctness of your code using `check50`. But be sure to compile and test it yourself as well!
314 |
315 | check50 cs50/problems/2021/x/caesar
316 |
317 | Execute the below to evaluate the style of your code using `style50`.
318 |
319 | style50 caesar.c
320 |
321 | ## How to Submit
322 |
323 | Execute the below, logging in with your GitHub username and password when prompted. For security, you’ll see asterisks (`*`) instead of the actual characters in your password.
324 |
325 | submit50 cs50/problems/2021/x/caesar
326 |
--------------------------------------------------------------------------------
/assignments/week_2/pset2/readability/README.md:
--------------------------------------------------------------------------------
1 | # Readability
2 |
3 | Implement a program that computes the approximate grade level needed to comprehend some text, per the below.
4 |
5 | ```
6 | $ ./readability
7 | Text: Congratulations! Today is your day. You're off to Great Places! You're off and away!
8 | Grade 3
9 | ```
10 |
11 | ## Reading Levels
12 |
13 | According to [Scholastic](https://www.scholastic.com/teachers/teaching-tools/collections/guided-reading-book-lists-for-every-level.html), E.B. White’s “Charlotte’s Web” is
14 | between a second and fourth grade reading level, and Lois Lowry’s “The Giver” is between an eighth grade reading level and a twelfth grade reading level. What does it mean,
15 | though, for a book to be at a “fourth grade reading level”?
16 |
17 | Well, in many cases, a human expert might read a book and make a decision on the grade for which they think the book is most appropriate. But you could also imagine an
18 | algorithm attempting to figure out what the reading level of a text is.
19 |
20 | So what sorts of traits are characteristic of higher reading levels? Well, longer words probably correlate with higher reading levels. Likewise, longer sentences probably
21 | correlate with higher reading levels, too. A number of “readability tests” have been developed over the years, to give a formulaic process for computing the reading level of a
22 | text.
23 |
24 | One such readability test is the Coleman-Liau index. The Coleman-Liau index of a text is designed to output what (U.S.) grade level is needed to understand the text. The
25 | formula is:
26 |
27 | index = 0.0588 * L - 0.296 * S - 15.8
28 |
29 | Here, `L` is the average number of letters per 100 words in the text, and `S` is the average number of sentences per 100 words in the text.
30 |
31 | Let’s write a program called `readability` that takes a text and determines its reading level. For example, if user types in a line from Dr. Seuss:
32 |
33 | ```
34 | $ ./readability
35 | Text: Congratulations! Today is your day. You're off to Great Places! You're off and away!
36 | Grade 3
37 | ```
38 |
39 | The text the user inputted has 65 letters, 4 sentences, and 14 words. 65 letters per 14 words is an average of about 464.29 letters per 100 words. And 4 sentences per 14 words
40 | is an average of about 28.57 sentences per 100 words. Plugged into the Coleman-Liau formula, and rounded to the nearest whole number, we get an answer of 3: so this passage is
41 | at a third grade reading level.
42 |
43 | Let’s try another one:
44 |
45 | ```
46 | $ ./readability
47 | Text: Harry Potter was a highly unusual boy in many ways. For one thing, he hated the summer holidays more than any other time of year. For another, he really wanted to do his homework, but was forced to do it in secret, in the dead of the night. And he also happened to be a wizard.
48 | Grade 5
49 | ```
50 |
51 | This text has 214 letters, 4 sentences, and 56 words. That comes out to about 382.14 letters per 100 words, and 7.14 sentences per 100 words. Plugged into the Coleman-Liau
52 | formula, we get a fifth grade reading level.
53 |
54 | As the average number of letters and words per sentence increases, the Coleman-Liau index gives the text a higher reading level. If you were to take this paragraph, for
55 | instance, which has longer words and sentences than either of the prior two examples, the formula would give the text an eleventh grade reading level.
56 |
57 | ```
58 | $ ./readability
59 | Text: As the average number of letters and words per sentence increases, the Coleman-Liau index gives the text a higher reading level. If you were to take this paragraph, for instance, which has longer words and sentences than either of the prior two examples, the formula would give the text an eleventh grade reading level.
60 | Grade 11
61 | ```
62 |
63 |
64 | Try It
65 |
66 |
67 |
68 | To try out the staff’s implementation of this problem, execute
69 |
70 | ```
71 | ./readability
72 | ```
73 |
74 | within [this sandbox](http://bit.ly/2ulEXkw).
75 |
76 |
77 |
78 | ## Specification
79 |
80 | Design and implement a program, `readability`, that computes the Coleman-Liau index of the text.
81 |
82 | - Implement your program in a file called `readability.c` in a directory called `readability`.
83 | - Your program must prompt the user for a `string` of text (using `get_string`).
84 | - Your program should count the number of letters, words, and sentences in the text. You may assume that a letter is any lowercase character from `a` to `z` or any uppercase
85 | character from `A` to `Z`, any sequence of characters separated by spaces should count as a word, and that any occurrence of a period, exclamation point, or question mark
86 | indicates the end of a sentence.
87 | - Your program should print as output `"Grade X"` where `X` is the grade level computed by the Coleman-Liau formula, rounded to the nearest integer.
88 | - If the resulting index number is 16 or higher (equivalent to or greater than a senior undergraduate reading level), your program should output `"Grade 16+"` instead of giving
89 | the exact index number. If the index number is less than 1, your program should output `"Before Grade 1"`.
90 |
91 | ### Getting User Input
92 |
93 | Let’s first write some C code that just gets some text input from the user, and prints it back out. Specifically, write code in `readability.c` such that when the user runs the
94 | program, they are prompted with `"Text: "` to enter some text.
95 |
96 | The behavior of the resulting program should be like the below.
97 |
98 | ```
99 | $ ./readability
100 | Text: In my younger and more vulnerable years my father gave me some advice that I've been turning over in my mind ever since.
101 | In my younger and more vulnerable years my father gave me some advice that I've been turning over in my mind ever since.
102 | ```
103 |
104 | ### Letters
105 |
106 | Now that you’ve collected input from the user, let’s begin to analyze that input by first counting the number of letters that show up in the text. Modify `readability.c` so
107 | that, instead of printing out the literal text itself, it instead prints out a count of the number of letters in the text.
108 |
109 | The behavior of the resulting program should be like the below.
110 |
111 | ```
112 | $ ./readability
113 | Text: Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, "and what is the use of a book," thought Alice "without pictures or conversation?"
114 | 235 letter(s)
115 | ```
116 |
117 | Letters can be any uppercase or lowercase alphabetic characters, but shouldn’t include any punctuation, digits, or other symbols.
118 |
119 | You can reference [https://man.cs50.io/](https://man.cs50.io/) for standard library functions that may help you here! You may also find that writing a separate function, like
120 | `count_letters`, may be useful to keep your code organized.
121 |
122 | ### Words
123 |
124 | The Coleman-Liau index cares not only about the number of letters, but also the number of words in a sentence. For the purpose of this problem, we’ll consider any sequence of
125 | characters separated by a space to be a word (so a hyphenated word like `"sister-in-law"` should be considered one word, not three).
126 |
127 | Modify `readability.c` so that, in addition to printing out the number of letters in the text, also prints out the number of words in the text.
128 |
129 | You may assume that a sentence will not start or end with a space, and you may assume that a sentence will not have multiple spaces in a row, **notwithstanding Brian’s
130 | walkthrough video, which was recorded before this specification was modified**.
131 |
132 | The behavior of the resulting program should be like the below.
133 |
134 | ```
135 | $ ./readability
136 | Text: It was a bright cold day in April, and the clocks were striking thirteen. Winston Smith, his chin nuzzled into his breast in an effort to escape the vile wind, slipped quickly through the glass doors of Victory Mansions, though not quickly enough to prevent a swirl of gritty dust from entering along with him.
137 | 250 letter(s)
138 | 55 word(s)
139 | ```
140 |
141 | ### Sentences
142 |
143 | The last piece of information that the Coleman-Liau formula cares about, in addition to the number of letters and words, is the number of sentences. Determining the number of
144 | sentences can be surprisingly trickly. You might first imagine that a sentence is just any sequence of characters that ends with a period, but of course sentences could end
145 | with an exclamation point or a question mark as well. But of course, not all periods necessarily mean the sentence is over. For instance, consider the sentence below.
146 |
147 | ```
148 | Mr. and Mrs. Dursley, of number four Privet Drive, were proud to say that they were perfectly normal, thank you very much.
149 | ```
150 |
151 | This is just a single sentence, but there are three periods! For this problem, we’ll ask you to ignore that subtlety: you should consider any sequence of characters that ends
152 | with a `.` or a `!` or a `?` to be a sentence (so for the above “sentence”, you may count that as three sentences). In practice, sentence boundary detection needs to be a
153 | little more intelligent to handle these cases, but we’ll not worry about that for now.
154 |
155 | Modify `readability.c` so that it also now prints out the number of sentences in the text.
156 |
157 | The behavior of the resulting program should be like the below.
158 |
159 | ```
160 | $ ./readability
161 | Text: When he was nearly thirteen, my brother Jem got his arm badly broken at the elbow. When it healed, and Jem's fears of never being able to play football were assuaged, he was seldom self-conscious about his injury. His left arm was somewhat shorter than his right; when he stood or walked, the back of his hand was at right angles to his body, his thumb parallel to his thigh.
162 | 295 letter(s)
163 | 70 word(s)
164 | 3 sentence(s)
165 | ```
166 |
167 | ### Putting it All Together
168 |
169 | Now it’s time to put all the pieces together! Recall that the Coleman-Liau index is computed using the formula:
170 |
171 | index = 0.0588 * L - 0.296 * S - 15.8
172 |
173 | where `L` is the average number of letters per 100 words in the text, and `S` is the average number of sentences per 100 words in the text.
174 |
175 | Modify `readability.c` so that instead of outputting the number of letters, words, and sentences, it instead outputs the grade level as given by the Coleman-Liau index
176 | (e.g. `"Grade 2"` or `"Grade 8"`). Be sure to round the resulting index number to the nearest whole number!
177 |
178 | If the resulting index number is 16 or higher (equivalent to or greater than a senior undergraduate reading level), your program should output `"Grade 16+"` instead of giving
179 | the exact index number. If the index number is less than 1, your program should output `"Before Grade 1"`.
180 |
181 |
182 | Hints
183 |
184 |
185 |
186 | - Recall that `math.h` declares a function called `round` that might be useful here.
187 | - Recall that, when dividing values of type `int` in C, the result will also be an `int`, with any remainder (i.e., digits after the decimal point) discarded. Put another way,
188 | the result will be “truncated.” You might want to cast your one or more values to `float` before performing division when calculating `L` and `S`!
189 |
190 |
191 |
192 | ## How to Test Your Code
193 |
194 | Try running your program on the following texts.
195 |
196 | - `One fish. Two fish. Red fish. Blue fish.` (Before Grade 1)
197 | - `Would you like them here or there? I would not like them here or there. I would not like them anywhere.` (Grade 2)
198 | - `Congratulations! Today is your day. You're off to Great Places! You're off and away!` (Grade 3)
199 | - `Harry Potter was a highly unusual boy in many ways. For one thing, he hated the summer holidays more than any other time of year. For another, he really wanted to do his
200 | homework, but was forced to do it in secret, in the dead of the night. And he also happened to be a wizard.` (Grade 5)
201 | - `In my younger and more vulnerable years my father gave me some advice that I've been turning over in my mind ever since.` (Grade 7)
202 | - `Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading,
203 | but it had no pictures or conversations in it, "and what is the use of a book," thought Alice "without pictures or conversation?"` (Grade 8)
204 | - `When he was nearly thirteen, my brother Jem got his arm badly broken at the elbow. When it healed, and Jem's fears of never being able to play football were assuaged, he was
205 | seldom self-conscious about his injury. His left arm was somewhat shorter than his right; when he stood or walked, the back of his hand was at right angles to his body, his
206 | thumb parallel to his thigh.` (Grade 8)
207 | - `There are more things in Heaven and Earth, Horatio, than are dreamt of in your philosophy.` (Grade 9)
208 | - `It was a bright cold day in April, and the clocks were striking thirteen. Winston Smith, his chin nuzzled into his breast in an effort to escape the vile wind, slipped
209 | quickly through the glass doors of Victory Mansions, though not quickly enough to prevent a swirl of gritty dust from entering along with him.` (Grade 10)
210 | - `A large class of computational problems involve the determination of properties of graphs, digraphs, integers, arrays of integers, finite families of finite sets, boolean
211 | formulas and elements of other countable domains.` (Grade 16+)
212 |
213 | Execute the below to evaluate the correctness of your code using `check50`. But be sure to compile and test it yourself as well!
214 |
215 | check50 cs50/problems/2021/x/readability
216 |
217 | Execute the below to evaluate the style of your code using `style50`.
218 |
219 | style50 readability.c
220 |
221 | ## How to Submit
222 |
223 | Execute the below, logging in with your GitHub username and password when prompted. For security, you’ll see asterisks (`*`) instead of the actual characters in your password.
224 |
225 | submit50 cs50/problems/2021/x/readability
226 |
--------------------------------------------------------------------------------
/assignments/week_2/pset2/substitution/README.md:
--------------------------------------------------------------------------------
1 | # Substitution
2 |
3 | Implement a program that implements a substitution cipher, per the below.
4 |
5 | ```
6 | $ ./substitution JTREKYAVOGDXPSNCUIZLFBMWHQ
7 | plaintext: HELLO
8 | ciphertext: VKXXN
9 | ```
10 |
11 | ## Background
12 |
13 | In a substitution cipher, we “encrypt” (i.e., conceal in a reversible way) a message by replacing every letter with another letter. To do so, we use a *key*: in this case, a
14 | mapping of each of the letters of the alphabet to the letter it should correspond to when we encrypt it. To “decrypt” the message, the receiver of the message would need to
15 | know the key, so that they can reverse the process: translating the encrypt text (generally called *ciphertext*) back into the original message (generally called *plaintext*).
16 |
17 | A key, for example, might be the string `NQXPOMAFTRHLZGECYJIUWSKDVB`. This 26-character key means that `A` (the first letter of the alphabet) should be converted into `N` (the
18 | first character of the key), `B` (the second letter of the alphabet) should be converted into `Q` (the second character of the key), and so forth.
19 |
20 | A message like `HELLO`, then, would be encrypted as `FOLLE`, replacing each of the letters according to the mapping determined by the key.
21 |
22 | Let’s write a program called `substitution` that enables you to encrypt messages using a substitution cipher. At the time the user executes the program, they should decide, by
23 | providing a command-line argument, on what the key should be in the secret message they’ll provide at runtime.
24 |
25 | Here are a few examples of how the program might work. For example, if the user inputs a key of `YTNSHKVEFXRBAUQZCLWDMIPGJO` and a plaintext of `HELLO`:
26 |
27 | ```
28 | $ ./substitution YTNSHKVEFXRBAUQZCLWDMIPGJO
29 | plaintext: HELLO
30 | ciphertext: EHBBQ
31 | ```
32 |
33 | Here’s how the program might work if the user provides a key of `VCHPRZGJNTLSKFBDQWAXEUYMOI` and a plaintext of `hello, world`:
34 |
35 | ```
36 | $ ./substitution VCHPRZGJNTLSKFBDQWAXEUYMOI
37 | plaintext: hello, world
38 | ciphertext: jrssb, ybwsp
39 | ```
40 |
41 | Notice that neither the comma nor the space were substituted by the cipher. Only substitute alphabetical characters! Notice, too, that the case of the original message has been
42 | preserved. Lowercase letters remain lowercase, and uppercase letters remain uppercase.
43 |
44 | Whether the characters in the key itself are uppercase or lowercase doesn’t matter. A key of `VCHPRZGJNTLSKFBDQWAXEUYMOI` is functionally identical to a key of
45 | `vchprzgjntlskfbdqwaxeuymoi` (as is, for that matter, `VcHpRzGjNtLsKfBdQwAxEuYmOi`).
46 |
47 | And what if a user doesn’t provide a valid key?
48 |
49 | ```
50 | $ ./substitution ABC
51 | Key must contain 26 characters.
52 | ```
53 |
54 | Or really doesn’t cooperate?
55 |
56 | ```
57 | $ ./substitution
58 | Usage: ./substitution key
59 | ```
60 |
61 | Or even…
62 |
63 | ```
64 | $ ./substitution 1 2 3
65 | Usage: ./substitution key
66 | ```
67 |
68 |
69 | Try It
70 |
71 |
72 |
73 | To try out the staff’s implementation of this problem, execute
74 |
75 | ```
76 | ./substitution key
77 | ```
78 |
79 | substituting a valid key in place of `key`, within [this sandbox](http://bit.ly/30Gnoru).
80 |
81 |
82 |
83 | ## Specification
84 |
85 | Design and implement a program, `substitution`, that encrypts messages using a substitution cipher.
86 |
87 | - Implement your program in a file called `substitution.c` in a directory called `substitution`.
88 | - Your program must accept a single command-line argument, the key to use for the substitution. The key itself should be case-insensitive, so whether any character in the key
89 | is uppercase or lowercase should not affect the behavior of your program.
90 | - If your program is executed without any command-line arguments or with more than one command-line argument, your program should print an error message of your choice (with
91 | `printf`) and return from `main` a value of `1` (which tends to signify an error) immediately.
92 | - If the key is invalid (as by not containing 26 characters, containing any character that is not an alphabetic character, or not containing each letter exactly once), your
93 | program should print an error message of your choice (with `printf`) and return from `main` a value of `1` immediately.
94 | - Your program must output `plaintext:` (without a newline) and then prompt the user for a `string` of plaintext (using `get_string`).
95 | - Your program must output `ciphertext:` (without a newline) followed by the plaintext’s corresponding ciphertext, with each alphabetical character in the plaintext substituted
96 | for the corresponding character in the ciphertext; non-alphabetical characters should be outputted unchanged.
97 | - Your program must preserve case: capitalized letters must remain capitalized letters; lowercase letters must remain lowercase letters.
98 | - After outputting ciphertext, you should print a newline. Your program should then exit by returning `0` from `main`.
99 |
100 | ## How to Test Your Code
101 |
102 | Execute the below to evaluate the correctness of your code using `check50`. But be sure to compile and test it yourself as well!
103 |
104 | check50 cs50/problems/2021/x/substitution
105 |
106 | Execute the below to evaluate the style of your code using `style50`.
107 |
108 | style50 substitution.c
109 |
110 | ## How to Submit
111 |
112 | Execute the below, logging in with your GitHub username and password when prompted. For security, you’ll see asterisks (`*`) instead of the actual characters in your password.
113 |
114 | submit50 cs50/problems/2021/x/substitution
115 |
--------------------------------------------------------------------------------
/cs50x.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HawksSpawn/cs50-introduction-to-computer-science/eb8d578f10456b7f8ac7491506023af327ff66cc/cs50x.jpeg
--------------------------------------------------------------------------------