Questions? Feel free to head to CS50 on Reddit, CS50 on StackExchange, or the CS50 Facebook group.

Objectives

  • Use algorithms to solve problems.

  • Learn about checksums.

  • See how to manipulate a large piece of data to create meaningful pieces from it.

  • Pages 1 – 7, 9, and 10 of http://www.howstuffworks.com/c.htm.

  • Chapters 1 – 5, 9, and 11 – 17 of Absolute Beginner’s Guide to C.

  • Chapters 1 – 6 of Programming in C.

Academic Honesty

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 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.

The essence of all work that you submit to this course must be your own. Collaboration on problems is not permitted (unless explicitly stated otherwise) except to the extent that you may ask classmates and 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 or writing to others, but you may not view theirs, so long as you and they respect this policy’s other constraints. Collaboration on quizzes and tests is not permitted at all. Collaboration on the final project is permitted to the extent prescribed by its specification.

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 not commit it until you solicit and receive approval in writing from your instructor. If a violation of this policy is suspected and confirmed, your instructor reserves the right to impose local sanctions on top of any disciplinary outcome that may include an unsatisfactory or failing grade for work submitted or for the course itself.

Reasonable

  • Communicating with classmates about problems in English (or some other spoken language).

  • Discussing the course’s material with others in order to understand it better.

  • Helping a classmate identify a bug in his or her code, such as by viewing, compiling, or running his or her code, even on your own computer.

  • Incorporating snippets of code that you find online or elsewhere into your own code, provided that those snippets are not themselves solutions to assigned problems and that you cite the snippets' origins.

  • Reviewing past years' quizzes, tests, and solutions thereto.

  • 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.

  • Sharing snippets of your own solutions to problems online so that others might help you identify and fix a bug or other issue.

  • 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 problems or your own final project.

  • Whiteboarding solutions to problems with others using diagrams or pseudocode but not actual code.

  • Working with (and even paying) a tutor to help you with the course, provided the tutor does not do your work for you.

Not Reasonable

  • Accessing a solution to some problem prior to (re-)submitting your own.

  • Asking a classmate to see his or her solution to a problem before (re-)submitting your own.

  • Decompiling, deobfuscating, or disassembling the staff’s solutions to problems.

  • Failing to cite (as with comments) the origins of code, writing, or techniques that you discover outside of the course’s own lessons and integrate into your own work, even while respecting this policy’s other constraints.

  • Giving or showing to a classmate a solution to a problem when it is he or she, and not you, who is struggling to solve it.

  • Looking at another individual’s work during a quiz or test.

  • Paying or offering to pay an individual for work that you may submit as (part of) your own.

  • Providing or making available solutions to problems to individuals who might take this course in the future.

  • Searching for, soliciting, or viewing a quiz’s questions or answers prior to taking the quiz.

  • Searching for or soliciting outright solutions to problems online or elsewhere.

  • Splitting a problem’s workload with another individual and combining your work (unless explicitly authorized by the problem itself).

  • Submitting (after possibly modifying) the work of another individual beyond allowed snippets.

  • Submitting the same or similar work to this course that you have submitted or will submit to another.

  • Using resources during a quiz beyond those explicitly allowed in the quiz’s instructions.

  • Viewing another’s solution to a problem and basing your own solution on it.

Assessment

Your work on this problem set will be evaluated along four axes primarily.

Scope

To what extent does your code implement the features required by our specification?

Correctness

To what extent is your code consistent with our specifications and free of bugs?

Design

To what extent is your code written well (i.e., clearly, efficiently, elegantly, and/or logically)?

Style

To what extent is your code readable (i.e., commented and indented with variables aptly named)?

To obtain a passing grade in this course, all students must ordinarily submit all assigned problems unless granted an exception in writing by the instructor.

Readin' Bookz

As you may know, most any book that you borrow or buy has an International Standard Book Number, otherwise known as an ISBN or ISBN-10, "a 10-digit number that uniquely identifies books and book-like products published internationally."[1] Books published since 2007 might also have an ISBN-13, a 13-digit number with a similar purpose, but never mind those.

It turns out that the last of an ISBN-10’s digits is a "check digit," otherwise known (in binary contexts) as a "checksum," a number related mathematically to its preceding digits. ISBN-10s' digits are supposed to adhere to a formula, not unlike credit card numbers, and this check digit allows you to check whether an ISBN-10’s other nine digits are (most likely) valid without having to check, say, a database of books.

Per the International ISBN Agency’s ISBN Users' Manual, "The check digit is the last digit of an ISBN. It is calculated on a modulus 11 with weights 10-2, using X in lieu of 10 where ten would occur as a check digit."[2]

Rly?

Yes rly, but what does that mean? The manual elaborates. "This means that each of the first nine digits of the ISBN—excluding the check digit itself—is multiplied by a number ranging from 10 to 2 and that the resulting sum of the products, plus the check digit, must be divisible by 11 without a remainder."

Okay, better, but still a bit unclear. Let’s define the check digit in terms of a formula. Fortunately, thanks to "modular arithmetic," we can simplify the Agency’s formal definition using weights ranging from 1 to 9 instead of 10 to 2. In fact, it’s really quite simple. If x1 represents an ISBN-10’s first digit and x10 its last[3], it turns out that:

x10 = (1·x1 + 2·x2 + 3·x3 + 4·x4 + 5·x5 + 6·x6 + 7·x7 + 8·x8 + 9·x9) mod 11

In other words, to compute an ISBN-10’s tenth digit, multiply its first digit by 1, its second digit by 2, its third digit by 3, its fourth digit by 4, its fifth digit by 5, its sixth digit by 6, its seventh digit by 7, its eighth digit by 8, and its ninth digit by 9. Take the sum of those products and then divide it by 11. The remainder should be the ISBN-10’s tenth digit! If, though, that remainder is 10, the tenth digit should instead be printed as X lest it be confused with a 1 followed by 0.

I S BN Calculatin'

Let’s try all this out. The ISBN-10 for the Absolute Beginner’s Guide to C, one of the course’s recommended books, is 0-789-75198-4, the tenth digit of which is, obviously, 4. But is the syllabus right? Well, let’s first take that sum using the ISBN-10’s first nine digits (highlighted in bold):

0 + 2·7 + 3·8 + 4·9 + 5·7 + 6·5 + 7·1 + 8·9 + 9·8 = 290

If we now divide that sum by 11, we get 204 ÷ 11 = 26 4/11 (i.e., a remainder of 4)! Well that’s kind of neat, the ISBN is legit! Actually, also thanks to modular arithmetic, we could just include that tenth digit in our sum and multiply it by 10:

0 + 2·7 + 3·8 + 4·9 + 5·7 + 6·5 + 7·1 + 8·9 + 9·8 + 10·4 = 330

If we now divide this sum by 11, we get 330 ÷ 11 = 30 with no remainder at all, which is an equivalent way of saying the ISBN-10 is legit! Stated more formally, 0 ≡ 330 (mod 11)!

Hopefully those exclamation points make the math more exciting.

So, computing this check digit’s not hard, but it does get a bit tedious by hand. Let’s write a program.

Create a file called isbn.c inside of your ~/workspace/unit1 directory, in which you should write a program that prompts the user for an ISBN-10 and then reports (via printf) whether the number’s legit. So that we can automate some tests of your code, we ask that your program’s last line of output be either YES\n or NO\n, nothing more, nothing less.

For simplicity, you may assume that the user’s input will be exactly ten decimal digits (i.e., devoid of hyphens and X), the first of which might even be zero(es), as in the case of our recommended book. But do not assume that the user’s input will fit in an int! Recall, after all, that the largest value that can fit in an int is 232 - 1 = 4,294,967,295 (and, even then, only if declared as unsigned). True, that’s a 10-digit value, but there might still be a problem. (What?) Best to be safe and use GetLongLong from CS50’s library to get users' input. (Why?)

Okay, so you’ve gotten some input. What should you do? Well, realize that this C program, not unlike Scratch projects, can be reduced to the most basic of building blocks. For the sake of discussion, suppose that some variable x contains a 10-digit long long (with no leading zeroes). How can you get at its tenth (i.e., rightmost) digit? Well how about this?

int tenth = x % 10;

Do you see why that works? Do not pass Go until it dawns on you why!

How, now, can you get at that same variable’s ninth digit? Well, why don’t we first get rid of its tenth digit by shifting every other one place to the right?

x = x / 10;

How about that trick? Do you see why it works? The ninth digit, now, is just:

int ninth = x % 10;

So we bet there’s a pattern here. And odds are you don’t need to (i.e., shouldn’t) copy/paste lines like the above nine or ten times. Loops are your friend. To be sure, other approaches exist. Proceed as you wish! Perhaps some of these tricks, though, will get you started.

To compile your program, type

make isbn

Assuming your program compiled without errors (or, ideally, warnings) via either command, run your program with the command below.

./isbn

Consider the below representative of how your own program should behave when passed a valid ISBN-10 (sans hyphens); underlined is some user’s input.

username@ide50:~/workspace/unit1 $ ./isbn
ISBN: 0789751984
YES

Of course, GetLongLong itself will reject an ISBN-10’s hyphens (and more) anyway:

username@ide50:~/workspace/unit1 $ ./isbn
ISBN: 0-789-75198-4
Retry: foo
Retry: 0789751984
YES

But it’s up to you to catch inputs that are not ISBN-10s (e.g., Jenny’s[4] phone number), even if ten digits.

username@ide50:~/workspace/unit1 $ ./isbn
ISBN: 5558675309
NO

Test out your program with a whole bunch of inputs, both valid and invalid. (We certainly will!) There are lots of valid ISBN-10s on amazon.com. Of course, you should also test your program with check50:

check50 1516.unit1.isbn isbn.c

If your program behaves incorrectly on some inputs (or doesn’t compile at all), have fun debugging! And if you’d like to play with the staff’s own implementation of isbn on CS50 IDE, you may execute the below.

~cs50/unit1/isbn

This was Problem 1-7.


1. http://www.isbn.org/standards/home/isbn/us/isbnqa.asp
2. http://www.isbn-international.org/en/userman/download/ISBNmanual.pdf
3. Normally, we’d start counting from 0 and not 1, but for ISBN-10s, it’s simpler not to!
4. https://en.wikipedia.org/wiki/867-5309/Jenny