| 1 | """ |
|---|
| 2 | Knuth's TPK program in Cobra |
|---|
| 3 | |
|---|
| 4 | From http://en.wikipedia.org/wiki/Trabb_Pardo-Knuth_algorithm |
|---|
| 5 | |
|---|
| 6 | "In their 1977 work "The Early Development of Programming Languages", Trabb Pardo |
|---|
| 7 | and Knuth introduced a trivial program which involved arrays, indexing, |
|---|
| 8 | mathematical functions, subroutines, I/O, conditionals and iteration. They then |
|---|
| 9 | wrote implementations of the algorithm in several early programming languages to |
|---|
| 10 | show how such concepts were expressed." |
|---|
| 11 | |
|---|
| 12 | While this is useful for demonstrating a few basic things about a language, it |
|---|
| 13 | does not demonstrate well the features surrounding larger issues such as |
|---|
| 14 | organizing large code bases, working on a team, documenting your code, etc. |
|---|
| 15 | Also, the standard TPK code mixes input, computations and output all together. |
|---|
| 16 | It also directly references stdin and hard codes constants rather than taking |
|---|
| 17 | parameters for those things. |
|---|
| 18 | |
|---|
| 19 | But some people still like to see this code to compare it to other languages. |
|---|
| 20 | So here it is, including a better version that addresses some of the above issues. |
|---|
| 21 | """ |
|---|
| 22 | |
|---|
| 23 | class TPK |
|---|
| 24 | |
|---|
| 25 | shared |
|---|
| 26 | |
|---|
| 27 | def f(x as number) as number |
|---|
| 28 | return x.abs.sqrt + 5.0 * x.pow(3.0) |
|---|
| 29 | |
|---|
| 30 | def basicTPK1 |
|---|
| 31 | a = number[](11) |
|---|
| 32 | |
|---|
| 33 | # read in the values for the array, one per line |
|---|
| 34 | for i in a.length |
|---|
| 35 | a[i] = number.parse(Console.readLine) |
|---|
| 36 | |
|---|
| 37 | # in reverse order, apply "f" to each element of the array and |
|---|
| 38 | # print the result, including index |
|---|
| 39 | for i in a.length-1 : 0 : -1 |
|---|
| 40 | y = .f(a[i]) |
|---|
| 41 | print '[i] ', if(y>400, 'TOO LARGE', y) |
|---|
| 42 | |
|---|
| 43 | def basicTPK2 |
|---|
| 44 | # some versions in other languages print the input number |
|---|
| 45 | # rather than its index |
|---|
| 46 | a = number[](11) |
|---|
| 47 | for i in a.length |
|---|
| 48 | a[i] = number.parse(Console.readLine) |
|---|
| 49 | Array.reverse(a) |
|---|
| 50 | for x in a |
|---|
| 51 | y = .f(x) |
|---|
| 52 | print '[x] ', if(y>400, 'TOO LARGE', y) |
|---|
| 53 | |
|---|
| 54 | def betterTPK |
|---|
| 55 | """ |
|---|
| 56 | Invokec .betterTPK with default arguments: Console.in, 11 and 400. |
|---|
| 57 | """ |
|---|
| 58 | .betterTPK(Console.in to !, 11, 400) |
|---|
| 59 | |
|---|
| 60 | def betterTPK(tr as TextReader, count as int, limit as number) |
|---|
| 61 | require |
|---|
| 62 | count > 0 |
|---|
| 63 | ensure |
|---|
| 64 | # Well there's not much to ensure for a method that dumps its |
|---|
| 65 | # results as textual output. An even better approach is to |
|---|
| 66 | # separate computation from I/O so that computations can be |
|---|
| 67 | # more easily tested, contracted and reused. |
|---|
| 68 | true |
|---|
| 69 | test |
|---|
| 70 | # Now that we're using parameters, we can make a proper test. |
|---|
| 71 | sw = StringWriter() |
|---|
| 72 | print to sw |
|---|
| 73 | .betterTPK(StringReader('1\r\n1\r\n'), 2, 400) |
|---|
| 74 | r = sw.toString.replace('\r','').replace('\n','; ') |
|---|
| 75 | assert r == '1 6.0; 1 6.0; ' |
|---|
| 76 | body |
|---|
| 77 | a = number[](count) |
|---|
| 78 | for i in a.length |
|---|
| 79 | a[i] = number.parse(tr.readLine) |
|---|
| 80 | Array.reverse(a) |
|---|
| 81 | for x in a |
|---|
| 82 | y = .f(x) |
|---|
| 83 | print '[x] ', if(y>limit, 'TOO LARGE', y) |
|---|
| 84 | |
|---|
| 85 | def main |
|---|
| 86 | if false |
|---|
| 87 | print |
|---|
| 88 | print 'Basic TPK - Enter numbers:' |
|---|
| 89 | .basicTPK1 |
|---|
| 90 | if true |
|---|
| 91 | print |
|---|
| 92 | print 'Better TPK - Enter numbers:' |
|---|
| 93 | .betterTPK |
|---|