--- /dev/null
+#next
+0.1a 10
--- /dev/null
+#print
+This script is loosely based on the material in
+"The C Programming Language", by Brian Kernighan
+and Dennis Ritchie (Prentice-Hall, 1978).
+You may find it helpful to have that at hand.
+Some of the lessons will indicate
+the section that they are based on.
+
+Do you have a copy at hand? Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match yes
+Fine.
+#fail
+It might help, but it's not critical.
+#log
+#next
+1.1a 10
--- /dev/null
+#print
+(Section 1.1)
+The way you compile a C program is to say
+ cc name.c
+where name.c is the name of the file the program
+is on. Here is a short C program that prints
+out a line containing "hello". Type it in and
+compile it. Call it anything you want but
+don't rename the output.
+When done, type "ready".
+
+main()
+{
+ printf("hello\n");
+}
+#once #create Ref
+hello
+#user
+a.out >x
+#cmp x Ref
+#log
+#next
+1.1b 10
--- /dev/null
+#print
+(Section 1.1)
+Now write a C program that prints two lines,
+the first of which says "hello" and the second
+"goodbye". Don't forget those \n delimiters.
+Compile and test it. When satisfied,
+type "ready".
+#once #create Ref
+hello
+goodbye
+#user
+a.out >test
+#cmp test Ref
+#succeed
+Here is one possible solution to compare against yours.
+
+main()
+{
+ printf("hello\n");
+ printf("goodbye\n");
+}
+
+You could also combine the two messages into one
+call to printf, like
+
+ printf("hello\ngoodbye\n");
+
+but this is harder to read at a glance.
+#log
+#next
+1.1c 10
--- /dev/null
+#print
+(Section 1.1)
+The program in Ref.c has an error in it.
+Find it, fix it, and run it.
+Then type ready.
+#once #create Ref.c
+main()
+{
+ printf("hello\");
+}
+#once #create Ref
+hello
+#user
+a.out >x
+#cmp x Ref
+#log
+#next
+1.1d 10
--- /dev/null
+#print
+(Section 1.1)
+Write a program which prints these four lines,
+exactly as shown:
+A tab is \t
+A backspace is \b
+A quote is \"
+A backslash is \\
+
+Compile it, test it, then type ready.
+#once #create Ref
+A tab is \t
+A backspace is \b
+A quote is \"
+A backslash is \\
+#user
+a.out >x
+#cmp x Ref
+#succeed
+One solution:
+
+main()
+{
+ printf("A tab is \\t\n");
+ printf("A backspace is \\b\n");
+ printf("A quote is \\\"\n");
+ printf("A backslash is \\\\\n");
+}
+#fail
+Watch out for those backslashes.
+#log
+#next
+1.1e 10
--- /dev/null
+#print
+What will be printed by the following printf statement?
+
+ printf("\"#@\"");
+
+Type "answer XXX", where XXX is the set of characters
+that will be printed.
+#copyin
+#user
+#uncopyin
+#match "#@"
+#log
+#next
+1.1f 10
--- /dev/null
+#print
+(Section 1.2)
+Write a program to print
+the value of the character 'X' in
+octal. Compile it and run it.
+Then type ready.
+#user
+a.out >test
+grep 130 test >/dev/null
+#succeed
+A possible solution:
+
+main()
+{
+ printf("%o\n", 'X');
+}
+#log
+#next
+2.1a 10
--- /dev/null
+#print
+The lessons from this point on are from the old C script.
+They have not been cleaned up as much as they could, so some
+are not very illuminating, and the code they illustrate
+is not always the best. You're welcome to try them nonetheless,
+but be warned.
+If you want to proceed, type yes;
+otherwise, type bye.
+#copyin
+#user
+#uncopyin
+#match yes
+#next
+11.1a 10
+11.2a 5
--- /dev/null
+#print
+With your 'cc' command you can give the name of
+an object file to be loaded with your program.
+For example
+ cc x.c y.o
+will load the previously compiled program 'y' along with
+the program 'x' to be compiled now.
+
+The file "getnum.o" contains a subroutine "getnum" which
+reads an integer and returns its value.
+Write a program which reads a number and decides
+whether or not it is a multiple of 23. If so print
+"yes" and otherwise print "no".
+Compile and test; then type "ready".
+#once #create Ref1
+23000
+#once #create Ref2
+23001
+#once cp %s/getnum.o .
+#user
+a.out <Ref1 >z1
+a.out <Ref2 >z2
+grep yes z1 >/dev/null && grep no z1 >/dev/null
+#succeed
+/* One way: */
+
+main() {
+ if (getnum()%23 == 0)
+ printf("yes\n");
+ else
+ printf("no\n");
+}
+#log
+#next
+12.1a 10
--- /dev/null
+#print
+With your 'cc' command you can give the name of
+an object file to be loaded with your program.
+For example
+ cc x.c y.o
+will load the previously compiled program 'y' along with
+the program 'x' to be compiled now.
+There is a file in this directory named "getnum.o"
+that contains a subroutine "getnum" that will read digits
+from the standard input, convert them to binary, and
+return an integer value.
+
+Write a program which reads an integer and prints
+it back in octal. Compile and test as usual.
+#once #create Ref
+254
+#once cp %s/getnum.o .
+#user
+a.out <Ref >test
+grep 376 test >/dev/null
+#succeed
+/* One way: */
+
+main() {
+ printf("%o\n", getnum());
+}
+#log
+#next
+11.1a 10
--- /dev/null
+#print
+Write a program which reads two numbers and
+prints the larger one in decimal. Use the same
+"getnum" subroutine. Compile, test and type
+"ready" as usual.
+#once #create Ref1
+14039 89
+#once #create Ref2
+20022 23001
+#once cp %s/getnum.o .
+#user
+a.out <Ref1 >x1
+a.out <Ref2 >x2
+grep 14039 x1 >/dev/null && grep 23001 x2 >/dev/null
+#succeed
+/* One way: */
+
+main() {
+ int n1, n2;
+
+ n1 = getnum();
+ n2 = getnum();
+ printf("%d\n", n1 > n2 ? n1 : n2);
+}
+
+You could also use something like
+
+ if (n1 > n2)
+ printf("%d\n", n1);
+ else
+ printf("%d\n", n2);
+#log
+#next
+12.1b 10
--- /dev/null
+#print
+The function getnum actually returns -1 when it
+encounters end of file. (The source is in getnum.c
+if you're interested.)
+Write, compile and run a program that
+reads numbers one per line with getnum
+and, for each, prints:
+
+small if the number is >0 and <=100
+big if the number is >100 and <=1000
+huge if the number is >1000.
+
+Type "ready" when you're done.
+#once cp %s/getnum.o .
+#once cp %s/getnum.c .
+#once #create Ref
+1001
+1000
+999
+101
+100
+1
+#once #create Ref1
+huge
+big
+big
+big
+small
+small
+#user
+a.out <Ref >test
+#cmp Ref1 test
+#succeed
+One way:
+
+main() {
+ int n;
+
+ while ((n = getnum()) >= 0)
+ if (n > 0 && n <= 100)
+ printf("small\n");
+ else if (n > 100 && n <= 1000)
+ printf("big\n");
+ else if (n > 1000)
+ printf("huge\n");
+}
+
+ Notice that in principle n could be negative,
+ so we need the last case to say
+ else if (n > 1000)
+ instead of just falling into it with a bare
+ else
+
+ Also it's a good idea to indent the else-if's
+ exactly the way they are here; otherwise
+ you'll lose track of what's going on.
+#log
+#next
+13.1a 10
--- /dev/null
+#print
+Write a program which reads
+its input and counts the number of
+characters and the number of spaces
+(where a space is either a blank or
+a tab or a newline). Print both numbers.
+Compile, test, and type "ready".
+#once #create Ref
+hoboken harrison newark roseville avenue grove street
+east orange brick church orange highland avenue
+mountain station south orange maplewood millburn short hills
+summit chatham madison convent station morristown
+new providence murray hill berkeley heights
+gillette stirling millington lyons basking ridge
+bernardsville far hills peapack gladstone
+#user
+a.out <Ref >x1
+a.out <Ref >x2
+grep 348 x1 >/dev/null && grep 45 x2 >/dev/null
+#success
+One way:
+
+ \b#include <stdio.h>
+
+main() {
+ int nchar, nspace;
+ char c;
+
+ nchar = nspace = 0;
+ while ((c = getchar()) != EOF) {
+ nchar++;
+ if (c == ' ' || c == '\t' || c == '\n')
+ nspace++;
+ }
+ printf("spaces = %d, chars = %d\n", nspace, nchar);
+}
+#log
+#next
+14.1a 10
+14.2a 5
--- /dev/null
+#print
+Using the familar "getnum.o" routine
+write a program that reads numbers one per line and determines
+for each if it is prime. Print "prime"
+for a prime number and "composite" for a non-prime number.
+Compile, test, and type "ready".
+#once #create Ref
+10039
+17947
+#once #create Ref1
+prime
+composite
+#once cp %s/getnum.o .
+#user
+a.out <Ref >x1
+#cmp x1 Ref1
+#success
+/* A slow but sure prime-tester */
+main()
+{
+ int p, i, comp;
+
+ while ((p = getnum()) >= 0) {
+ comp = 0;
+ for (i = 2; i*i <= p; i++)
+ if (p%i == 0) {
+ comp = 1;
+ break;
+ }
+ if (comp)
+ printf("composite\n");
+ else
+ printf("prime\n");
+ }
+}
+#log
+15.1a 10
--- /dev/null
+#print
+Using the "getnum" routine on "getnum.o", write a program
+that reads a list of positive numbers and prints their sum. Stop reading
+numbers when "getnum" returns a negative or zero value.
+Compile and test your program; then type "ready".
+#once #create Ref
+5 43 293 400 75 832 903 33
+#once cp %s/getnum.o .
+#user
+a.out <Ref >xxx
+grep 2584 xxx >/dev/null
+#succeed
+/* Read numbers and count */
+main()
+{
+ int s, n;
+
+ s = 0;
+ while ((n=getnum()) > 0)
+ s += n;
+ printf("Sum is %d\n", s);
+}
+#log
+#next
+14.2b 5
+15.1a 10
--- /dev/null
+#print
+Write a program which counts the number of five letter
+words in its input (define a word as anything between
+blanks, tabs or newlines). Compile and run it, then type "ready".
+Note that all that is wanted is the total number of
+five letter words - nothing was said about distinct
+words. Just count the number of times exactly five
+characters appear between spaces.
+#once #create Ref
+This is a passage of text which contains
+exactly twelve words of five letters.
+Words may appear at the start or at the final
+part of a line. Other words show up in
+the middle. Avoid counting seven or eight letters
+but every five must be noted.
+#user
+a.out <Ref >xxx
+grep 12 xxx >/dev/null
+#succeed
+/* one way to count five letter words */
+ \b#include <stdio.h>
+
+main()
+{
+ int since, wdnum, c;
+
+ since = 0;
+ while ((c=getchar()) != EOF) {
+ if (c == ' ' || c == '\t' || c == '\n') {
+ if (since == 5)
+ wdnum++;
+ since = 0;
+ }
+ else
+ since++;
+ }
+ printf("%d\n", wdnum);
+}
+#log
+#next
+15.1a 10
--- /dev/null
+#print
+Write a program that reads in lines one at a time,
+and prints them out if their length (including
+the newline) is odd.
+You can use the function getline if you like; the object
+file is in getline.o.
+Compile and run it, then type "ready".
+#once #create Ref1
+this line contains an odd number of letters
+this line, however, contains an even number of letters
+#once #create Ref2
+this line contains an odd number of letters
+#once cp %s/getline.o .
+#user
+a.out <Ref1 >x1
+#cmp x1 Ref2
+#succeed
+It's certainly easiest with getline:
+
+ \b#include <stdio.h>
+
+main()
+{
+ char line[500];
+ int n;
+
+ while ((n = getline(line, 500)) > 0)
+ if (n % 2 == 1)
+ printf("%s", line);
+}
+#log
+#next
+15.1b 10
--- /dev/null
+#print
+Write a program that reads in lines, and prints each out
+in reverse order (except that the newline should be
+at the end).
+Thus the line
+cat food
+should come out as
+doof tac
+Compile it and run it, then type "ready".
+#once #create Ref1
+This is odd.
+This is even.
+
+#once #create Ref2
+.ddo si sihT
+.neve si sihT
+
+#once cp %s/getline.o .
+#user
+a.out <Ref1 >x1
+#cmp x1 Ref2
+#succeed
+/* one way to do this */
+ \b#include <stdio.h>
+
+main()
+{
+ char line[500];
+ int n;
+
+ while ((n = getline(line, 500)) > 0) {
+ for (n -= 2; n >= 0; n--)
+ putchar(line[n]);
+ putchar('\n');
+ }
+}
+#log
+#next
+17.1a 10
+16.2a 5
--- /dev/null
+#print
+Write a program which reads a file with lines of up
+to 200 characters and shortens them to 60 characters
+by throwing away any characters past the first 60.
+Compile and test it; then type "ready".
+#once #create Ref
+hoboken harrison newark roseville avenue grove street
+east orange brick church orange highland avenue east orange
+mountain station south orange maplewood millburn short hills
+summit chatham madison convent station morristown summit cha
+new providence murray hill berkeley heights
+
+gillette stirling millingon lyons basking ridgexxxxxxxxxxxxx
+bernardsville far hills peapack gladstone
+#once #create badin
+hoboken harrison newark roseville avenue grove street
+east orange brick church orange highland avenue east orange brick church orange highland avenue east orange brick church orange highland avenue
+mountain station south orange maplewood millburn short hills
+summit chatham madison convent station morristown summit chatham madison convent station morristown summit chatham madison convent station morristown
+new providence murray hill berkeley heights
+
+gillette stirling millingon lyons basking ridgexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+bernardsville far hills peapack gladstone
+#user
+a.out <badin >xxx
+#cmp Ref xxx
+#succeed
+/* one way to do this */
+ \b#include <stdio.h>
+
+main()
+{
+ char line[61];
+ int c, k;
+
+ k = 0;
+ while ((c = getchar()) != EOF) {
+ if (c == '\n') {
+ line[k] = 0;
+ printf("%s\n", line);
+ k = 0;
+ }
+ else if (k < 60)
+ line[k++] = c;
+ }
+}
+
+Note that this version works regardless of
+how long the lines are. If you use getline,
+is the same thing true??
+#log
+#next
+16.2b 10
--- /dev/null
+#print
+Write a program which copies all lines containng
+the letter 'p' from its input to its output.
+Compile and test it; then type "ready".
+#once #create Ref
+mountain station south orange maplewood millburn short hills
+new providence murray hill berkeley heights
+bernardsville far hills peapack gladstone
+#once #create badin
+hoboken harrison newark roseville avenue grove street
+east orange brick church orange highland avenue
+mountain station south orange maplewood millburn short hills
+summit chatham madison convent station morristown
+new providence murray hill berkeley heights
+gillette stirling millington lyons basking ridge
+bernardsville far hills peapack gladstone
+#once cp %s/getline.o .
+#user
+a.out <badin >xxx
+#cmp Ref xxx
+#succeed
+/* a way to find lines with 'p' */
+ \b#include <stdio.h>
+
+main()
+{
+ char line[500];
+ int k;
+
+ while (getline(line, 500) > 0)
+ for (k = 0; line[k] != '\0'; k++)
+ if (line[k] == 'p') {
+ printf("%s", line);
+ break;
+ }
+}
+#log
+#next
+16.2c 5
+17.1a 10
--- /dev/null
+#print
+Write a program to read its input and find the
+word in it with the most vowels (instances of a,e,i,o, or u).
+Print out that word. Compile and test your
+program, then type ready.
+#once #create Ref
+When in the course of human events, it becomes
+necessary for one people to dissolve the political bands which have
+connected them with another, and to assume among the
+powers of the earth the separate and equal station to which
+the laws of Nature and of Nature's God entitle them, a decent
+respect to the opinions of mankind requires that they should
+declare the causes which impel them to the separation.
+ We hold these truths to be self evident, that all men
+are created equal, that they are endowed by their creator
+with certain unalienable rights, that among these are life, liberty,
+and the pursuit of happiness. That to secure these rights,
+governments are instituted among men, deriving their just
+powers from the consent of the governed. That whenever
+any form of government becomes destructive of these ends,
+it is the right of the people to alter or to abolish it, and
+to institute new government, laying its foundation on such
+principles and organizing its powers in such form, as to them
+shall seem most likely to effect their safety and happiness.
+#user
+a.out <Ref >xxx
+grep inalienable xxx >/dev/null
+#succeed
+/* a way to find a word with lots of vowels */
+ \b#include <stdio.h>
+
+main()
+{
+ char bigword[100], thisword[100];
+ int nvow, maxvow, c, k;
+
+ maxvow = k = 0;
+ while ((c = getchar()) != EOF) {
+ if (c == '\n' || c == ' ') {
+ if (nvow > maxvow) {
+ copy(thisword, bigword, k);
+ maxvow = nvow;
+ }
+ nvow = k = 0;
+ } else {
+ thisword[k++] = c;
+ switch (c) {
+ case 'a': case 'e': case 'i': case 'o': case 'u':
+ nvow++;
+ }
+ }
+ }
+ printf("the word %s had %d vowels\n", bigword, maxvow);
+}
+
+copy(a, b, n)
+char a[], b[];
+{
+ int i;
+
+ for(i = 0; i < n; i++)
+ b[i] = a[i];
+ b[i] = 0;
+}
+#log
+#next
+17.1a 10
--- /dev/null
+#print
+Write in a program which reads its input and writes it
+out line numbered, with a three-digit line number (starting at one)
+followed by a single space and then by the original line.
+Note: the printf format specification %3d will print a three
+digit number.
+You might try the function fgets (part of the standard library).
+ fgets(buf, size, stdin)
+reads from the terminal ("stdin") up to size characters
+into buf. It returns NULL on end of file.
+
+Compile and test your program; then type "ready".
+#once #create Ref
+When in the course of human events, it becomes
+necessary for one people to dissolve the political bands which have
+connected them with another, and to assume among the
+powers of the earth the separate and equal station to which
+the laws of Nature and of Nature's God entitle them, a decent
+respect to the opinions of mankind requires that they should
+declare the causes which impel them to the separation.
+ We hold these truths to be self evident, that all men
+are created equal, that they are endowed by their creator
+with certain unalienable rights, that among these are life, liberty,
+and the pursuit of happiness. That to secure these rights,
+governments are instituted among men, deriving their just
+powers from the consent of the governed. That whenever
+any form of government becomes destructive of these ends,
+it is the right of the people to alter or to abolish it, and
+to institute new government, laying its foundation on such
+principles and organizing its powers in such form, as to them
+shall seem most likely to effect their safety and happiness.
+#once #create reffed
+ 1 When in the course of human events, it becomes
+ 2 necessary for one people to dissolve the political bands which have
+ 3 connected them with another, and to assume among the
+ 4 powers of the earth the separate and equal station to which
+ 5 the laws of Nature and of Nature's God entitle them, a decent
+ 6 respect to the opinions of mankind requires that they should
+ 7 declare the causes which impel them to the separation.
+ 8 We hold these truths to be self evident, that all men
+ 9 are created equal, that they are endowed by their creator
+ 10 with certain unalienable rights, that among these are life, liberty,
+ 11 and the pursuit of happiness. That to secure these rights,
+ 12 governments are instituted among men, deriving their just
+ 13 powers from the consent of the governed. That whenever
+ 14 any form of government becomes destructive of these ends,
+ 15 it is the right of the people to alter or to abolish it, and
+ 16 to institute new government, laying its foundation on such
+ 17 principles and organizing its powers in such form, as to them
+ 18 shall seem most likely to effect their safety and happiness.
+#user
+a.out <Ref >xxx
+#cmp xxx reffed
+#succeed
+
+FROM HERE ON, EXAMPLES HAVEN'T BEEN CLEANED AT ALL
+
+ \b#include <stdio.h>
+
+main()
+{
+ char s[200];
+ int k;
+
+ k = 0;
+ while (fgets(s, 200, stdin) != NULL)
+ printf("%3d %s", ++k, s);
+}
+#log
+#next
+18.1a 10
+17.1c 5
--- /dev/null
+#print
+Print the 20 Fibonacci numbers beginning with 2
+(the sequence is 2,3,5,8,... where each number
+is the sum of the immediately preceding pair of numbers.
+Start with the pair 1,1).
+Print each number on a separate line as a five digit
+number (remember %3d in printf? %5d does five digits).
+Compile and test your program; then type "ready".
+#once #create Ref
+ 2
+ 3
+ 5
+ 8
+ 13
+ 21
+ 34
+ 55
+ 89
+ 144
+ 233
+ 377
+ 610
+ 987
+ 1597
+ 2584
+ 4181
+ 6765
+10946
+17711
+#user
+a.out >xxx
+#cmp xxx Ref
+#succeed
+/* one way */
+main()
+{
+ int f1, f2, t, count;
+
+ f1 = 1;
+ f2 = 1;
+ for (count = 0; count < 20; count++) {
+ t = f1+f2;
+ f1 = f2;
+ f2 = t;
+ printf("%5d\n", t);
+ }
+}
+#log
+#next
+18.1a 10
--- /dev/null
+#print
+There is nothing to force you to write a main program
+on each file; just as I supplied "getnum" on a separate file,
+you can put different routines on different files. Write
+a function "length(s)" which if given a character array argument
+"s" returns the length of that string.
+Put this on a file names "length.c", and leave
+the object file in "length.o".
+Write the main program for
+testing this somewhere else. Type "ready" when you have compiled
+and tested your program and are happy with it.
+#once #create Ref
+This file contains several lines of quite different lengths.
+
+You should get
+all of them exactly
+r
+right.
+#once #create answer
+60
+0
+14
+19
+1
+6
+#once #create tzaqc.c
+main() {
+ char s[200];
+ while (gets(s))
+ printf("%d\n", length(s));
+}
+#user
+cc tzaqc.c length.c -lS
+a.out <Ref >value
+#cmp value answer
+#succeed
+/* one way */
+length(s)
+char *s;
+{
+ int k;
+
+ for (k=0; s[k]; k++)
+ ;
+ return(k);
+}
+#log
+#next
+19.1a 10
--- /dev/null
+#print
+Write a subroutine which counts the number of times it has
+been called and returns that count each time. Name it
+"count()". Write it on a file named "count.c". Compile
+and test it; type "ready" when happy.
+#once #create Ref
+23080
+#once #create tzaqc.c
+main() {
+ int i;
+ for (i = 0; i < 23079; i++)
+ count();
+ printf("%d\n", count());
+}
+#user
+cc tzaqc.c count.o
+a.out >value
+#cmp value Ref
+#succeed
+/* one way */
+count()
+{
+ static int n = 0;
+ return(++n);
+}
+#log
+#next
+30.1a 10
+20.1a 5
--- /dev/null
+#print
+(Section 1.2)
+The file Ref.c contains a copy of
+a program to convert Fahrenheit to
+Celsius. Modify it to print this
+heading at the top:
+Fahrenheit-Celsius Conversion
+ F: C:
+Type ready when you're satisfied.
+#once #create Ref
+Fahrenheit-Celsius Conversion
+ F: C:
+ 0 -17.8
+ 20 -6.7
+ 40 4.4
+ 60 15.6
+ 80 26.7
+ 100 37.8
+ 120 48.9
+ 140 60.0
+ 160 71.1
+ 180 82.2
+ 200 93.3
+ 220 104.4
+ 240 115.6
+ 260 126.7
+ 280 137.8
+ 300 148.9
+#once #create Ref.c
+/* print Fahrenheit-Celsius table
+ for f = 0, 20, ..., 300 */
+main()
+{
+ int lower, upper, step;
+ float fahr, celsius;
+
+ lower = 0; /* lower limit of temperature table */
+ upper = 300; /* upper limit */
+ step = 20; /* step size */
+
+ fahr = lower;
+ while (fahr <= upper) {
+ celsius = (5.0/9.0) * (fahr-32.0);
+ printf("%4.0f %6.1f\n", fahr, celsius);
+ fahr = fahr + step;
+ }
+}
+#user
+a.out >x
+#cmp Ref x
+#fail
+Make sure you get the spacing right.
+#log
+#next
+2.1b 10
--- /dev/null
+#print
+(Section 1.2)
+Write a C program that prints a number which is
+the sum of three numbers: 23, 197, and the product
+of 23 and 197. Again, compile and test
+it. Please do the computation with the program -
+if you do it by hand, I'll give you credit for the
+work, but it's just stupid.
+#user
+a.out >test
+grep 4751 test >/dev/null
+#succeed
+/* Here is one possible solution */
+
+main()
+{
+ printf("%d\n", 23 + 197 + 23*197);
+}
+#log
+#next
+2.1c 10
--- /dev/null
+#print
+(Section 1.2)
+What value is printed by this printf statement?
+
+ printf("%.3f", 3.141592654);
+
+Type "answer XXX", where XXX is the value.
+#copyin
+#user
+#uncopyin
+#match 3.142
+#fail
+Remember about rounding?
+#log
+#next
+2.1d 10
--- /dev/null
+#print
+What value is printed by this printf statement?
+
+ printf("%%3.1f", 3.141592654);
+
+Type "answer XXX", where XXX is the value.
+#copyin
+#user
+#uncopyin
+#match %3.1f
+#fail
+Look again - it's %%
+#log
+#next
+2.1e 10
--- /dev/null
+#print
+Is there any difference between
+
+ printf("%s", s);
+
+and
+
+ printf(s);
+
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match yes
+#fail
+Consider the string "50% of the answers are wrong."
+#log
+#next
+3.1a 10
--- /dev/null
+#print
+Write a program to read a list of positive numbers
+and sort them into ascending order. Print
+the sorted list of numbers one per line
+as five digit numbers (%5d in printf).
+Stop reading numbers when getnum returns zero.
+Compile and test your program; then type "ready".
+#once #create Ref
+ 1
+ 3
+ 4
+ 9
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 20
+ 34
+ 71
+ 200
+ 225
+ 250
+ 275
+ 300
+ 4095
+ 7111
+16384
+#once cp %s/getnum.o .
+#once #create input
+4 20 3 200 16384 4095 71 11 12 13 14
+15 16 17 34 9 7111 300 275 250 225 1
+#user
+a.out <input >xxx
+#cmp xxx Ref
+#succeed
+main()
+{
+ getlist();
+ sortlist();
+ printlist();
+}
+
+int n;
+int list[1000];
+
+getlist()
+{
+ while (list[n]=getnum())
+ n++;
+}
+
+sortlist()
+{
+ shellsort(list,n);
+}
+
+/* this is a shell sort, stripped down to process a list
+ of integers only. Although you probably don't know
+ how to write this offhand, you should know where to find
+ it - it is only marginally more code than a bubble sort
+ and much faster (n**1.5 vs. n**2) in time. */
+shellsort(array, nitem)
+int *array;
+shellsort(v, n) /* sort v[0]...v[n-1] into increasing order */
+int v[], n;
+{
+ int gap, i, j, temp;
+
+ for (gap = n/2; gap > 0; gap /= 2)
+ for (i = gap; i < n; i++)
+ for (j=i-gap; j>=0 && v[j]>v[j+gap]; j-=gap) {
+ temp = v[j];
+ v[j] = v[j+gap];
+ v[j+gap] = temp;
+ }
+}
+
+printlist()
+{
+ int i;
+ for(i=0; i<n; i++)
+ printf("%5d\n",list[i]);
+}
+/* this is a crummy bubble sort which
+ would work perfectly well for this
+ problem but can not be recommended
+ for large jobs.
+sortlist()
+{
+ int i, j, k;
+
+ for(i=0; i<n; i++)
+ for(j=n-1; j>0; j--)
+ if (list[j-1] > list[j]) {
+ k = list[j];
+ list[j] = list[j-1];
+ list[j-1] = k;
+ }
+}
+ ****/
+#log
+#next
+30.1a 10
--- /dev/null
+#print
+(Section 1.3)
+The file Ref.c contains a copy of
+a program to convert Fahrenheit to
+Celsius that prints from 0 to 300
+degrees in steps of 20.
+Modify it to print from 300 down to 0
+in steps of 50. Type ready when you're done.
+#once #create Ref
+ 300 148.9
+ 250 121.1
+ 200 93.3
+ 150 65.6
+ 100 37.8
+ 50 10.0
+ 0 -17.8
+#once #create Ref.c
+/* print Fahrenheit-Celsius table
+ for f = 0, 20, ..., 300 */
+main()
+{
+ int lower, upper, step;
+ float fahr, celsius;
+
+ lower = 0; /* lower limit of temperature table */
+ upper = 300; /* upper limit */
+ step = 20; /* step size */
+
+ fahr = lower;
+ while (fahr <= upper) {
+ celsius = (5.0/9.0) * (fahr-32.0);
+ printf("%4.0f %6.1f\n", fahr, celsius);
+ fahr = fahr + step;
+ }
+}
+#user
+a.out >x
+#cmp Ref x
+#succeed
+Here's our solution:
+
+main() /* Fahrenheit-Celsius 300 ... 0 by 50 */
+{
+ int lower, upper, step;
+ float fahr;
+
+ lower = 0; /* lower limit of temperature table */
+ upper = 300; /* upper limit */
+ step = 50; /* step size */
+
+ for (fahr = upper; fahr >= lower; fahr = fahr - step)
+ printf("%4.0f %6.1f\n", fahr, (5.0/9.0) * (fahr-32.0));
+}
+#log
+#next
+3.1b 10
--- /dev/null
+#print
+What is the value of i after this
+___\b\b\bfor statement executes?
+Type "answer N", where N is the value of i.
+
+ for (i = 0; i < 10; i = i + 3)
+ ;
+#copyin
+#user
+#uncopyin
+#match 12
+#log
+#next
+4.1a 10
--- /dev/null
+#print
+Write a subroutine named "index(s,c)" which expects two
+arguments: the first is a pointer to characters 's' which
+points to a null-terminated string, and the second
+is a character 'c' which is to be searched for in the
+string 's'. If the character 'c' does not
+appear in the string return 0; otherwise return a pointer
+to the position of 'c' in the string. Name the program "index.c";
+as usual, compile and test it and then type "ready".
+#once #create Ref
+0
+19
+0
+25
+0
+#once #create tzaqc.c
+char *alpha "abcdefghijklmnopqrstuvwxyz";
+main()
+{
+ extern char *index();
+ printf("%d\n", index(alpha, '+'));
+ printf("%d\n",index(alpha, 't')-alpha));
+ printf("%d\n",index(alpha, 'a')-alpha));
+ printf("%d\n",index(alpha, 'z')-alpha));
+ printf("%d\n",index("", 'z'));
+}
+#user
+cc tzaqc.c index.o
+a.out >value
+#cmp value Ref
+#succeed
+Try this:
+
+char *index (s, c)
+char *s;
+{
+ for( ; *s; s++)
+ if (*s == c)
+ return(s);
+ return(0);
+}
+#log
+#next
+31.1a 10
--- /dev/null
+#print
+Write a function named "rev(s)" which reverses
+the string "s" in place. Name the file that contains
+the function "rev.c".
+When you're satisfied, type "ready".
+#once #create Ref
+cbax0987654321
+#once #create tzaqc.c
+main(){
+ char *s1, *s2, *s3, *s4;
+ s1 = "abc";
+ s2 = "x";
+ s3 = "";
+ s4 = "1234567890";
+ rev(s1);
+ rev(s2);
+ rev(s3);
+ rev(s4);
+ printf(s1);
+ printf(s2);
+ printf(s3);
+ printf(s4);
+ printf("\n");
+}
+#user
+cc tzaqc.c rev.o
+a.out >value
+#cmp value Ref
+#succeed
+One way:
+
+rev (s)
+char *s;
+{
+ char *p;
+ int t;
+
+ for (p=s; *p; p++)
+ ;
+ for (p--; p > s; p--, s++) {
+ t = *p;
+ *p = *s;
+ *s = t;
+ }
+}
+#log
+#next
+32.1a 10
--- /dev/null
+#print
+Write a program
+ pair(a,b)
+which accepts as arguments two pointers to integers
+and swaps the integers if necessary so that the
+first argument points to the larger one; that is
+ int x,y;
+ x = 9;
+ y = 15;
+ pair( &x, &y);
+results in x being 15 and y 9. Leave the program
+on file "pair.c"; compile, test it, and type "ready".
+#once #create tzaqc.c
+main()
+{
+int x,y;
+y=200;
+x = 0;
+pair(&y, &x);
+if (x!=0 || y !=200) return(1);
+pair(&x,&y);
+if (x!=200 || y !=0) return(1);
+x = 30;
+y = 23097;
+pair(&x,&y);
+if (x!= 23097 || y!= 30) return(1);
+return(0);
+}
+#user
+cc tzaqc.c pair.o
+a.out
+#succeed
+pair(a, b)
+int *a, *b;
+{
+ int t;
+
+ if (*a <= *b) {
+ t = *a;
+ *a = *b;
+ *b = t;
+ }
+}
+#log
+#next
+33.1a 10
--- /dev/null
+#print
+Write a program which counts the number of arguments
+it has which begin with the letter 'b'. Print the
+result in decimal. Compile and test it as usual.
+Then type "ready".
+#user
+a.out abc bcd efg rpq b bbvd >xxx
+grep 3 xxx >/dev/null
+#succeed
+/* a possible solution */
+main(argc, argv)
+char *argv[];
+{
+ int i, k;
+
+ for(i=k=0; i<argc; i++)
+ if (argv[i][0] == 'b')
+ k++;
+ printf("%d\n", k);
+}
+#log
+#next
+35.1a 10
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+Sometimes there will be a need for a subscript or superscript
+that has nothing to the left of it, as in references like
+ $"" sup 1$Smith, J. `A great paper...'
+
+Experiment and decide if you can get this effect
+by writing simply
+ %sup 1%Smith, J.....
+
+Type yes if this works, no if it does not.
+.pl 1
+#
+#once neqn message | nroff -T$term %s/tinyms -
+#copyin
+#user
+#uncopyin
+#match no
+#log
+#next
+11.1f 10
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+The way to handle the problem of a subscript or superscript
+on nothing is to provide something to hang the subscript
+or superscript on.
+One possibility is to use a tilde, but that has a real width,
+and might spoil the appearance of the output.
+The best solution is this:
+
+ "" sup 1 ...
+
+The expression "" has no width, so everything works
+out properly. The use of "" may seem a bit unnatural
+but it's an idiom that you get used to quite quickly.
+
+For practice, modify "Example" so it produces
+output that looks like this,
+then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+"" sup + H sub 2 ~ "<=>" ~ "" sup - H ~+~ "" sup + H
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+xxx
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#fail
+Don't forget spaces; don't forget to quote
+things when needed (including <=>).
+#log
+#next
+11.1g 10
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+For practice, modify "Example" so it produces
+output that looks like this,
+then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+{ lim ~ "sup" } bar ~f(x) ~=~ x
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+xxx
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+12.1a 10
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+The next step is to learn how to put big parentheses,
+brackets, braces or bars around equations, like this:
+.EQ
+left | a sup 2 over b sub i right |
+.EN
+
+This is done with two new words called "left" and "right".
+To put bars around something, you simply say, in the middle
+of an equation,
+ left | something right |
+and the job is done.
+"something" can indeed be anything, from a single letter
+up to some horribly complicated mess.
+The bars grow to the right height to cover the
+"something", automatically.
+To produce the example above, all that was needed was
+ .EQ
+ left | a sup 2 over b sub i right |
+ .EN
+
+For practice, modify file "Example" so it produces output
+that looks like this, then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+left |
+{a over b ~+~ c over d} over 2
+right |
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+replace me
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+12.1b 10
--- /dev/null
+#print
+Bars are not the only characters you can put
+around an equation.
+If you say
+ left ( thing right )
+you will get large parentheses around "thing".
+You can also use [ and ] for large square brackets
+and { and } for large braces.
+
+The main problem is that on your terminal there is
+no good way for neqn to draw large braces
+or brackets or parens. So neqn replaces all of these
+with bars.
+Use the right character anyway, though - things do
+work properly on the typesetter. And who knows, some day
+neqn may get improved as well.
+
+With the current version of neqn, does the input
+ left { a over b right }
+produce the same output as
+ left [ a over b right ]
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match yes
+#log
+#next
+12.1c 10
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+Of course the thing with bars or braces around it can
+still be part of larger expressions: the input
+ .EQ
+ left | {a over b ~+~ c over d} over 2 right | over a+b+c+d
+ .EN
+produces
+.EQ
+left | {a over b ~+~ c over d} over 2 right | over a+b+c+d
+.EN
+
+For practice, modify file "Example" so it produces output
+that looks like this, then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+left |
+{a over b ~+~ c over d} over 2
+right |
+sup half
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+replace me
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+12.1d 10
--- /dev/null
+#print
+.LP
+The "right" part of a left-right construction can be
+omitted if it is not used; just leave that part out.
+The main thing to watch out for is that now you will
+need braces to enclose the entire construction, "left" and all -
+otherwise neqn will not know where to stop in
+figuring out how high the thing is.
+
+For example, will
+ left "{" a + b over c over d
+produce the same output as
+ { left "{" a } + b over c over d
+Answer yes or no after experimenting.
+#copyin
+#user
+#uncopyin
+#match no
+#log
+#next
+12.1e 10
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.PP
+There are also occasions when you want to omit
+the left part and keep the right part.
+This is a bit more complicated, since for obscure
+reasons neqn won't let you actually leave the
+left part out completely.
+But you can ask it to print no character,
+instead of using bars, by saying
+ left "" thing right |
+.LP
+This is similar to the way we used quotes before, to get
+a zero-width thing before a superscript.
+
+For practice, modify file "Example" so it produces output
+that looks like this, then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+left ""
+int from 0 to {2 pi} sin (x) dx ~=~
+cos (x) right | sub 0 sup {2 pi}
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+replace me
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
--- /dev/null
+#print
+You may have noticed that neqn threw away the spaces
+in several of the examples we did. For example, in
+.EQ
+a = b + c - d
+.EN
+the output equation looks like
+a=b+c-d
+regardless of spaces in the input.
+
+Spaces are always thrown away, and so are new lines - you
+can type an equation on as many lines as you like.
+This latitude is permitted mainly to make it easy to type equations -
+longer equations are easier to edit when they are typed
+as a series of short input lines instead of one giant
+one.
+
+Will the printed output of this equation
+.EQ
+a
++
+b
++
+c
+.EN
+be any different from this one?
+.EQ
+a+b+c
+.EN
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match no
+#log
+#next
+2.1b 10
+2.2a 5
--- /dev/null
+#print
+Since spaces are thrown away, what do you do when
+you want spaces? The answer is that you have to ask for
+them explicitly.
+If you type a "~" (tilde) it will be replaced by a space
+on output; use one tilde for each space.
+Thus to get
+a + b
+you need
+.EQ
+a~+~b
+.EN
+
+Modify the equation in file "Example" so there is one space
+around each of the operators =, + and -, so it looks like
+
+a = b + c - d
+
+Print it with neqn and nroff -ms to verify it.
+Type "ready" when done.
+#once #create Ref
+.PP
+You probably thought you were done with this ridiculous
+example of just
+.EQ
+a ~=~
+b ~+~ c
+~-~d
+.EN
+Sorry, but you will probably even see it again.
+.pl 1
+#once neqn Ref | nroff >X1 &
+#once #create Example
+.PP
+You probably thought you were done with this ridiculous
+example of just
+.EQ
+a =
+b + c
+-d
+.EN
+Sorry, but you will probably even see it again.
+.pl 1
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+2.1c 10
+2.2b 5
--- /dev/null
+#once #create message
+.nf
+.EQ
+delim $$
+.EN
+Several of the examples we did earlier had Greek letters
+and other mathematical symbols in them.
+The way to get things like $pi$ and $sum$ and $int$ is
+rather easy - you just spell out their names, like this:
+
+$pi$ is pi
+
+$sum$ is sum
+
+$int$ is int
+
+and so on.
+The main thing you must always remember about these names
+is that when they appear in an equation, they must be
+separated from surrounding symbols by blanks or tildes,
+OR THEY WILL NOT BE RECOGNIZED.
+
+For practice, modify "Example" so the symbol $partial$
+is replaced by $sum$ everywhere it appears.
+Type "ready" when you're done.
+.pl 1
+#once #create Ref
+.PP
+The symbol
+.EQ
+sum
+.EN
+often appears in lines like
+.EQ
+{ sum x } over { sum y } = y over x
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message | nroff -T$term
+#once #create Example
+.PP
+The symbol
+.EQ
+partial
+.EN
+often appears in lines like
+.EQ
+{ partial x } over { partial y } = y over x
+.EN
+.pl 1
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+2.1d 10
--- /dev/null
+#print
+The file "Chars" contains a longer list of characters that
+you can obtain with neqn.
+Print the file "Chars" with neqn and nroff -ms, then
+type "ready". (Don't forget -Txxx.)
+#once #create Chars
+.LP
+.EQ
+delim $$
+.EN
+.nf
+$alpha$ alpha
+$beta$ beta
+$gamma$ gamma
+$GAMMA$ GAMMA
+$delta$ delta
+$DELTA$ DELTA
+$epsilon$ epsilon
+$zeta$ zeta
+$eta$ eta
+$THETA$ THETA
+$theta$ theta
+$lambda$ lambda
+$LAMBDA$ LAMBDA
+$mu$ mu
+$nu$ nu
+$xi$ xi
+$pi$ pi
+$PI$ PI
+$rho$ rho
+$sigma$ sigma
+$SIGMA$ SIGMA
+$tau$ tau
+$phi$ phi
+$PHI$ PHI
+$psi$ psi
+$PSI$ PSI
+$omega$ omega
+$OMEGA$ OMEGA
+$partial$ partial
+$integral$ integral
+$int$ int
+$sum$ sum
+$prod$ prod
+$<=$ <=
+$>=$ >=
+$==$ ==
+$cdot$ cdot
+$...$ ...
+.pl 1
+#copyin
+#user
+#uncopyin
+grep 'neqn Chars *| *nroff' <.copy >/dev/null
+#log
+#next
+2.1e 10
--- /dev/null
+#once #create message
+.ND
+.PP
+For practice, in this directory there is a file called
+"Example". It contains an equation. Make it
+look like this:
+.EQ
+int from i to j f( pi ) ~=~ LAMBDA (x)
+.EN
+by changing the character names as appropriate
+and adding spaces where needed.
+Type "ready" when you're satisfied.
+.pl 1
+#once neqn message | nroff -T$term %s/tinyms -
+#once #create Ref
+.LP
+.EQ
+int from i to j f( pi ) ~=~ LAMBDA (x)
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+sum from i to j f(q) = lambda (x)
+.EN
+.pl 1
+#once neqn Ref | nroff >X2 &
+#user
+neqn Example | nroff >X1
+#cmp X1 X2
+#log
+#next
+2.1f 10
+2.2e 5
--- /dev/null
+#once #create message
+.ND
+.LP
+One of the most common problems in using neqn is forgetting
+to leave spaces or tildes around "magic" words like "pi"
+or "int" or "sum". The result is that the magic words
+cease to be magic, and just look like ordinary strings
+of letters.
+
+In the file "Example", there are several such errors.
+Find them, and fix them so the output looks
+like this, then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+sum ~=~ pi ~+~1
+.EN
+.EQ
+a~=~ pi (x)
+.EN
+.EQ
+alpha ~=~ beta ~+~ gamma ~+~ delta
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+sum=pi+1
+.EN
+.EQ
+a=pi(x)
+.EN
+.EQ
+alpha=beta+gamma+delta
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+3.1a 10
--- /dev/null
+#print
+Will the output from the first equation below be different
+from the second?
+
+.EQ
+X = Y
++Z
+.EN
+
+.EQ
+x = y
++ z
+.EN
+
+Answer yes if they will be different,
+no if they will be the same.
+#copyin
+#user
+#uncopyin
+#match yes
+#fail
+Look more closely at ____\b\b\b\bwhat letters are being printed.
+#log
+#next
+2.1b 10
--- /dev/null
+#print
+One more example of spaces before getting on to something
+new.
+In the file "Example", change the spacing so the equation
+reads
+
+a = b+c-d
+
+Print the example with "-ms".
+Type "ready" when you're done.
+#once #create Ref
+.PP
+Here it is again. One example goes a long way.
+.EQ
+a ~=~
+b + c
+-d
+.EN
+Sorry, but you will probably even see it again.
+.pl 1
+#once #create Example
+.PP
+Here it is again. One example goes a long way.
+.EQ
+a =
+b + c
+-d
+.EN
+Sorry, but you will probably even see it again.
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+2.1c 10
--- /dev/null
+#print
+Make the two equations in "Example" look like these two,
+then type "ready".
+
+#once #create Ref
+.ND
+.LP
+.EQ (1.1)
+PI ~=~ ( pi sub 1 , pi sub 2 ,..., pi sub n )
+.EN
+.EQ (1.2)
+pi bar ~=~ sum ( alpha , beta )
+.EN
+.pl 1
+#once #create Example
+.ND
+.LP
+.EQ
+PHI = ( phi sub 1 , phi sub 2 ,..., phi sub n )
+.EN
+.EQ
+phi bar = sum (A,B)
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#fail
+Don't forget equation numbering and spaces
+where needed. Print file "Chars" if you've forgotten
+the character names.
+#log
+#next
+2.1f
--- /dev/null
+#once #create message
+.ND
+.PP
+Now that we have some of the preliminaries out of the way,
+we can get on to doing real mathematics.
+I have been slipping small things into the example files
+as we go along so that you will at least have seen
+some common neqn constructions.
+
+One of the most frequent is the word "sub", which
+indicates a subscript, like this:
+
+ .EQ
+ x sub i + y sub j
+ .EN
+
+which produces
+.EQ
+x sub i + y sub j
+.EN
+The main thing to notice is that the blanks are delimiters -
+the subscript of "x" is "i"; the blank after the "i" marks
+the end of the subscript.
+
+Modify the file "Example" so the equation in it looks like
+this:
+.EQ
+x sub alpha ~=~ y sub pi ~+~ z sub pi
+.EN
+Then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+x sub alpha ~=~ y sub pi ~+~ z sub pi
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+xxx
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+3.1b 10
+3.2a 5
--- /dev/null
+#once #create message
+.ND
+.PP
+Naturally there is a superscript operation that's exactly
+like "sub", except that it goes up instead of down.
+It is called "sup". To make
+.EQ
+x sup i+j
+.EN
+for example, you type
+ .EQ
+ x sup i+j
+ .EN
+
+Make the file "Example" produce the same output
+as the following, then type "ready".
+#once #create Ref
+.LP
+.EQ
+x sup alpha ~=~ y sup pi ~+~ z sup pi
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+xxx
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#fail
+Don't forget that there are spaces
+around the = and +.
+#cmp X1 X2
+#log
+#next
+3.1c 10
--- /dev/null
+#once #create message
+.ND
+.PP
+Subscripts and superscripts can appear in the same equation,
+and any subscripted or superscripted thing can have
+a subscript or superscript.
+For example, you can say
+
+ .EQ
+ x sub i sub j ~+~ y sup i sup j
+ .EN
+
+to get
+.EQ
+x sub i sub j ~+~ y sup i sup j
+.EN
+Modify "Example" to produce the following output, then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+2 sup 2 sup 2 sup 2 ~=~ 65536
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+xxx
+.EN
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+3.1d 10
+3.2c 5
--- /dev/null
+#once #create message
+.ND
+.PP
+There is one special construction with subscripts
+and superscripts that you have to be aware of, although
+it almost always does what you want automatically.
+When something has both a subscript and a superscript,
+it is usually printed as
+.EQ
+x sub i sup j
+.EN
+instead of
+.EQ
+{x sub i} sup j
+.EN
+To produce this effect, with the superscript _____\b\b\b\b\babove the
+subscript instead of to the right, you have to type
+the subscript ______\b\b\b\b\b\bbefore the superscript, like this:
+
+ .EQ
+ x sub i sup j
+ .EN
+
+That's all there is to it.
+
+Modify "Example" to produce the following output, then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+x sub ij sup kmn = y sub i sub j
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+xxx
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+3.1e 10
+3.2d 5
--- /dev/null
+#once #create message
+.ND
+.PP
+One common typing error that you should watch out for
+is forgetting to end a superscript or subscript
+with a blank or other delimiter (like tilde).
+For instance, you often see output like
+.EQ
+f(x sup 2)=1
+.EN
+because there wasn't a space left between the 2 and the ).
+What we really wanted, of course, was
+.EQ
+f(x sup 2 )=1
+.EN
+
+Modify "Example" to produce this output, then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+g( x sup pi )
+= pi (gx sup 2 )
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+g( x sup pi)
+=pi(gxsup2)
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+4.1a 10
--- /dev/null
+#print
+Do
+ x sub i +y sub j
+and
+ x sub i+y sub j
+produce the same output?
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match no
+#log
+#next
+3.1b 10
--- /dev/null
+#once #create message
+.ND
+.PP
+Modify "Example" to produce this output, then type "ready".
+#once #create Ref
+.LP
+.EQ
+x sup 2 + y sup 2 = z sup 2
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+xxx
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+3.1d 10
--- /dev/null
+#print
+Does the equation
+
+ x sup pi sub i
+
+produce the same output as
+
+ x sub i sup pi
+
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match no
+#log
+#next
+3.1e 10
--- /dev/null
+#once #create message
+.ND
+.EQ
+delim $$
+.EN
+.LP
+The next neqn word to learn is "over", which makes
+fractions like
+.EQ
+a+b over c
+.EN
+In fact that line was made by
+ .EQ
+ a+b over c
+ .EN
+To begin with an easy one, reproduce
+the equation below in the file "Example", then type
+ready.
+(To get $>=$, type ">=".)
+.pl 1
+#once #create Ref
+.LP
+.EQ
+x+1 over y+1 ~>=~ x over y
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+replace me
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+4.1b 10
+4.2a 5
--- /dev/null
+#once #create message
+.ND
+.LP
+Of course you can use reserved words like "pi" or "int"
+with the "over" construction. For example, modify
+"Example" so its output looks like the following, then
+type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+alpha over beta ~=~ pi over 2
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+replace me
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#fail
+The names are alpha, beta and pi.
+I hope your trouble wasn't any more
+complicated than that.
+#log
+#next
+4.1c 10
--- /dev/null
+#print
+Does the neqn input
+ .EQ
+ a
+ over
+ b
+ .EN
+produce the same output as the input
+ .EQ
+ a over b
+ .EN
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match yes
+#log
+#next
+4.1d 10
+4.2c 5
--- /dev/null
+#once #create message
+.ND
+.LP
+You can put fractions over fractions with multiple "over"'s
+just as you can do multiple subscripts and superscripts,
+although fractions within fractions are much
+less common (probably because they are harder for
+people to read).
+Anyway, if you want, for example, something like
+.EQ
+a over b over c
+.EN
+you just type
+ .EQ
+ a over b over c
+ .EN
+
+As a drill, change "Example" so it produces an equation
+that looks like the following one, then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+x over x+x over x+x+x
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+right here
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+5.1a
--- /dev/null
+#once #create message
+.ND
+.LP
+Another practice one for using "over".
+Modify the file "Example" so it produces
+output that looks like this one, then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+a + b over c + d = e over f
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+replace me
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+4.1b 10
--- /dev/null
+#print
+Does the neqn input
+ .EQ
+ ~a
+ over
+ b~
+ .EN
+produce the same output as the input
+ .EQ
+ a~ over ~b
+ .EN
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match no
+#log
+#next
+4.1d 10
--- /dev/null
+#once #create message
+.ND
+.EQ
+delim $$
+.EN
+.LP
+So far we have carefuly skirted around a potential
+problem; maybe you've wondered about it.
+Suppose we want to produce an equation that looks
+like this:
+.EQ
+x sup { pi + 1 }
+.EN
+The superscript is complicated, in that it contains
+both a $pi$ and a +1, which has to be separated
+from the $pi$ by a blank.
+But I already told you that a blank terminates
+the superscript. What's going on?
+
+As the first step to finding out, will the input
+equation
+
+ x sup pi + 1
+
+produce the output
+
+ $x sup {pi + 1}$ ?
+Answer yes or no.
+(You can play with the file "Example" if you like.)
+.pl 1
+#once #create Example
+.LP
+.EQ
+replace me
+.EN
+.pl 1
+#
+#once neqn message | nroff -T$term %s/tinyms -
+#copyin
+#user
+#uncopyin
+#match no
+#log
+#next
+5.1b
--- /dev/null
+#once #create message
+.ND
+.EQ
+delim $$
+.EN
+.LP
+The problem is really that we need a way to tell neqn
+that in spite of blanks, a group of things (like the $pi$
+and the +1) have to be kept together as a single superscript.
+The way that this is done is to enclose the group in
+braces - the characters { and } - like this:
+
+ .EQ
+ x sup {pi + 1}
+ .EN
+
+This tells neqn that everything inside the braces belongs
+to the superscript, in spite of blanks and tildes.
+(You don't need blanks before and after braces themselves -
+like tildes, they act as delimiters.)
+
+Modify the file "Example" so that the output looks like
+the following, then type "ready".
+(To get $==$, type "==".)
+.pl 1
+#once #create Ref
+.LP
+.EQ
+x sup {pi +1} == y sup z sup {alpha + beta}
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+replace me
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+5.1c 10
+5.2b 5
--- /dev/null
+#once #create message
+.ND
+.EQ
+delim $$
+.EN
+.LP
+Braces are an exceedingly useful construction.
+Wherever you have a place where you could have used
+a single thing like the letter "x", you can plug in
+anything in braces, and the whole thing will
+be positioned properly. You can use braces with sub and sup
+and over, and all the other magic words we
+haven't seen yet.
+
+First let's use braces with "over".
+Modify "Example" to produce this output, then
+type "ready".
+(Recall that $partial$ is called "partial".)
+.pl 1
+#once #create Ref
+.LP
+.EQ
+{partial y} over {partial x} ~=~ alpha over {alpha +1}
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+replace me
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+5.1d 10
--- /dev/null
+#once #create message
+.ND
+.EQ
+delim $$
+.EN
+.LP
+You will get lots of practice
+using braces as we go along.
+One thing to keep in mind is that
+braces can appear ______\b\b\b\b\b\bwithin braces.
+(Remember that I said that anywhere you
+could use an "x" you could put something in
+braces instead. So to get this:
+.EQ
+e sup {x sup {pi +1} + y sup {pi +1}}
+.EN
+you can type
+
+ e sup {x sup {pi +1} + y sup {pi +1}}
+
+The big superscript (the one on the "e") has
+a pair of braces that take in everything.
+Then the "x" and the "y" each have braces
+to delimit their superscripts.
+Of course the braces have to go in the right
+places, or you won't get the output you
+want.
+
+To verify that you are still following this
+lesson, modify "Example" so it looks like
+this, then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+e sup { - {x sup {pi +1} + y sup {pi +1}} over 2}
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+e sup {x sup {pi +1} + y sup {pi +1}}
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#fail
+Don't forget that you need braces for the overall superscript,
+and also for the "over" part.
+#log
+#next
+5.1e 10
+5.2d 5
--- /dev/null
+#print
+Once you start using braces, there are a number of
+mistakes that you can make. For example, you can
+leave a brace out, or you can get them out of order
+(Like } xxx { ), or you can get them in illegal places.
+For all of these, neqn tells you "syntax error",
+then tries to say what file and line numbers are
+involved.
+The line numbers are often not exact, but
+they are very close. When you get such a message,
+print a line or two before and after the line
+numbers named in the syntax error message.
+
+The file "Example" contains a syntax error.
+What line does neqn believe it begins on?
+Type "answer N", where N is the line number.
+#once #create Example
+.LP
+.EQ 3
+e sup -x sup 2 + e sup -x sub i sup 2 + e sup{-x sub i}sup 2
+.EN
+.EQ 4
+ e sup{-{x sub i sup 2 + y sub i sup 2}over 2}
+= e sup{- x over y}
+.EN
+.EQ 5
+a over b = c over d = A over B times C over D
+.EN
+.EQ 8
+B sub a sub 2 +
+B sub a sup 2 +B{ sub a}sup 2 + (B sub a ) sup 2 + (B sup 2 ) sub a
++B sup 2 sup x
+.EN
+#copyin
+#user
+#uncopyin
+#match 13
+#log
+#next
+5.1f 10
--- /dev/null
+#print
+Is the construction
+ a {sup pi +1}
+legal in neqn? Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match no
+#log
+#next
+5.1g 10
--- /dev/null
+#print
+It is often possible to leave out braces,
+but when you do be sure that you get the
+answer you really wanted.
+For example, does
+ x sup a over b
+produce the same output as
+ x sup {a over b}
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match no
+#log
+#next
+5.1h 10
+5.2g 5
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+One thing that you will occasionally need
+is to be able to get a literal { or } in your
+output, for an expression like
+.EQ
+{ "{" a + b "}" } over 2
+.EN
+The way to do this is to place the braces
+that are really to appear ______\b\b\b\b\b\binside ______\b\b\b\b\b\bquotes,
+like this:
+ .EQ
+ { "{" a + b "}" } over 2
+ .EN
+.br
+The quotes temporarily turn off the special meaning
+of the braces so that you can have them printed.
+
+The file "Example" has a lot of square brackets in
+it. Modify them so they are all braces when they are
+printed - so they look like this - then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+f"{" x sub 1 ,..., x sub n "}" ~=~ "{" x sub 1 ,..., x sub n "}"
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+f[ x sub 1 ,..., x sub n ] ~=~ [ x sub 1 ,..., x sub n ]
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+6.1a 10
--- /dev/null
+#once #create message
+.ND
+.EQ
+delim $$
+.EN
+.LP
+Try another example with braces, for practice.
+Make the file "Example" produce output that looks
+like this line, then type "ready".
+(The character $rho$ is "rho".)
+.pl 1
+#once #create Ref
+.LP
+.EQ
+alpha sub i sup {pi + rho + 1} ~=~ 1
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+replace me
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+5.1c 10
--- /dev/null
+#once #create message
+.ND
+.EQ
+delim $$
+.EN
+.LP
+Modify "Example" so it produces this output, then
+type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+{partial e sup {-{x sup 2 + y sup 2} over 2}} over
+{partial x} ~=~ f(x)
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+xxxx
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+5.1e 10
--- /dev/null
+#print
+Does
+ x sup a over b
+produce the same output as
+ {x sup a} over b
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match yes
+#log
+#next
+5.1h 10
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+So far every equation you have typed in
+has been "displayed" - neatly centered or indented, and
+offset from the surrounding text.
+But not all equations are like that.
+Very often they appear right in the middle of
+running text as subscripts like $x sub i$ or special characters
+like $pi$ or $partial$. How are these done?
+
+The idea is this. Two characters (which may be identical)
+are set aside as "delimiters". When the
+left delimiter is seen anywhere in ___\b\b\bany line,
+it marks the beginning of an in-line equation.
+The end is marked by the right delimiter. Between the
+delimiters, all the normal rules of neqn apply.
+
+Suppose we say the delimiters are % signs.
+Then to get $pi$, you have to type %pi%.
+
+To make sure that you can do this much, find the
+$pi$, $alpha$ and $sum$ characters in "Example"
+and make them into in-line equations.
+Use % and % as the delimiter characters.
+(This is the most frequent choice, by the way.)
+Type "ready" when you're done.
+.pl 1
+#once #create Ref
+.EQ
+delim $$
+.EN
+.LP
+This line contains some $pi$ and $alpha$ Greek
+and $sum$ as well. Don't forget that spaces
+inside dollar signs are ignored, while spaces
+outside them are significant.
+.pl 1
+#once #create Example
+.EQ
+delim $$
+.EN
+.LP
+This line contains some pi and alpha Greek
+and sum as well. Don't forget that spaces
+inside dollar signs are ignored, while spaces
+outside them are significant.
+.pl 1
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+6.1b
--- /dev/null
+#print
+There is one other thing you have to do before
+you can use a character as a delimiter - you
+have to tell neqn that you are going to.
+To do this, as the very first thing in your
+input you must put these three lines:
+
+.EQ
+delim $$
+.EN
+
+(If you like, other characters than $ can be used,
+but we will stick to dollar signs here.)
+Until you do this, $ signs have no special
+significance to neqn.
+
+Modify the file "Example" by adding the "delim"
+lines to the beginning, and check that $ signs are
+now significant. Type "ready" when you are done.
+#once #create Ref
+.EQ
+delim $$
+.EN
+.LP
+Now is the $times$ for all good $mu$ $epsilon$ $nu$
+to come to the aid of their party.
+.pl 1
+#once #create Example
+.LP
+Now is the $times$ for all good $mu$ $epsilon$ $nu$
+to come to the aid of their party.
+.pl 1
+#user
+#cmp Ref example
+#log
+#next
+6.1c 10
--- /dev/null
+#print
+One thing to keep in mind is that outside of
+$ signs, spaces are significant just as they
+were before. Inside $ signs, spaces are significant
+only as delimiters, and will not add any space
+to the output.
+Furthermore, inside delimiters, new lines also
+don't matter, just as they didn't matter between
+the .EQ and .EN.
+
+Do the lines
+
+Let $alpha$ be the size of the vector $pi$.
+
+and
+
+Let $ alpha $ be the size of the vector $ pi $.
+
+produce the same output?
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match yes
+#log
+#next
+6.1d 10
--- /dev/null
+#print
+Do the inputs
+
+Let $x sub i$ and $y sub i$ be $>= z sub i$.
+
+and
+
+Let $x sub i$ and $y sub i$ be $>=$ $z sub i$.
+
+produce the same output?
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match no
+#log
+#next
+7.1a
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+The next construction we're going to look at
+is one for putting things above and below other
+things, in a rather specialized way.
+For example, if you want something like
+.EQ
+sum from i to j
+.EN
+you type
+ .EQ
+ sum from i to j
+ .EN
+The words "from" and "to" are more magic, like
+sub or sup or over. The "from" part is centered
+under the main piece; the "to" part is centered
+above it.
+As a warmup, modify "Example" so it produces
+output that looks like the following, then type
+ready.
+.pl 1
+#once #create Ref
+.EQ
+delim $$
+.EN
+.LP
+Let $Q( pi )$ be $sum from {i= pi sub 1} to {i= pi sub 2} x sub i$.
+.pl 1
+#once #create Example
+.EQ
+delim $$
+.EN
+.LP
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+7.1b 10
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+As you might expect from our previous discussions,
+any part of a
+
+ thing from thing to thing
+
+construction can be as complicated as you wish.
+The only limitation is that the individual "thing"'s
+may well need braces around them to make it
+clear to neqn which part goes with which.
+
+For example, suppose you want
+.EQ
+sum from {pi = 0} to {pi = n}
+.EN
+Then you have to ensure that the $pi =0$ and
+$pi =n$ parts are included in braces or
+they will not work right.
+
+Modify file "Example" so the output looks like
+the example above, then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+sum from {pi = 0} to {pi =n}
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+sum from pi = 0 to pi = n
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+7.1c 10
+7.2b 5
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+It is also quite permissible to leave out
+either the "from" part or the "to" part
+of a from-to construction. For example,
+modify "Example" so its output looks like this,
+then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+lim from {x-> pi /2} ( tan~x) sup {sin~2x}~=~1
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+lim from xxx ( tan~x) sup {sin~2x}~=~1
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+7.1d 10
+7.2c 5
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+Let's do one more example of from-to for practice
+before we go on to the next topic.
+Modify "Example" so it produces output that looks
+like this, then type "ready".
+.pl 1
+#once #create Ref
+.EQ
+delim $$
+.EN
+.LP
+Let $Q( pi )$ be $sum from {i= pi sub 1} to {i= pi sub 2} x sub i$.
+.pl 1
+#once #create Example
+.EQ
+delim $$
+.EN
+.LP
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#fail
+Don't forget to set delimiters before the .LP line,
+and get the spaces right around the dollar signs.
+#log
+#next
+8.1a 10
--- /dev/null
+#print
+Does the input
+
+ sum from {i = -n} to {i = +n}
+
+produce the same output as the input
+
+ sum from i=-n to i=+n
+
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match yes
+#log
+#next
+7.1c
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+Modify file "Example" so it looks like this,
+then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+sum to N+n-m x sub mn > 0
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+xxx
+.EN
+.pl 1
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+7.1d 10
--- /dev/null
+#once #create message
+.ND
+.LP
+The next neqn operation is called "sqrt" - it makes
+square root signs over things, like this:
+.EQ
+sqrt a+b
+.EN
+(They don't look very good on a terminal, unfortunately.)
+This one is very easy - to print the line above, you
+say
+ .EQ
+ sqrt a+b
+ .EN
+The "sqrt" operates on the first thing it finds
+so if you want something more complicated, like
+.EQ
+sqrt {pi +1}
+.EN
+you have to use braces to enclose the entire
+thing. This one was printed with
+ .EQ
+ sqrt {pi +1}
+ .EN
+And that's all there is to sqrt.
+
+Modify "Example" so it looks like this, then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+f(x) ~=~ sqrt {ax sup 2 +bx+c}
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+f(x)....
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+8.1b 10
--- /dev/null
+#once #create message
+.ND
+.LP
+Since "sqrt thing" is really a single object, you
+often don't need braces around it, although there
+may well be braces around "thing" itself.
+For example, you can say
+ .EQ
+ 1 over sqrt {ax sup2 +bx+c}
+ .EN
+to produce
+.EQ
+1 over sqrt {ax sup 2 +bx+c}
+.EN
+Does the input
+ .EQ
+ e sup sqrt {pi x}
+ .EN
+produce the same output as
+ .EQ
+ e sup {sqrt {pi x}}
+ .EN
+Answer yes or no.
+.pl 1
+#
+#once neqn message | nroff -T$term %s/tinyms -
+#copyin
+#user
+#uncopyin
+#match yes
+#log
+#next
+9.1a 10
+8.2b 5
--- /dev/null
+#print
+Does the input
+ .EQ
+ e sup sqrt {pi x}
+ .EN
+produce the same output as
+ .EQ
+ e sup sqrt pi x
+ .EN
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match no
+#log
+#next
+9.1a 10
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+The next step is to learn about "diacriticals", which
+is a big word for funny marks on symbols, like
+a bar over something ($x bar$), or a tilde or hat on
+something ($x tilde ,~a hat$), or perhaps a dot
+or dotdot ($T dot ,~U dotdot$), or even an
+underlining like $abc under$.
+
+These are all easy. Each funny character
+has a name, and all you have to do is put the name
+after the thing you want the character on.
+Thus
+ x hat makes $x hat$
+ y bar makes $y bar$
+ T dot makes $T dot$
+ x tilde makes $x tilde$ (notice that we spell tilde)
+ u dotdot makes $u dotdot$ (looks ugly on a terminal)
+.br
+and
+ i under makes $i under$.
+
+Except for "bar" and "under", these are almost always
+attached to just a single letter.
+If you want to put a bar over something longer, like
+${2 pi +1} bar$, simply enclose the thing in braces:
+
+ {2 pi +1} bar
+
+Modify "Example" to produce output that looks like this,
+then type "ready".
+.pl 1
+#once #create Ref
+.EQ
+delim $$
+.EN
+.LP
+Let $x bar$, $y bar$, and $z bar$ be the components of $pi bar$.
+Let ${alpha +1} bar$ be the mean value of $alpha hat$.
+.pl 1
+#once #create Example
+.EQ
+delim $$
+.EN
+.LP
+Let x bar, y bar, and z bar be the components of pi bar.
+Let alpha +1 bar be the mean value of alpha hat.
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#fail
+Don't forget to set delimiters at the beginning,
+and get the spaces right around the dollar signs.
+#log
+#next
+9.1b 10
+9.2a 5
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+You sometimes have to make explicit what you
+mean when you say "bar", by putting in braces
+to enclose the parts that you want the bar
+to be over.
+For example, what has to be done to make
+the output
+.EQ
+{x sub i} bar
+.EN
+Find out (by putting braces in the right place
+if necessary) in the file "Example", then
+type "ready" after you have successfully modified it.
+.pl 1
+#once #create Ref
+.EQ
+delim $$
+.EN
+.LP
+.EQ
+{x sub i} bar
+.EN
+.pl 1
+#once #create Example
+.EQ
+delim $$
+.EN
+.LP
+.EQ
+x sub i bar
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+10.1a 10
+9.2b 5
--- /dev/null
+#once #create message
+.ND
+.tr %$
+.EQ
+delim $$
+.EN
+.LP
+Modify "Example" to produce output that looks like this,
+then type "ready".
+.pl 1
+#once #create Ref
+.LP
+.EQ
+x bar ~=~ E(x) bar ~/~ E( x bar )
+.EN
+.pl 1
+#once #create Example
+.LP
+.EQ
+xxxx
+.EN
+.pl 1
+#
+#once neqn Ref | nroff >X1 &
+#once neqn message Ref | nroff -T$term %s/tinyms -
+#user
+neqn Example | nroff >X2
+#cmp X1 X2
+#log
+#next
+9.1b 10
--- /dev/null
+#print
+Which equation prints a longer bar?
+
+ xyz sub i bar
+
+or
+
+ x yz sub i bar
+
+Type "answer N", where N is 1 if it's
+the first one, 2 if it's the second, and
+0 if they are the same length.
+#copyin
+#user
+#uncopyin
+#match 0
+#log
+#next
+10.1a 10
+9.3b 5
--- /dev/null
+#print
+Does
+ ax bar
+produce the same output as
+ a x bar
+Answer yes or no.
+#copyin
+#user
+#uncopyin
+#match no
+#log
+#next
+10.1a 10
--- /dev/null
+.\" short set of macros to simulate behavior of
+.\" most common -ms macros:
+.\" .PP, .LP, .EQ, .EN
+.\"
+.de PP
+.br
+.sp
+.ll 60n
+.fi
+.ti +5n
+..
+.de LP
+.br
+.sp
+.ll 60n
+.fi
+..
+.de EQ
+.sp
+.ce
+..
+.de EN
+.sp
+..