-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathJavaExercises.nb
9254 lines (8866 loc) · 388 KB
/
JavaExercises.nb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
(* Content-type: application/vnd.wolfram.mathematica *)
(*** Wolfram Notebook File ***)
(* http://www.wolfram.com/nb *)
(* CreatedBy='Mathematica 10.0' *)
(*CacheID: 234*)
(* Internal cache information:
NotebookFileLineBreakTest
NotebookFileLineBreakTest
NotebookDataPosition[ 158, 7]
NotebookDataLength[ 396883, 9245]
NotebookOptionsPosition[ 386148, 8917]
NotebookOutlinePosition[ 386860, 8942]
CellTagsIndexPosition[ 386817, 8939]
WindowFrame->Normal*)
(* Beginning of Notebook Content *)
Notebook[{
Cell[CellGroupData[{
Cell[BoxData["Today"], "Input",
CellChangeTimes->{{3.73279634913824*^9, 3.732796351862769*^9},
3.732800493320031*^9, {3.733048870739476*^9, 3.733048877267962*^9}, {
3.733269864488125*^9, 3.73326986576749*^9}, {3.733270990938971*^9,
3.733270991318811*^9}}],
Cell[BoxData[
TemplateBox[{RowBox[{"\"Sat 21 Apr 2018\""}],RowBox[{"DateObject", "[",
RowBox[{"{",
RowBox[{"2018", ",", "4", ",", "21"}], "}"}], "]"}]},
"DateObject",
Editable->False]], "Output",
CellChangeTimes->{
3.7327963524456987`*^9, 3.7327988146073503`*^9, 3.732800496874042*^9,
3.732801372125017*^9, 3.732823456956298*^9, 3.7329704256210613`*^9,
3.733048877735165*^9, 3.733050796302861*^9, 3.7330512148570766`*^9,
3.7330577948371572`*^9, 3.73306577680892*^9, 3.733073981551526*^9,
3.733074149010796*^9, 3.7330799624885187`*^9, 3.733125359554858*^9,
3.7331282284863567`*^9, 3.733133300114868*^9, 3.7332108372466917`*^9,
3.733211535417728*^9, 3.7332125525177917`*^9, 3.733212752415169*^9, {
3.733212822324748*^9, 3.733212848177206*^9}, 3.7332159636484222`*^9,
3.733216118586319*^9, 3.7332217374188557`*^9, 3.733221796739285*^9,
3.733269886381727*^9, 3.733277690053195*^9}]
}, Open ]],
Cell[CellGroupData[{
Cell[TextData[{
StyleBox["Solving all lab exercises of an Introductory Java course with ",
FontSize->36],
StyleBox["Mathematica",
FontSize->36,
FontSlant->"Italic"],
" "
}], "Title",
CellChangeTimes->{{3.7327963739455347`*^9, 3.732796402168004*^9}, {
3.7327984592813587`*^9, 3.7327984659055033`*^9}, {3.732971174845151*^9,
3.732971175181555*^9}, {3.733040541201063*^9, 3.733040561485742*^9},
3.733270101690648*^9},
FontSize->14],
Cell[TextData[{
StyleBox["Ilkka Kokkarinen",
FontSlant->"Italic"],
", ",
StyleBox["[email protected]",
FontFamily->"Courier New"],
"\n\n",
StyleBox["Introduction", "Chapter"],
"\n\nThe author has taught an introductory Java course ",
ButtonBox["CCPS 109 Computer Science I",
BaseStyle->"Hyperlink",
ButtonData->{
URL["https://docs.google.com/document/d/1JTbx-Nm16GNwTxHnujq4APC_gztz-\
VgqJTVu4jkx4M0/edit?usp=sharing"], None},
ButtonNote->
"https://docs.google.com/document/d/1JTbx-Nm16GNwTxHnujq4APC_gztz-\
VgqJTVu4jkx4M0/edit?usp=sharing"],
" at the Ryerson Chang School continuously for the past sixteen years, \
basically developing all his own material along the way. Over this time span, \
the Java language itself has evolved tremendously, from the introduction of \
",
StyleBox["generics",
FontSlant->"Italic"],
" in Java 5 to the move towards more functional programming spirit with \
techniques such as ",
StyleBox["computation streams",
FontSlant->"Italic"],
" and ",
StyleBox["lambdas",
FontSlant->"Italic"],
" in Java 8. As this course nears the end of its lifetime, as the department \
has chosen to follow the universal trend of switching the introductory \
programming course to Python, a move enthusiastically 100% endorsed by this \
author, it is time to take this idea one step further. This document was \
inspired from the question of how difficult it would be to solve ",
ButtonBox["the instructor\[CloseCurlyQuote]s current set of ten weekly labs",
BaseStyle->"Hyperlink",
ButtonData->{
URL["https://docs.google.com/document/d/1l9IeT9brVc1Hwbip5rpTNEvIje3rfet_\
j37DgoVUyUI/edit?usp=sharing"], None},
ButtonNote->
"https://docs.google.com/document/d/1l9IeT9brVc1Hwbip5rpTNEvIje3rfet_\
j37DgoVUyUI/edit?usp=sharing"],
", each lab consisting of four method writing problems, using ",
StyleBox["Mathematica ",
FontSlant->"Italic"],
"instead of Java",
StyleBox[". ",
FontSlant->"Italic"],
"Along the way, we see what these exercises, originally designed to teach \
the imperative programming thinking of Java to rank beginners, can teach us \
about the fundamental similarities and differences between these two \
languages.\nOver these sixteen years, these weekly labs and their exercises \
also evolved significantly. Usually after each semester, some poorly \
performing and uninteresting lab problem was replaced by some sparkly new \
problem. Over time, most of the lab problems eventually fell on the wayside, \
and of course, a couple of lofty ideas with high hopes turned out to be utter \
failures with students and were quickly replaced by something that turned out \
to work better in practice. Pretty much all the remaining problems that have \
survived this gauntlet of unnatural selection really do have some important \
and educational point in them that justifies their existence. None of the \
problems is there as some make-work drudgery to fill that week\
\[CloseCurlyQuote]s mandatory work quota.\nThe target audience of this \
document is mainly intended to be motivated students of all ages who have \
taken the first year or two of computer science so that they know the basics \
of imperative programming and the object oriented thinking and style, and who \
are curious about functional programming languages and their different, often \
more concise style of thinking and problem solving. Many students gain such \
motivation after taking the author\[CloseCurlyQuote]s second course of \
programming where they get to try their hands on Java 8 computation streams \
to learn what a handy way they are to solve many problems in a way that is \
completely different from the usual way of solving problems with loops. \
(Streams also have the additional advantage of being naturally ",
StyleBox["parallelizable",
FontSlant->"Italic"],
" without any extra effort from the part of the programmer, leading to an \
interesting class dicussion in the second programming course about that topic \
and other advantages of expressing computations in functional style.)\n\
Traditionally, the imperative and functional programming languages have been \
taught to form a strict duality of opposites that shall never meet. But \
surely it would be more accurate to say that these paradigms form a continuum \
on which almost all programming languages then fall depending on to what \
extent they allow functions and code to be treated and manipulated as \
first-class citizens of that language. Since the Nineties, languages from \
both the C family tree and the scripting language paradigm have steadfastly \
inched towards the functional programming end of this continuum, not trying \
to reach all the way to the very end but aiming towards that unknown sweet \
spot that would be the perfect compromise of clarity and power for working \
programmers to solve actual problems. The examples implemented in this \
document teach such people how to take the ideas that they would normally \
implement with loops and mutable arrays, and express these same ideas in \
functional programming form.\nFor this level of beginning programmer, the \
material that teaches functional programming available online is rather \
lacking, compared to the torrent of material readily available for every \
imperative and object oriented programming language. Most of such material is \
just far too simplistic so that it does not explain how to actually ",
StyleBox["do",
FontSlant->"Italic"],
" anything using a functional programming approach. The other alternative \
is that the material is way too high level so that you would basically need \
to already be a computer science Ph.D. to even begin to read it, written for \
people who write compilers and interpreters for fun and who do their thinking \
in category theory while juggling monads the way us boring normos write loops \
and conditions. This document aims to fill in this gap with at least a little \
bit of, if you pardon the pun, ",
StyleBox["concrete",
FontSlant->"Italic"],
". Solving these 42 problems will give the reader a grand tour of pretty \
much all of the important functions and techniques that make up the ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" core language, so this document works as a practical introduction to ",
StyleBox["Mathematica",
FontSlant->"Italic"],
".\nThe secondary audience of this article are other computer science \
instructors looking for inspiration for lab exercises either in the \
imperative or functional programming spirit, or who would just simply enjoy \
an \[OpenCurlyDoubleQuote]over the shoulder\[CloseCurlyDoubleQuote] read \
about the overall thought process that goes into the design of an \
introductory programming course and its individual labs.\n\n",
StyleBox["Lab One: Classes and objects", "Chapter"],
"\nThe most fundamental difference between Java and ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" is the forced program structure of classes and methods of the former, \
versus the functional and pattern matching programming style of the latter. \
This first lab of the Java course, intended to familiarize the student with \
the concepts of classes and objects (no main method is needed at this point, \
because the course uses the BlueJ environment that allows Java classes and \
objects to be manipulated with an interactive graphical GUI to try them out), \
asks the student to define a simple ",
StyleBox["Rectangle",
FontWeight->"Bold"],
" class whose instances have an individual ",
StyleBox["width",
FontWeight->"Bold"],
" and ",
StyleBox["height",
FontWeight->"Bold"],
", from which the derived virtual properties of ",
StyleBox["area",
FontWeight->"Bold"],
" and ",
StyleBox["perimeter",
FontWeight->"Bold"],
" can then be computed.\n",
StyleBox["Mathematica",
FontSlant->"Italic"],
" already contains all our familiar and unfamiliar geometric shapes as first \
class citizens of the symbolics language, so that the mathematical pattern \
matching engine can compute their arbitrary properties and transformations. \
But let us ignore those for the moment, and solve this problem using the \
basic pattern matching operations of ",
StyleBox["Mathematica",
FontSlant->"Italic"],
". Since everything in ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" is an expression for which we can define arbitrary transformation rules of \
our own choosing, a rectangle can be encoded as an expression of the form ",
StyleBox["rectangle(width, height)",
FontWeight->"Bold"],
" for which we define appropriate substitution rules. Of course, \
\[OpenCurlyDoubleQuote]rectangle\[CloseCurlyDoubleQuote], \
\[OpenCurlyDoubleQuote]width\[CloseCurlyDoubleQuote] and \
\[OpenCurlyDoubleQuote]height\[CloseCurlyDoubleQuote] are just names that \
mean nothing to the computer. But when naming things, it is important to give \
them names that ring the correct bell inside the human reader\
\[CloseCurlyQuote]s brain and allow him to make reasonable inferences based \
on the semantic associations of those names. (On the other hand, we should \
not fall into the famous fallacy of artificial intelligence and hallucinate \
that our chosen names themselves have magical properties that somehow have \
the power to affect the operation of that program, so that a program that \
encodes a triple ",
StyleBox["(is, love, emotion)",
FontWeight->"Bold"],
" would be somehow different from an identical program that encodes a triple \
",
StyleBox["(x98, foo\[Pi]bar, QQQ)",
FontWeight->"Bold"],
". Any program will still work exactly the same after you consistently \
renamed all its identifiers throughout that program.)"
}], "Text",
CellChangeTimes->{{3.7327964204649563`*^9, 3.73279675484359*^9}, {
3.732796935834816*^9, 3.732797072087311*^9}, {3.732797109642292*^9,
3.732797415995082*^9}, {3.732797514512808*^9, 3.732797622096161*^9}, {
3.732797713062183*^9, 3.7327977919331007`*^9}, {3.73279791414694*^9,
3.732797917865099*^9}, {3.7327987728860273`*^9, 3.732798787470323*^9}, {
3.732971087322248*^9, 3.732971141631958*^9}, {3.732971182398868*^9,
3.7329717152161093`*^9}, {3.732971765706108*^9, 3.73297177312733*^9}, {
3.733043418159894*^9, 3.73304373365084*^9}, {3.733047092598217*^9,
3.733047117312434*^9}, {3.7330488995812893`*^9, 3.733048949225789*^9}, {
3.733048980407762*^9, 3.733049226069482*^9}, {3.733049752650333*^9,
3.733049987537429*^9}, 3.733058352852895*^9, {3.733071437507064*^9,
3.7330716823649387`*^9}, {3.733123899266214*^9, 3.733124098316934*^9}, {
3.7331248328808117`*^9, 3.733124911849532*^9}, {3.733125707991702*^9,
3.73312570941538*^9}, {3.733126754483507*^9, 3.7331270019585*^9}, {
3.733127066674748*^9, 3.733127078806126*^9}, {3.733127114162244*^9,
3.733127332065813*^9}, {3.733212764659501*^9, 3.733212788412902*^9}, {
3.73321698187635*^9, 3.733217176833932*^9}, {3.733217287874159*^9,
3.733217507538066*^9}, {3.733217551135755*^9, 3.733217606742793*^9}, {
3.7332217157394133`*^9, 3.7332217171192636`*^9}, {3.7332227147457113`*^9,
3.733222777237756*^9}, {3.733250604648847*^9, 3.733250607239285*^9}, {
3.733251134751848*^9, 3.733251153438324*^9}, {3.73326990546765*^9,
3.7332699060519342`*^9}, 3.733270286431634*^9, {3.7332710399636393`*^9,
3.733271063059705*^9}},
TextJustification->1.,
FontSize->14],
Cell[BoxData[{
RowBox[{
RowBox[{
RowBox[{"width", "[",
RowBox[{"rectangle", "[",
RowBox[{"w_", ",", "h_"}], "]"}], "]"}], " ", ":=", " ", "w"}],
";"}], "\[IndentingNewLine]",
RowBox[{
RowBox[{
RowBox[{"height", "[",
RowBox[{"rectangle", "[",
RowBox[{"w_", ",", "h_"}], "]"}], "]"}], " ", ":=", " ", "h"}],
";"}], "\[IndentingNewLine]",
RowBox[{
RowBox[{
RowBox[{"area", "[",
RowBox[{"rectangle", "[",
RowBox[{"w_", ",", "h_"}], "]"}], "]"}], " ", ":=", " ",
RowBox[{"w", " ", "*", " ", "h"}]}], ";"}], "\[IndentingNewLine]",
RowBox[{
RowBox[{
RowBox[{"perimeter", "[",
RowBox[{"rectangle", "[",
RowBox[{"w_", ",", "h_"}], "]"}], "]"}], " ", ":=", " ",
RowBox[{"2",
RowBox[{"(",
RowBox[{"w", " ", "+", " ", "h"}], ")"}]}]}],
";"}], "\[IndentingNewLine]",
RowBox[{
RowBox[{
RowBox[{"flip", "[",
RowBox[{"rectangle", "[",
RowBox[{"w_", ",", "h_"}], "]"}], "]"}], " ", ":=", " ",
RowBox[{"rectangle", "[",
RowBox[{"h", ",", "w"}], "]"}]}], ";"}]}], "Input",
CellChangeTimes->{{3.732797400562686*^9, 3.732797430273752*^9}, {
3.7327974658090467`*^9, 3.7327974737148743`*^9}, {3.732797567304819*^9,
3.732797580296527*^9}, {3.7327976283738737`*^9, 3.732797727596902*^9}, {
3.732797800483687*^9, 3.732797823355256*^9}, 3.73279794608652*^9, {
3.732798790508864*^9, 3.732798808965816*^9}},
FontSize->14],
Cell[TextData[{
"These five definitions provide the functionality required in the first lab. \
Each of the ten labs of the course comes with a ",
StyleBox["JUnit tester class",
FontSlant->"Italic"],
" that separately tests each of the four methods required in that lab. To \
guarantee the appropriate test coverage, the tester for each method generates \
a large number of random inputs that are individually given to the method \
currently under testing, and calculates the Adler-32 checksum of the answers \
returned by the method implementation. (Using some cryptographically stronger \
but slower checksum would be pointless, since any student able to crack the \
current scheme would still get off easier simply by honestly writing the \
specified methods as asked.) This checksum is then compared to the checksum \
that was produced by the instructor\[CloseCurlyQuote]s private model \
solution, hardcoded inside the JUnit tester. If these two checksums agree, \
the student gets the green checkmark in the BlueJ tester interface and 0.5 \
marks added towards his or her total course grade, these ten labs together \
accounting for 20 marks of the total course grade of 100.\nThe Java language \
guarantees that all possible computations done using the four primitive \
integer types ",
StyleBox["byte",
FontWeight->"Bold"],
", ",
StyleBox["short",
FontWeight->"Bold"],
", ",
StyleBox["int",
FontWeight->"Bold"],
" and ",
StyleBox["long",
FontWeight->"Bold"],
" will yield the exact same results in all environments. Since the Java \
standard random number generator class ",
StyleBox["java.util.Random",
FontWeight->"Bold"],
" is also similarly guaranteed to always and everywhere produce the exact \
same random number stream from the same fixed seed that is hardcoded in the \
JUnit testers, this approach of testing student code submissions makes \
reaching good test coverage quite easy for instructors. This scheme works \
better also for the students who, while working on the lab problems usually \
at home at whatever time of the week is convenient for them, especially in \
the case of adult students who have actual real lives and corresponding adult \
life responsibilities rather than the ",
StyleBox["wandervogel",
FontSlant->"Italic"],
" freedom to slouch your behind into the computer lab (which, not unlike the \
Java language itself, are just another silly relic from a simpler and poorer \
time when computing power was not as cheap and ubiquitous as it is today) \
every Friday night, instantly knowing if their method works or not by one \
mouse click of the green JUnit tester class. Since each lab solution is \
submitted as a complete BlueJ project folder that includes that JUnit tester, \
the instructor can also verify and grade the submission in literally ten \
seconds flat with just a couple of mouse clicks, instead of having to pore \
through the code and reason whether some particularly novel construction that \
is different from the instructor\[CloseCurlyQuote]s own model solution would \
produce some off-by-one error in some corner case. This is why we have \
machines in the first place, to do this tedious work for us. \nOne big \
downside of this randomized testing is that this process cannot tell the \
student which particular test cases and how many of them the code failed. The \
",
StyleBox["CodingBat",
FontSlant->"Italic"],
" interactive Java training website, also used in this course to drill in \
the Java syntax and thinking, is much better in this sense that its \
submission process makes the particular failed tests explicit to help the \
student reason about the exact nature of the bug in his code. This can be \
ameliorated slightly by having the tester to also compute additional \
information about the answers returned method, such as the total number of ",
StyleBox["true",
FontWeight->"Bold"],
" answers over the test cases when testing some classifier method. If this \
number differs from the expected result, the fact of whether this count is \
too high (false positives) or too low (false negatives) guides the student in \
reasoning and finding the bug. However, in place of a larger programming \
project, the instructor prefers to serve his students CodingBat for \
breakfast, lunch and dinner, to really drill in the language syntax and the \
process of solving problems with the language.\nIn ",
StyleBox["Mathematica",
FontSlant->"Italic"],
", the same way as in symbolic mathematics in general, we are content to \
observe that our definitions are mathematically correct. We can still quickly \
try them out by hand as a simple sanity check, of course."
}], "Text",
CellChangeTimes->{{3.732797952065847*^9, 3.73279845253925*^9}, {
3.732798502954035*^9, 3.732798623169012*^9}, {3.7327986545678864`*^9,
3.7327986589201717`*^9}, {3.732798760446876*^9, 3.732798761940493*^9}, {
3.732799027866582*^9, 3.732799172078607*^9}, {3.732799282197022*^9,
3.732799342268371*^9}, {3.7329718009093733`*^9, 3.732971802269824*^9}, {
3.733050032989768*^9, 3.7330500347106667`*^9}, {3.7330716941939497`*^9,
3.733072070570993*^9}, {3.733217182188315*^9, 3.733217275587124*^9}, {
3.733219306771763*^9, 3.733219492855632*^9}, {3.733250614927743*^9,
3.73325076225074*^9}},
TextJustification->1.,
FontSize->14],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{"{",
RowBox[{
RowBox[{"height", "[",
RowBox[{"flip", "[",
RowBox[{"rectangle", "[",
RowBox[{"3", ",", "6"}], "]"}], "]"}], "]"}], ",",
RowBox[{"area", "[",
RowBox[{"rectangle", "[",
RowBox[{"4", ",", " ", "5"}], "]"}], "]"}], ",",
RowBox[{"perimeter", "[",
RowBox[{"rectangle", "[",
RowBox[{"10", ",", "20"}], "]"}], "]"}]}], "}"}]], "Input",
CellChangeTimes->{{3.732797400562686*^9, 3.732797430273752*^9}, {
3.7327974658090467`*^9, 3.7327974737148743`*^9}, {3.732797567304819*^9,
3.732797580296527*^9}, {3.7327976283738737`*^9, 3.732797727596902*^9}, {
3.732797800483687*^9, 3.732797823355256*^9}, 3.73279794608652*^9, {
3.732798629758914*^9, 3.732798647870905*^9}},
FontSize->14],
Cell[BoxData[
RowBox[{"{",
RowBox[{"3", ",", "20", ",", "60"}], "}"}]], "Output",
CellChangeTimes->{{3.732797466116315*^9, 3.7327974709877043`*^9},
3.7327978255894613`*^9, 3.732798648486508*^9, 3.732798814706311*^9,
3.7328004969658318`*^9, 3.732801372265132*^9, 3.732823457173131*^9,
3.732970425853854*^9, 3.733050796544178*^9, 3.733051215067272*^9,
3.7330577950601797`*^9, 3.733065777042532*^9, 3.733073981800529*^9,
3.7330741492983913`*^9, 3.733079962745092*^9, 3.733125359765689*^9,
3.733128228731277*^9, 3.733133300333075*^9, 3.733210837679652*^9,
3.7332115355936947`*^9, 3.733212552663126*^9, 3.733212752570581*^9, {
3.7332128224621363`*^9, 3.733212848330276*^9}, 3.7332159638603*^9,
3.733216118739868*^9, 3.733221737609026*^9, 3.733221796952072*^9,
3.7332698866759567`*^9, 3.7332776901908503`*^9},
FontSize->14]
}, Open ]],
Cell["\<\
We can also define pattern matching rules for decisions that were not part of \
this first lab, since the Java if-else statement has not been taught at this \
point of the course.\
\>", "Text",
CellChangeTimes->{{3.732797482073166*^9, 3.732797502681439*^9}, {
3.732797853963399*^9, 3.732797910721717*^9}, {3.7327984726114283`*^9,
3.732798497937146*^9}, {3.732798702136331*^9, 3.732798749381544*^9}, {
3.732798868609207*^9, 3.73279897116788*^9}, {3.7327991783807096`*^9,
3.7327992713398237`*^9}, {3.73279934490631*^9, 3.732799376056983*^9}, {
3.732799427082857*^9, 3.73279946777708*^9}, {3.732800359178419*^9,
3.73280035936281*^9}, {3.732971818852201*^9, 3.732971949011118*^9}, {
3.733040608597472*^9, 3.7330406602608957`*^9}, {3.7330500115638*^9,
3.733050021468852*^9}, {3.733072082400552*^9, 3.733072087386346*^9}, {
3.733271342800768*^9, 3.733271343213872*^9}},
TextJustification->1.,
FontSize->14],
Cell[CellGroupData[{
Cell[BoxData[{
RowBox[{
RowBox[{
RowBox[{"isSquare", "[",
RowBox[{"rectangle", "[",
RowBox[{"x_", ",", "x_"}], "]"}], "]"}], " ", ":=", " ", "True"}],
";"}], "\[IndentingNewLine]",
RowBox[{
RowBox[{
RowBox[{
RowBox[{"isSquare", "[", "_", "]"}], " ", ":=", " ", "False"}], ";"}],
"\[IndentingNewLine]"}], "\[IndentingNewLine]",
RowBox[{"{",
RowBox[{
RowBox[{"isSquare", "[",
RowBox[{"rectangle", "[",
RowBox[{"4", ",", "4"}], "]"}], "]"}], ",", " ",
RowBox[{"isSquare", "[",
RowBox[{"rectangle", "[",
RowBox[{"3", ",", "8"}], "]"}], "]"}]}], "}"}]}], "Input",
CellChangeTimes->{{3.733040674501939*^9, 3.733040726116042*^9}},
FontSize->14],
Cell[BoxData[
RowBox[{"{",
RowBox[{"True", ",", "False"}], "}"}]], "Output",
CellChangeTimes->{{3.733040713011043*^9, 3.733040727436584*^9},
3.7330507966138163`*^9, 3.733051215136593*^9, 3.733057795135075*^9,
3.733065777143858*^9, 3.7330739818817377`*^9, 3.7330741493887978`*^9,
3.733079962850775*^9, 3.733125359853557*^9, 3.733128228831614*^9,
3.733133300440402*^9, 3.733210837798011*^9, 3.733211535667242*^9,
3.733212552752743*^9, 3.7332127526462317`*^9, {3.733212822537129*^9,
3.7332128484136143`*^9}, 3.733215963960677*^9, 3.73321611883669*^9,
3.733221737705132*^9, 3.7332217970481586`*^9, 3.7332698867625923`*^9,
3.733277690269019*^9},
FontSize->14]
}, Open ]],
Cell[TextData[{
"In ",
StyleBox["Mathematica",
FontSlant->"Italic"],
", all geometric shapes are first class citizens of the entire language same \
way as all other mathematical objects, with arbitrary symbolic computations \
and transformation being possible for them. In a formalism where pretty much \
everything is an expression that consists of a head and some number of \
arguments, pattern matching rules and other transformations can be liberally \
applied to everything, and the front end will then render the resulting \
expressions with a particular head in some more human friendly visual form. \
Expressions whose head is ",
StyleBox["Graphics",
FontWeight->"Bold"],
" are rendered as the graphical shapes that they symbolically represent. But \
despite how fancy some result looks when rendered on screen, everything is \
still internally an expression tree, as can always be revealed by applying \
either function ",
StyleBox["FullForm",
FontWeight->"Bold"],
" or ",
StyleBox["TreeForm",
FontWeight->"Bold"],
" to any expression to reveal the bare bones of this underlying reality."
}], "Text",
CellChangeTimes->CompressedData["
1:eJxTTMoPSmViYGCQAGIQnRDuxLr//GvHyHNX2UG01pV9xiDaT+K6FYi+NEG4
EURL/bVtAdGXY47MBdFzTNcsBtEL6iZvAtFu8an7QfQxPZ+bIPra/VdPQHQd
g+w7EH3uEuMnEH1kWdIPEH39bsVfsDlbn+YcANIqc16DaWvXaFWRC68dRaIX
mILoOjnhPaZA2imy4xCIFvqV8cUSSGukfWCzAtI9XhURIHpJ+68oEB0RXtkG
olfNae8E0953poPoaX6bZoLo6drLNoJo/8nlm0F0zYSH20G0+1P+HSC6PSci
2wVIr/h6ogREL+tU3x8PpJf7XjgCovdcUJJMAIn/X6QAotsKP97oBNKLeFvu
gGjLxMwN3SD3MApvAtHfFxaI9QLpsGuXxUH0IaPT6cuAdMZ5gwIQDQCOKNwj
"],
TextJustification->1.,
FontSize->14],
Cell[CellGroupData[{
Cell[BoxData[{
RowBox[{
RowBox[{"s1", " ", "=",
RowBox[{"Rectangle", "[",
RowBox[{
RowBox[{"{",
RowBox[{"0", ",", "0"}], "}"}], ",",
RowBox[{"{",
RowBox[{"2", ",", "2"}], "}"}]}], "]"}]}], ";"}], "\[IndentingNewLine]",
RowBox[{
RowBox[{"s2", " ", "=", " ",
RowBox[{"Disk", "[",
RowBox[{
RowBox[{"{",
RowBox[{"2", ",", "2"}], "}"}], ",", "1"}], "]"}]}],
";"}], "\[IndentingNewLine]",
RowBox[{
RowBox[{"s3", " ", "=", " ",
RowBox[{"RegionIntersection", "[",
RowBox[{"s1", ",", " ", "s2"}], "]"}]}], ";"}], "\[IndentingNewLine]",
RowBox[{
RowBox[{"ClearAll", "[",
RowBox[{"x", ",", "y"}], "]"}], ";"}], "\[IndentingNewLine]",
RowBox[{"{",
RowBox[{
RowBox[{"Area", "[", "s1", "]"}], ",", " ",
RowBox[{"Area", "[", "s2", "]"}], ",", " ",
RowBox[{"Area", "[", "s3", "]"}], ",", " ",
RowBox[{"Integrate", "[",
RowBox[{
RowBox[{
RowBox[{"x", "^", "2"}], "+", "y"}], ",", " ",
RowBox[{
RowBox[{"{",
RowBox[{"x", ",", "y"}], "}"}], " ", "\[Element]", " ", "s3"}]}],
"]"}]}], "}"}], "\[IndentingNewLine]",
RowBox[{"Graphics", "[",
RowBox[{
RowBox[{"{",
RowBox[{
RowBox[{"EdgeForm", "[",
RowBox[{"{",
RowBox[{"Thick", ",", " ", "Black"}], "}"}], "]"}], ",", "Red", ",",
" ", "s1", ",", " ",
RowBox[{"Opacity", "[", ".5", "]"}], ",", "Green", ",", " ", "s2"}],
"}"}], ",", " ",
RowBox[{"ImageSize", " ", "\[Rule]", " ", "Small"}]}], "]"}]}], "Input",
CellChangeTimes->{{3.7330500866204348`*^9, 3.733050209083714*^9}, {
3.733050240107102*^9, 3.7330502479849577`*^9}, {3.73305029649769*^9,
3.7330503006423903`*^9}, {3.7330503396727858`*^9, 3.733050412907413*^9}, {
3.7330504480708237`*^9, 3.733050546885775*^9}, {3.73305057783733*^9,
3.73305063072335*^9}, {3.733050669732189*^9, 3.733050669874494*^9}, {
3.7330507085905323`*^9, 3.7330507430586576`*^9}, {3.733072098694427*^9,
3.733072100254237*^9}, {3.7331266309961777`*^9, 3.733126633519623*^9}, {
3.7332217217370377`*^9, 3.7332217218490562`*^9}, {3.7332217799388227`*^9,
3.733221782456421*^9}, {3.733251180793741*^9, 3.733251184840847*^9}},
FontSize->14],
Cell[BoxData[
RowBox[{"{",
RowBox[{"4", ",", "\[Pi]", ",",
FractionBox["\[Pi]", "4"], ",",
RowBox[{
FractionBox["5", "48"], " ",
RowBox[{"(",
RowBox[{
RowBox[{"-", "16"}], "+",
RowBox[{"15", " ", "\[Pi]"}]}], ")"}]}]}], "}"}]], "Output",
CellChangeTimes->{
3.733050631838379*^9, 3.733050670523735*^9, {3.73305071337084*^9,
3.7330507477000732`*^9}, 3.733050800208445*^9, 3.733051218593081*^9,
3.733057798323743*^9, 3.7330657803224154`*^9, 3.733072105296195*^9,
3.733073986648593*^9, 3.733074153758664*^9, 3.733079966943808*^9,
3.7331253639260607`*^9, 3.733126638238584*^9, 3.733128233415642*^9,
3.733133304311599*^9, 3.73321084177735*^9, 3.73321153979275*^9,
3.733212556621264*^9, 3.7332127565084457`*^9, {3.733212826410871*^9,
3.7332128522102633`*^9}, 3.7332159682282124`*^9, 3.733216122820221*^9, {
3.733221775805081*^9, 3.73322179857648*^9}, 3.733269888545657*^9,
3.733277691950946*^9},
FontSize->14],
Cell[BoxData[
GraphicsBox[
{RGBColor[1, 0, 0], EdgeForm[{GrayLevel[0], Thickness[Large]}],
RectangleBox[{0, 0}, {2, 2}],
{RGBColor[0, 1, 0], Opacity[0.5], DiskBox[{2, 2}]}},
ImageSize->Small]], "Output",
CellChangeTimes->{
3.733050631838379*^9, 3.733050670523735*^9, {3.73305071337084*^9,
3.7330507477000732`*^9}, 3.733050800208445*^9, 3.733051218593081*^9,
3.733057798323743*^9, 3.7330657803224154`*^9, 3.733072105296195*^9,
3.733073986648593*^9, 3.733074153758664*^9, 3.733079966943808*^9,
3.7331253639260607`*^9, 3.733126638238584*^9, 3.733128233415642*^9,
3.733133304311599*^9, 3.73321084177735*^9, 3.73321153979275*^9,
3.733212556621264*^9, 3.7332127565084457`*^9, {3.733212826410871*^9,
3.7332128522102633`*^9}, 3.7332159682282124`*^9, 3.733216122820221*^9, {
3.733221775805081*^9, 3.73322179857648*^9}, 3.733269888545657*^9,
3.733277691964099*^9},
FontSize->14]
}, Open ]],
Cell[TextData[{
"The previous example uses ",
StyleBox["x",
FontWeight->"Bold"],
" and ",
StyleBox["y",
FontWeight->"Bold"],
" as symbols that are assumed to be uninitialized when used inside ",
StyleBox["Integrate",
FontWeight->"Bold"],
". Whenever symbols are used this way, it is a good idea to use ",
StyleBox["ClearAll",
FontWeight->"Bold"],
" to ensure that their names don\[CloseCurlyQuote]t have any values \
associated with them but remain as pure symbols. This avoids tricky bugs that \
can easily occur especially if several ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" documents are simultaneously open using the same computation kernel. If \
evaluating another document assigns some values to these symbols, these \
values get silently substituted in their place inside ",
StyleBox["Integrate",
FontWeight->"Bold"],
", causing the entire computation to do something very different than was \
originally intended."
}], "Text",
CellChangeTimes->{{3.7332512069361877`*^9, 3.7332513714773893`*^9}, {
3.733269932973502*^9, 3.733269961805265*^9}, {3.733271445695674*^9,
3.733271459172535*^9}},
TextJustification->1.,
FontSize->14],
Cell[TextData[{
StyleBox["Lab Two: Conditions\n", "Chapter"],
"The second lab of this introductory Java course teaches the students to use \
the basic ",
StyleBox["if-else conditions",
FontSlant->"Italic"],
" to solve decision problems. Nearly every adult is familiar with the \
ordinary 52 playing cards and how their combinations create virtually \
infinite possibilities for endless variety of play, which makes playing cards \
an immediately familiar problem domain for the students to practice \
programming in both this and the following week's labs. (As Mark Twain noted \
back in his day, every educated person should at least know that a flush \
beats a straight.) The four methods required this week each receive a hand \
of playing cards as arguments, from which these methods then have to \
determine whether that hand of cards satisfies the given interesting property \
such as being a poker ",
StyleBox["flush",
FontSlant->"Italic"],
" or a ",
StyleBox["four-of-a-kind",
FontSlant->"Italic"],
". Given a poker hand known to contain exactly five cards, these conditions \
can be written without any loops, since those have not yet been taught at \
this point in the course, merely by looking at the five cards and the pairs \
that they form one at the time inside an ",
StyleBox["if-else ladder",
FontSlant->"Italic"],
". However, the stealthy idea between the lines in all of this week\
\[CloseCurlyQuote]s problems is preparing the student for the need for loops \
in the future labs where the string can contain any number of cards, or for \
that matter, anything at all.\nAt this point of the Java course, the students \
have not yet seen arrays, but the previous lecture that covered all the basic \
data types and their properties and operations has familiarized them with the \
",
StyleBox["String",
FontWeight->"Bold"],
" class with its basic operations ",
StyleBox["charAt",
FontWeight->"Bold"],
", ",
StyleBox["length",
FontWeight->"Bold"],
" and ",
StyleBox["substring",
FontWeight->"Bold"],
", from which all other ",
StyleBox["String",
FontWeight->"Bold"],
" operations could in principle be built from ground up. In ",
StyleBox["Mathematica",
FontSlant->"Italic"],
", lists are naturally taught from day one, so in a programming course that \
uses ",
StyleBox["Mathematica",
FontSlant->"Italic"],
", the five card poker hand would be given as a list of cards. The fully \
symbolic nature of the ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" language would even allow us to represent ranks and suits directly as \
these symbols, using the Unicode symbols within the language itself to denote \
the suits. "
}], "Text",
CellChangeTimes->{{3.732797482073166*^9, 3.732797502681439*^9}, {
3.732797853963399*^9, 3.732797910721717*^9}, {3.7327984726114283`*^9,
3.732798497937146*^9}, {3.732798702136331*^9, 3.732798749381544*^9}, {
3.732798868609207*^9, 3.73279897116788*^9}, {3.7327991783807096`*^9,
3.7327992713398237`*^9}, {3.73279934490631*^9, 3.732799376056983*^9}, {
3.732799427082857*^9, 3.73279946777708*^9}, {3.732800359178419*^9,
3.73280035936281*^9}, {3.732971818852201*^9, 3.732971949011118*^9}, {
3.733040608597472*^9, 3.7330406602608957`*^9}, {3.733049251280526*^9,
3.7330493995124702`*^9}, {3.7330500517591*^9, 3.733050074836355*^9}, {
3.733072132642799*^9, 3.733072143219222*^9}, {3.7331266122143307`*^9,
3.7331266156134043`*^9}, {3.733212909577549*^9, 3.7332129919585133`*^9}, {
3.733219528585815*^9, 3.73321968730682*^9}, {3.73327148097476*^9,
3.733271703282097*^9}},
TextJustification->1.,
FontSize->14],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{"suitChars", " ", "=", " ",
RowBox[{"FromCharacterCode", "[",
RowBox[{"Map", "[",
RowBox[{
RowBox[{
RowBox[{"FromDigits", "[",
RowBox[{"#", ",", "16"}], "]"}], "&"}], ",",
RowBox[{"{",
RowBox[{
"\"\<2663\>\"", ",", "\"\<2666\>\"", ",", " ", "\"\<2660\>\"", ",",
" ", "\"\<2665\>\""}], " ", "}"}]}], "]"}], "]"}]}]], "Input",
CellChangeTimes->{{3.7327994691994457`*^9, 3.732799543945075*^9}, {
3.732799586751647*^9, 3.7327996737116756`*^9}, {3.732807489404282*^9,
3.7328074897684317`*^9}},
FontSize->14],
Cell[BoxData["\<\"\[ClubSuit]\:2666\[SpadeSuit]\:2665\"\>"], "Output",
CellChangeTimes->{
3.732799544872333*^9, {3.73279963268165*^9, 3.7327996740221786`*^9},
3.732800497015486*^9, 3.732801372308345*^9, 3.732823457274132*^9,
3.732970425941112*^9, 3.733050800476921*^9, 3.733051218864806*^9,
3.733057798597784*^9, 3.733065780619285*^9, 3.733073987023608*^9,
3.733074154056733*^9, 3.7330799672301292`*^9, 3.733125364237546*^9,
3.7331282336912603`*^9, 3.733133304597505*^9, 3.733210842192443*^9,
3.7332115400111113`*^9, 3.733212556837895*^9, 3.73321275670061*^9, {
3.733212826615267*^9, 3.733212852407598*^9}, 3.73321596847361*^9,
3.733216123066085*^9, 3.7332217987819853`*^9, 3.73326988881809*^9,
3.733277692123331*^9},
FontSize->14]
}, Open ]],
Cell[TextData[{
"However, we can use this opportunity to solve these problems with ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" string processing techniques, so that following the specification of the \
original Java lab, the arguments given to these functions are text strings \
where each card is encoded as two characters. The first character represents \
the rank from ",
StyleBox["23456789TJQKA",
FontSlant->"Italic"],
", followed by the second character representing the suit from ",
StyleBox["cdhs",
FontSlant->"Italic"],
". A hand that consists of ",
StyleBox["n",
FontSlant->"Italic"],
" playing cards will then be encoded as a string of precisely the length ",
StyleBox["2n",
FontSlant->"Italic"],
", with no separator characters inserted between the cards.\nThe very first \
lab problem within the previous setup asks for a method that takes the rank \
given as a character and converts it to its nominal integer value. For \
simplicity, and following the lightweight spirit of the ",
StyleBox["design by contract",
FontSlant->"Italic"],
" software engineering philosophy, in all the labs in the course the method \
implementations may assume that their argument values are legal as promised \
in the method specification. These methods therefore don\[CloseCurlyQuote]t \
need to perform any error detection, let alone error recovery that would be a \
topic better left for a more advanced course. (The author\[CloseCurlyQuote]s \
second course of programming, of course, covers the concept of ",
StyleBox["method pre- and postconditions",
FontSlant->"Italic"],
" and how ",
StyleBox["exceptions",
FontSlant->"Italic"],
" are used to terminate a method that can only throw its hands up in the air \
in frustration and give up as soon as it realizes that it has been asked to \
do something that was logically impossible to begin with.)"
}], "Text",
CellChangeTimes->{{3.7327996866450167`*^9, 3.7327999119604588`*^9}, {
3.73297197580206*^9, 3.732972048721084*^9}, {3.732972096906045*^9,
3.732972141735405*^9}, {3.733072149152166*^9, 3.7330722431204977`*^9}, {
3.733219697797144*^9, 3.7332198673513203`*^9}, {3.733222698539114*^9,
3.733222701841579*^9}, {3.733271728395788*^9, 3.733271808535548*^9}},
TextJustification->1.,
FontSize->14],
Cell[CellGroupData[{
Cell[BoxData[{
RowBox[{
RowBox[{"ranks", " ", "=", " ",
RowBox[{"{",
RowBox[{
"\"\<2\>\"", ",", "\"\<3\>\"", ",", "\"\<4\>\"", ",", "\"\<5\>\"", ",",
"\"\<6\>\"", ",", "\"\<7\>\"", ",", "\"\<8\>\"", ",", "\"\<9\>\"", ",",
"\"\<T\>\"", ",", "\"\<J\>\"", ",", "\"\<Q\>\"", ",", "\"\<K\>\"", ",",
"\"\<A\>\""}], "}"}]}], ";"}], "\[IndentingNewLine]",
RowBox[{
RowBox[{
RowBox[{"numericalRank", "[", "r_", "]"}], " ", ":=", " ",
RowBox[{"First", "[",
RowBox[{"First", "[",
RowBox[{"1", " ", "+", " ",
RowBox[{"Position", "[",
RowBox[{"ranks", ",", " ", "r"}], "]"}]}], "]"}], "]"}]}],
";"}], "\[IndentingNewLine]",
RowBox[{"Map", "[",
RowBox[{"numericalRank", ",", " ", "ranks"}], "]"}]}], "Input",
CellChangeTimes->{{3.732799918121694*^9, 3.732800030263535*^9}, {
3.732800667662332*^9, 3.732800676380962*^9}, {3.7329720711952333`*^9,
3.732972089200919*^9}},
FontSize->14],
Cell[BoxData[
RowBox[{"{",
RowBox[{
"2", ",", "3", ",", "4", ",", "5", ",", "6", ",", "7", ",", "8", ",", "9",
",", "10", ",", "11", ",", "12", ",", "13", ",", "14"}], "}"}]], "Output",
CellChangeTimes->{{3.732799982164116*^9, 3.732800031304603*^9},
3.732800497065687*^9, 3.73280067700156*^9, 3.7328013723592854`*^9,
3.7328234573571253`*^9, 3.732970426024562*^9, 3.7329720907000847`*^9,
3.7330508005402203`*^9, 3.7330512189654016`*^9, 3.733057798678691*^9,
3.7330657809448233`*^9, 3.7330739871446047`*^9, 3.733074154152975*^9,
3.733079967330142*^9, 3.733125364333164*^9, 3.7331282338011017`*^9,
3.733133304702488*^9, 3.733210842308474*^9, 3.733211540092121*^9,
3.733212556932829*^9, 3.733212756775001*^9, {3.733212826699765*^9,
3.73321285249305*^9}, 3.733215968573908*^9, 3.733216123149415*^9,
3.73322179886333*^9, 3.733269888901651*^9, 3.73327769220862*^9},
FontSize->14]
}, Open ]],
Cell[TextData[{
"Given a five-card poker hand encoded as a string of ten characters, the \
second lab problem of this week asks the method to determine whether that \
hand is a ",
StyleBox["flush",
FontSlant->"Italic"],
", that is, all of its five cards are of the same suit. In Java, this \
becomes a straightforward conjunction of equality comparisons between the \
five suit characters extracted from the hand. The students will hopefully \
realize at this point that only four equality comparisons suffice, since it \
is necessary to compare each suit character only to the suit of the first \
card, due to the ",
StyleBox["transitivity",
FontSlant->"Italic"],
" of equality.\nIn ",
StyleBox["Mathematica",
FontSlant->"Italic"],
", determining whether the hand is a flush can be achieved in a more \
abstract manner by checking whether the string matches the pattern whose \
characters on the odd positions we don\[CloseCurlyQuote]t care about, whereas \
all five characters in the even positions must be the exact same character, \
whichever suit character that one might be. One very important difference \
between Java and ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" also illustrated in this problem is that Java uses the programmer-style \
zero-based indexing throughout, whereas ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" consistently uses normal people style one-based indexing throughout. (The \
zeroth index of a list or an arbitrary expression gives the head of that \
expression, which can cause weird results for somebody who, due to an \
ingrained habit, accidentally uses zero-based indexing with ",
StyleBox["Mathematica",
FontSlant->"Italic"],
".) We can write this function to work with hands on any length ",
StyleBox["n",
FontSlant->"Italic"],
" by building the pattern used for string matching to consist of ",
StyleBox["n",
FontSlant->"Italic"],
" separate pieces that are combined together with ",
StyleBox["Nest",
FontWeight->"Bold"],
"."
}], "Text",
CellChangeTimes->{{3.732800050400955*^9, 3.732800078550231*^9}, {
3.732800170612006*^9, 3.732800220427393*^9}, {3.732800340322835*^9,
3.732800390601242*^9}, {3.7328024576589737`*^9, 3.7328024970105762`*^9}, {
3.732803416419623*^9, 3.732803478834983*^9}, {3.732972157944769*^9,
3.732972245797879*^9}, {3.7330407866273537`*^9, 3.733040825138817*^9}, {
3.7330722531981907`*^9, 3.733072365511232*^9}, {3.7332198823460703`*^9,
3.733219932142069*^9}, {3.733271319075571*^9, 3.7332713268716183`*^9}, {
3.733271816090487*^9, 3.733271912173009*^9}},
TextJustification->1.,
FontSize->14],
Cell[CellGroupData[{
Cell[BoxData[{
RowBox[{
RowBox[{
RowBox[{"isFlush", "[", "hand_", "]"}], " ", ":=", " ",
RowBox[{"With", "[",
RowBox[{
RowBox[{"{",
RowBox[{"n", " ", "=", " ",
RowBox[{"Ceiling", "[",
RowBox[{
RowBox[{"StringLength", "[", "hand", "]"}], "/", "2"}], "]"}]}],
"}"}], ",", "\[IndentingNewLine]",
RowBox[{"With", "[",
RowBox[{
RowBox[{"{",
RowBox[{"pat", " ", "=", " ",
RowBox[{"Nest", "[",
RowBox[{
RowBox[{
RowBox[{"(",
RowBox[{
"#", " ", "~~", " ", "_", " ", "~~", " ", "suitInFlush_"}],
")"}], "&"}], ",", "StartOfString", ",", " ", "n"}], "]"}]}],
"}"}], ",", "\[IndentingNewLine]",
RowBox[{"StringMatchQ", "[",
RowBox[{"hand", ",", " ", "pat"}], "]"}]}], "]"}]}], "]"}]}],
";"}], "\[IndentingNewLine]",
RowBox[{
RowBox[{"SetAttributes", "[",
RowBox[{"isFlush", ",", " ", "Listable"}], "]"}],
";"}], "\[IndentingNewLine]",
RowBox[{"isFlush", "[",
RowBox[{"{",
RowBox[{
"\"\<Kh7h2hTh3h\>\"", ",", " ", "\"\<Qh7s2hTh3h\>\"", ",", " ",
"\"\<7hAh4h\>\""}], "}"}], "]"}]}], "Input",
CellChangeTimes->{{3.732800087918878*^9, 3.732800166669567*^9},
3.732800407467168*^9, {3.732800476219584*^9, 3.73280049007157*^9}, {
3.7328014784763308`*^9, 3.732801506152872*^9}, {3.732801554564928*^9,
3.732801646834787*^9}, {3.732801678671895*^9, 3.7328017502483788`*^9}, {
3.732801817875804*^9, 3.732801866521743*^9}, {3.73280191793819*^9,
3.732801926275405*^9}},
FontSize->14],
Cell[BoxData[
RowBox[{"{",
RowBox[{"True", ",", "False", ",", "True"}], "}"}]], "Output",
CellChangeTimes->{{3.7328016218539553`*^9, 3.73280164863787*^9},
3.732801684848732*^9, {3.7328017199407387`*^9, 3.732801751212059*^9}, {
3.732801819047936*^9, 3.732801825386066*^9}, 3.732801868767962*^9,
3.73282345744101*^9, 3.732970426108699*^9, 3.7330508006073627`*^9,
3.733051219050344*^9, 3.733057798761043*^9, 3.733065781036717*^9,
3.733073987267465*^9, 3.733074154260998*^9, 3.7330799674301577`*^9,
3.733125364433515*^9, 3.733128233918*^9, 3.733133304802718*^9,
3.733210842445362*^9, 3.733211540180094*^9, 3.733212557032123*^9,