Discovering Computer Science Interdisciplinary Problems Principles And Python Programming Havill download
Discovering Computer Science Interdisciplinary Problems Principles And Python Programming Havill download
https://ebookbell.com/product/discovering-computer-science-
interdisciplinary-problems-principles-and-python-programming-
havill-21354402
https://ebookbell.com/product/discovering-computer-science-
interdisciplinary-problems-principles-and-python-programming-2nd-
edition-jessen-havill-24229672
https://ebookbell.com/product/discovering-computer-science-
interdisciplinary-problems-principles-and-python-programming-1st-
edition-jessen-havill-5743478
https://ebookbell.com/product/discovering-computer-science-
interdisciplinary-problems-principles-and-python-programming-first-
edition-jessen-havill-10833944
https://ebookbell.com/product/discovering-computer-science-havill-
jessen-61266728
Computer Science Notable Research And Discoveries Kyle Kirkland
https://ebookbell.com/product/computer-science-notable-research-and-
discoveries-kyle-kirkland-23139084
https://ebookbell.com/product/discovering-computers-fundamentals-your-
interactive-guide-to-the-digital-world-gary-b-shelly-2412418
https://ebookbell.com/product/discovering-computers-
fundamentals-2011-edition-shelly-cashman-7th-edition-gary-b-
shelly-2414214
https://ebookbell.com/product/discovering-computers-complete-your-
interactive-guide-to-the-digital-world-1st-edition-gary-b-
shelly-2446660
https://ebookbell.com/product/discovering-computers-fundamentals-5th-
ed-gary-b-shelly-misty-e-vermaat-contributing-authors-2620866
DISCOVERING
COMPUTER
SCIENCE
Interdisciplinary Problems,
Principles, and Python
Programming
CHAPMAN & HALL/CRC
TEXTBOOKS IN COMPUTING
Series Editors
This series covers traditional areas of computing, as well as related technical areas, such as
software engineering, artificial intelligence, computer engineering, information systems, and
information technology. The series will accommodate textbooks for undergraduate and gradu-
ate students, generally adhering to worldwide curriculum standards from professional societ-
ies. The editors wish to encourage new and imaginative ideas and proposals, and are keen to
help and encourage new authors. The editors welcome proposals that: provide groundbreaking
and imaginative perspectives on aspects of computing; present topics in a new and exciting
context; open up opportunities for emerging areas, such as multi-media, security, and mobile
systems; capture new developments and applications in emerging fields of computing; and
address topics that provide support for computing, such as mathematics, statistics, life and
physical sciences, and business.
Published Titles
DISCOVERING
COMPUTER
SCIENCE
Interdisciplinary Problems,
Principles, and Python
Programming
Jessen Havill
Denison University
Granville, Ohio, USA
CRC Press
Taylor & Francis Group
6000 Broken Sound Parkway NW, Suite 300
Boca Raton, FL 33487-2742
© 2016 by Taylor & Francis Group, LLC
CRC Press is an imprint of Taylor & Francis Group, an Informa business
This book contains information obtained from authentic and highly regarded sources. Reasonable efforts have been
made to publish reliable data and information, but the author and publisher cannot assume responsibility for the valid-
ity of all materials or the consequences of their use. The authors and publishers have attempted to trace the copyright
holders of all material reproduced in this publication and apologize to copyright holders if permission to publish in this
form has not been obtained. If any copyright material has not been acknowledged please write and let us know so we may
rectify in any future reprint.
Except as permitted under U.S. Copyright Law, no part of this book may be reprinted, reproduced, transmitted, or uti-
lized in any form by any electronic, mechanical, or other means, now known or hereafter invented, including photocopy-
ing, microfilming, and recording, or in any information storage or retrieval system, without written permission from the
publishers.
For permission to photocopy or use material electronically from this work, please access www.copyright.com (http://
www.copyright.com/) or contact the Copyright Clearance Center, Inc. (CCC), 222 Rosewood Drive, Danvers, MA 01923,
978-750-8400. CCC is a not-for-profit organization that provides licenses and registration for a variety of users. For
organizations that have been granted a photocopy license by the CCC, a separate system of payment has been arranged.
Trademark Notice: Product or corporate names may be trademarks or registered trademarks, and are used only for
identification and explanation without intent to infringe.
Visit the Taylor & Francis Web site at
http://www.taylorandfrancis.com
and the CRC Press Web site at
http://www.crcpress.com
Contents
Preface xv
Acknowledgments xxiii
v
vi Contents
Built-in functions 45
Strings 47
Modules 51
*2.5 BINARY ARITHMETIC 54
Finite precision 55
Negative integers 56
Designing an adder 57
Implementing an adder 58
2.6 SUMMARY 62
2.7 FURTHER DISCOVERY 62
Bibliography 709
Index 713
This page intentionally left blank
Preface
xv
xvi Preface
Web resources
The text, exercises, and projects often refer to files on the book’s accompanying
web site, which can be found at
http://discoverCS.denison.edu .
This web site also includes pointers for further exploration, links to additional
documentation, and errata.
To students
Learning how to solve computational problems and implement them as computer
programs requires daily practice. Like an athlete, you will get out of shape and fall
behind quickly if you skip it. There are no shortcuts. Your instructor is there to
help, but he or she cannot do the work for you.
With this in mind, it is important that you type in and try the examples
throughout the text, and then go beyond them. Be curious! There are numbered
“Reflection” questions throughout the book that ask you to stop and think about, or
apply, something that you just read. Often, the question is answered in the book
immediately thereafter, so that you can check your understanding, but peeking
ahead will rob you of an important opportunity.
There are many opportunities to delve into topics more deeply. Boxes scattered
throughout the text briefly introduce related, but more technical, topics. For the
most part, these are not strictly required to understand what comes next, but I
encourage you to read them anyway. In the “Further discovery” section of each
chapter, you can find additional pointers to explore chapter topics in more depth.
At the end of most sections are several programming exercises that ask you
to further apply concepts from that section. Often, the exercises assume that you
have already worked through all of the examples in that section. All later chapters
conclude with a selection of more involved interdisciplinary projects that you may
be asked by your instructor to tackle.
The book assumes no prior knowledge of computer science. However, it does
assume a modest comfort with high school algebra and mathematical functions.
Occasionally, trigonometry is mentioned, as is the idea of convergence to a limit,
but these are not crucial to an understanding of the main topics in this book.
To instructors
This book may be appropriate for a traditional CS1 course for majors, a CS0 course
for non-majors (at a slower pace and omitting more material), or an introductory
computing course for students in the natural and/or social sciences.
As suggested above, I emphasize computer science principles and the role of
abstraction, both functional and data, throughout the book. I motivate functions
as implementations of functional abstractions, and point out that strings, lists,
and dictionaries are all abstract data types that allow us to solve more interesting
problems than would otherwise be possible. I introduce the idea of time complexity
Preface xvii
Chapter 7 Chapter 6
Chapter 8 Chapter 5
Designing Text, documents,
Data analysis Forks in the road
programs and DNA
Chapter 10
Chapter 9 Chapter 11
Self-similarity and
Flatland Organizing data
recursion
Chapter 13
Chapter 12
Abstract data
Networks
types
intuitively, without formal definitions, in the first chapter and return to it several
times as more sophisticated algorithms are developed. The book uses a spiral
approach for many topics, returning to them repeatedly in increasingly complex
contexts. Where appropriate, I also weave into the book topics that are traditionally
left for later computer science courses. A few of these are presented in boxes that
may be covered at your discretion. None of these topics is introduced rigorously, as
they would be in a data structures course. Rather, I introduce them informally and
intuitively to give students a sense of the problems and techniques used in computer
science. I hope that the tables below will help you navigate the book, and see where
particular topics are covered.
This book contains over 600 end-of-section exercises and over 300 in-text reflection
questions that may be assigned as homework or discussed in class. At the end of
most chapters is a selection of projects (about 30 in all) that students may work on
independently or in pairs over a longer time frame. I believe that projects like these
are crucial for students to develop both problem solving skills and an appreciation
for the many fascinating applications of computer science.
Because this book is intended for a student who may take additional courses in
computer science and learn other programming languages, I intentionally omit some
features of Python that are not commonly found elsewhere (e.g., simultaneous swap,
chained comparisons, enumerate in for loops). You may, of course, supplement
with these additional syntactical features.
There is more in this book than can be covered in a single semester, giving an
instructor the opportunity to tailor the content to his or her particular situation and
interests. Generally speaking, as illustrated in Figure 1, Chapters 1–6 and 8 form the
core of the book, and should be covered sequentially. The remaining chapters can be
covered, partially or entirely, at your discretion, although I would expect that most
instructors will cover at least parts of Chapters 7, 10, 11, and 13. Chapter 7 contains
xviii Preface
Chapter outlines
The following tables provide brief overviews of each chapter. Each table’s three
columns, reflecting the three parts of the book’s subtitle, provide three lenses through
which to view the chapter. The first column lists a selection of representative problems
that are used to motivate the material. The second column lists computer science
principles that are introduced in that chapter. Finally, the third column lists Python
programming topics that are either introduced or reinforced in that chapter to
implement the principles and/or solve the problems.
Chapter 9. Flatland
Sample problems Principles Programming
• earthquake data • 2-D data • 2-D data in list of lists
• Game of Life • cellular automata • nested loops
• image filters • digital images • 2-D data in a dictionary
• racial segregation • color models
• ferromagnetism
• dendrites
Software assumptions
To follow along in this book and complete the exercises, you will need to have installed
Python 3.4 (or later) on your computer, and have access to IDLE or another
programming environment. The book also assumes that you have installed the
matplotlib and numpy modules. Please refer to Appendix A for more information.
Errata
While I (and my students) have ferreted out many errors, readers will inevitably
find more. You can find an up-to-date list of errata on the book web site. If
you find an error in the text or have another suggestion, please let me know at
havill@denison.edu.
This page intentionally left blank
Acknowledgments
was extraordinarily naı̈ve when I embarked on this project two years ago. “How
I hard can it be to put these ideas into print?” Well, much harder than I thought,
as it turns out. I owe debts of gratitude to many who saw me through to the end.
First and foremost, my family not only tolerated me during this period, but
offered extraordinary support and encouragement. Thank you Beth, for your patience
and strength, and all of the time you have made available to me to work on the
book. I am grateful to my in-laws, Roger and Nancy Vincent, who offered me their
place in Wyoming for a month-long retreat in the final stretch. And, to my four
children, Nick, Amelia, Caroline, and Lillian, I promise to make up for lost time.
My colleagues Matt Kretchmar, Ashwin Lall, and David White used drafts in
their classes, and provided invaluable feedback. They have been fantastic sounding
boards, and have graciously provided many ideas for exercises and projects. Students
in Denison University’s CS 111 and 112 classes caught many typos, especially Gabe
Schenker, Christopher Castillo, Christine Schmittgen, Alivia Tacheny, Emily Lamm,
and Ryan Liedke. Dana Myers read much of the book and offered an abundance of
detailed suggestions. Joan Krone also read early chapters and offered constructive
feedback. I am grateful to Todd Feil for his support, and his frank advice after
reading the almost-final manuscript.
I have benefitted tremendously from many conversations about computational
science, geology, and life with my friend and colleague David Goodwin. Project 8.1
is based on an assignment that he has used in his classes. I have also learned a great
deal from collaborations with Jeff Thompson. Jeff also advised me on Section 6.7
and Project 6.2. Frank Hassebrock enthusiastically introduced me to theories of
problem solving in cognitive psychology. And Dee Ghiloni, the renowned cat herder,
has supported me and my work in more ways than I can count.
I am indebted to the following reviewers, who read early chapters and offered
expert critiques: Terry Andres (University of Manitoba), John Impagliazzo (Qatar
University), Daniel Kaplan (Macalester College), Nathaniel Kell (Duke University),
Andrew McGettrick (University of Strathclyde); Hamid Mokhtarzadeh (University
of Minnesota), George Novacky (University of Pittsburgh), and J. F. Nystrom (Ferris
State University).
I could not have completed this book without the Robert C. Good Fellowship
awarded to me by Denison University.
Finally, thank you to Randi Cohen, for believing in this project, and for her
advice and patience throughout.
xxiii
This page intentionally left blank
About the author
Jessen Havill is a Professor of Computer Science and the Benjamin Barney Chair
of Mathematics at Denison University, where he has been on the faculty since 1998.
Dr. Havill teaches courses across the computer science curriculum, as well as an
interdisciplinary elective in computational biology. He was awarded the college’s
highest teaching honor, the Charles A. Brickman Teaching Excellence Award, in
2013.
Dr. Havill is also an active researcher, with a primary interest in the development
and analysis of online algorithms. In addition, he has collaborated with colleagues
in biology and geosciences to develop computational tools to support research
and teaching in those fields. Dr. Havill earned his bachelor’s degree from Bucknell
University and his Ph.D. in computer science from The College of William and
Mary.
xxv
This page intentionally left blank
CHAPTER 1
What is computation?
We need to do away with the myth that computer science is about computers. Computer
science is no more about computers than astronomy is about telescopes, biology is about
microscopes or chemistry is about beakers and test tubes. Science is not about tools, it is
about how we use them and what we find out when we do.
omputers are the most powerful tools ever invented, but not because of their
C versatility and speed, per se. Computers are powerful because they empower
us to innovate and make unprecedented discoveries.
A computer is a machine that carries out a computation, a sequence of simple
steps that transforms some initial information, an input, into some desired result,
the output. Computer scientists harness the power of computers to solve complex
problems by designing solutions that can be expressed as computations. The output
of a computation might be a more efficient route for a spacecraft, a more effective
protocol to control an epidemic, or a secret message hidden in a digital photograph.
Computer science has always been interdisciplinary, as computational problems
arise in virtually every domain imaginable. Social scientists use computational models
to better understand social networks, epidemics, population dynamics, markets,
and auctions. Scholars working in the digital humanities use computational tools to
curate and analyze classic literature. Artists are increasingly incorporating digital
technologies into their compositions and performances. Computational scientists
work in areas related to climate prediction, genomics, particle physics, neuroscience,
and drug discovery.
In this book, we will explore the fundamental problem solving techniques of
computer science, and discover how they can be used to model and solve a variety of
interdisciplinary problems. In this first chapter, we will provide an orientation and
lay out the context in which to place the rest of the book. We will further develop
all of these ideas throughout, so don’t worry if they are not all crystal clear at first.
1
2 What is computation?
search engine
search terms
search results
Buxton Inn
313 E Broadway GPS device
Granville, OH 43023
address directions
y = 18x + 31
or
f (x) = 18x + 31,
you may have thought about the variable x as a representation of the input and
y, or f (x), as a representation of the output. In this example, when the input is
x = 2, the output is y = 67, or f (x) = 67. The arithmetic that turns x into y is a
very simple (and boring) example of a computation.
Reflection 1.1 What kinds of problems are you interested in? What are their inputs
and outputs? Are the inputs and outputs, as you have defined them, sufficient to
define the problem completely?
Problems and abstraction 3
To use the technologies illustrated in Figure 1.1 you do not need to understand how
the underlying computation transforms the input to the output; we can think of
the computation as a “black box” and still use the technology effectively. We call
this idea functional abstraction, a very important concept that we often take for
granted. Put simply,
A functional abstraction describes how to use a tool or technology without
necessarily providing any knowledge about how it works.
We exist in a world of abstractions; we could not function without them. We
even think about our own bodies in terms of abstractions. Move your fingers. Did
you need to understand how your brain triggered your nervous and musculoskeletal
systems to make that happen? As far as most of us are concerned, a car is also an
abstraction. To drive a car, do you need to know how turning the steering wheel
turns the car or pushing the accelerator makes it go faster? We understand what
should happen when we do these things, but not necessarily how they happen.
Without abstractions, we would be paralyzed by an avalanche of minutiae.
Reflection 1.2 Imagine that it was necessary to understand how a GPS device
works in order to use it. Or a music player. Or a computer. How would this affect
your ability to use these technologies?
New technologies and automation have introduced new functional abstractions into
everyday life. Our food supply is a compelling example of this. Only a few hundred
years ago, our ancestors knew exactly where their food came from. Inputs of hard
work and suitable weather produced outputs of grain and livestock to sustain a
family. In modern times, we input money and get packaged food; the origins of our
food have become much more abstract.
Reflection 1.3 Think about a common functional abstraction that you use regularly,
such as your phone or a credit card. How has this functional abstraction changed
over time? Can you think of instances in which better functional abstractions have
enhanced our ability to use a technology?
We also use layers of functional abstractions to work more efficiently. For example,
suppose you are the president of a large organization (like a university) that is
composed of six divisions and 5,000 employees. Because you cannot effectively
manage every detail of such a large organization, you assign a vice president to
oversee each of the divisions. You expect each VP to keep you informed about the
general activity and performance of that division, but insulate you from the day-to-
day details. In this arrangement, each division becomes a functional abstraction to
you: you know what each division does, but not necessarily how it does it. Benefitting
from these abstractions, you are now free to focus your resources on more important
organization-level activity. Each VP may utilize a similar arrangement within his
or her division. Indeed, organizations are often subdivided many times until the
number of employees in a unit is small enough to be overseen by a single manager.
4 What is computation?
Computers are similarly built from many layers of functional abstractions. When
you use a computer, you are presented with a “desktop” abstraction on which you
can store files and use applications (i.e., programs) to do work. That there appear
to be many applications executing simultaneously is also an abstraction. In reality,
some applications may be executing in parallel while others are being executed
one at a time, but alternating so quickly that they just appear to be executing in
parallel. This interface and the basic management of all of the computer’s resources
(e.g., hard drives, network, memory, security) is handled by the operating system.
An operating system is a complicated beast that is often mistakenly described as
“the program that is always running in the background on a computer.” In reality,
the core of an operating system provides several layers of functional abstractions
that allow us to use computers more efficiently.
Computer scientists invent computational processes (e.g., search engines, GPS
software, and operating systems), that are then packaged as functional abstractions
for others to use. But, as we will see, they also harness abstraction to correctly
and efficiently solve real-world problems. These problems are usually complicated
enough that they must be decomposed into smaller problems that human beings can
understand and solve. Once solved, each of these smaller pieces becomes a functional
abstraction that can be used in the solution to the original problem.
The ability to think in abstract terms also enables us to see similarities in prob-
lems from different domains. For example, by isolating the fundamental operations
of sexual reproduction (i.e., mutation and recombination) and natural selection (i.e.,
survival of the fittest), the process of evolution can be thought of as a randomized
computation. From this insight was borne a technique called evolutionary computa-
tion that has been used to successfully solve thousands of problems. Similarly, a
technique known as simulated annealing applies insights gained from the process
of slow-cooling metals to effectively find solutions to very hard problems. Other
examples include techniques based on the behaviors of crowds and insect swarms,
the operations of cellular membranes, and how networks of neurons make decisions.
use to carry out this formula. For example, each of these algorithms computes the
volume of a sphere.
1. Divide 4 by 3. 1. Compute r × r × r.
2. Multiply the previous result by π. 2. Multiply the previous result by π.
or
3. Repeat the following three times: 3. Multiply the previous result by 4.
multiply the previous result by r. 4. Divide the previous result by 3.
Both of these algorithms use the same formula, but they execute the steps in
different ways. This distinction may seem trivial to us but, depending on the level
of abstraction, we may need to be this explicit when “talking to” a computer.
Reflection 1.4 Write yet another algorithm that follows the volume formula.
def sphereVolume(radius):
volume = (4 / 3) * 3.14159 * (radius ** 3)
return volume
result = sphereVolume(10)
print(result)
Each line in a program is called a statement. The first statement in this program,
beginning with def, defines a new function. Like an algorithm, a function contains a
sequence of steps that transforms an input into an output. In this case, the function is
named sphereVolume, and it takes a single input named radius, in the parentheses
following the function name. The second line, which is indented to indicate that it is
part of the sphereVolume function, uses the volume formula to compute the volume
of the sphere, and then assigns this value to a variable named volume. The third line
indicates that the value assigned to volume should be “returned” as the function’s
output. These first three lines only define what the sphereVolume function should
do; the fourth line actually invokes the sphereVolume function with input radius
6 What is computation?
problem
solve
algorithm
implement
high-level program
execute or “run”
computation
equal to 10, and assigns the result (41.88787) to the variable named result. The
fifth line, you guessed it, prints the value assigned to result.
If you have never seen a computer program before, this probably looks like
“Greek” to you. But, at some point in your life, so did (4/3)πr3 . (What is this
symbol π? How can you do arithmetic with a letter? What is that small 3 doing
up there? There is no “plus” or “times” symbol; is this even math?) The same
can be said for notations like H2 O or 19○ C. But now that you are comfortable
with these representations, you can appreciate that they are more convenient and
less ambiguous than representations like “multiply 4/3 by π by the radius cubed”
and “two atoms of hydrogen and one atom of oxygen.” You should think of a
programming language as simply an extension of the familiar arithmetic notation.
But programming languages enable us to express algorithms for problems that reach
well beyond simple arithmetic.
The process that we have described thus far is illustrated in Figure 1.2. We start
with a problem having well-defined input and output. We then solve the problem
by designing an algorithm. Next, we implement the algorithm by expressing it as
a program in a programming language. Programming languages like Python are
often called high-level because they use familiar words like “return” and “print,”
and enable a level of abstraction that is familiar to human problem solvers. (As we
will see in Section 1.4, computers do not really “understand” high-level language
programs.) Finally, executing the program on a computer initiates the computation
Algorithms and programs 7
that gives us our results. (Executing a program is also called “running” it.) As we
will see soon, this picture is hiding some details, but it is sufficient for now.
Let’s look at another, slightly more complicated problem. Suppose, as part of an
ongoing climate study, we are tracking daily maximum water temperatures recorded
by a drifting buoy in the Atlantic Ocean. We would like to compute the average (or
mean) of these temperatures over one year. Suppose our list of high temperature
readings (in degrees Celsius) starts like this:
18.9, 18.9, 19.0, 19.2, 19.3, 19.3, 19.2, 19.1, 19.4, 19.3, ...
Reflection 1.5 What are the input and output for this problem? Think carefully
about all the information you need in the input. Express your output in terms of the
input.
The input to the mean temperature problem obviously includes the list of tempera-
tures. We also need to know how many temperatures we have, since we need to divide
by that number. The output is the mean temperature of the list of temperatures.
Reflection 1.6 What algorithm can we use to find the mean daily temperature?
Think in terms of the steps we followed in the algorithms to compute the volume of
a sphere.
Of course, we know that we need to add up all the temperatures and divide by the
number of days. But even a direction as simple as “add up all the temperatures” is too
complex for a computer to execute directly. As we will see in Section 1.4, computers
are, at their core, only able to execute instructions on par with simple arithmetic
on two numbers at a time. Any complexity or “intelligence” that we attribute to
computers is actually attributable to human beings harnessing this simple palette of
instructions in creative ways. Indeed, this example raises two necessary characteristics
of computer algorithms: their steps must be both unambiguous and executable by a
computer. In other words, the steps that a computer algorithm follows must correlate
to things a computer can actually do, without inviting creative interpretation by a
human being.
These two requirements are not really unique to computer algorithms. For example,
we hope that new surgical techniques are unambiguously presented and reference
actual anatomy and real surgical tools. Likewise, when an architect designs a
building, she must take into account the materials available and be precise about
their placement. And when an author writes a novel, he must write to his audience,
using appropriate language and culturally familiar references.
To get a handle on how to translate “add up all the temperatures” into something
a computer can understand, let’s think about how we would do this without a
8 What is computation?
Since this 367-step algorithm is pretty cumbersome to write, and steps 2–366 are
essentially the same, we can shorten the description of the algorithm by substituting
steps 2–366 with
For each temperature t in our list, repeat the following:
add t to the running sum, and assign the result to be the new
running sum.
In this shortened representation, which is called a loop, t stands in for each temper-
ature. First, t is assigned the first temperature in the list, 18.9, which the indented
statement adds to the running sum. Then t is assigned the second temperature, 18.9,
which the indented statement next adds to the running sum. Then t is assigned the
third temperature, 19.0. And so on. With this substitution (in red), our algorithm
becomes:
Algorithms and programs 9
We can visualize the execution of this loop more explicitly by “unrolling” it into its
equivalent sequence of statements. The statement indented under step 2 is executed
once for each different value of t in the list. Each time, the running sum is updated.
So, if our list of temperatures is the same as before, this loop is equivalent to the
following sequence of statements:
(a) Add 18.9 to 0 , and assign 18.9 to be the new running sum.
± ® ±
t the running sum the result
(b) Add 18.9 to 18.9 , and assign 37.8 to be the new running sum.
± ± ±
t the running sum the result
(c) Add 19.0 to 37.8 , and assign 56.8 to be the new running sum.
± ± ±
t the running sum the result
Another important benefit of the loop representation is that it renders the algorithm
representation independent of the length of the list of temperatures. In Mean Tem-
perature 1, we had to know up front how many temperatures there were because
we needed one statement for each temperature. However, in Mean Temperature
2, there is no mention of 365, except in the final statement; the loop simply repeats
as long as there are temperatures remaining. Therefore, we can generalize Mean
Temperature 2 to handle any number of temperatures. Actually, there is nothing
in the algorithm that depends on these values being temperatures at all, so we
should also generalize it to handle any list of numbers. If we let n denote the length
of the list, then our generalized algorithm looks like the following:
10 What is computation?
Algorithm Mean
Input: a list of n numbers
1. Initialize the running sum to 0.
2. For each number t in our list, repeat the following:
Add t to the running sum, and assign the result to be the new
running sum.
3. Divide the running sum by n, and assign the result to be the mean.
Output: the mean
As you can see, there are often different, but equivalent, ways to represent an
algorithm. Sometimes the one you choose depends on personal taste and the pro-
gramming language in which you will eventually express it. Just to give you a sense
of what is to come, we can express the Mean algorithm in Python like this:
def mean(values):
n = len(values)
sum = 0
for number in values:
sum = sum + number
mean = sum / n
return mean
Try to match the statements in Mean to the statements in the program. By doing
so, you can get a sense of what each part of the program must do. We will flesh
this out in more detail later, of course; in a few chapters, programs like this will
be second nature. As we pointed out earlier, once you are comfortable with this
notation, you will likely find it much less cumbersome and more clear than writing
everything in full sentences, with the inherent ambiguities that tend to emerge in
the English language.
Exercises
1.2.1. Describe three examples from your everyday life in which an abstraction is beneficial.
Explain the benefits of each abstraction versus what life would be like without it.
1.2.2. Write an algorithm to find the minimum value in a list of numbers. Like the
Mean algorithm, you may only examine one number at a time. But instead of
remembering the current running sum, remember the current minimum value.
1.2.3. You are organizing a birthday party where cookies will be served. On the invite
list are some younger children and some older children. The invite list is given in
shorthand as a list of letters, y for a young child and o for an older child. Each
older child will eat three cookies, while each younger child will eat two cookies.
Efficient algorithms 11
Write an algorithm that traces through the list, and prints how many cookies are
needed. For example, if the input were y, y, o, y, o then the output should be 12
cookies.
1.2.4. Write an algorithm for each player to follow in a simple card game like Blackjack
or Go Fish. Assume that the cards are dealt in some random order.
1.2.5. Write an algorithm to sort a stack of any 5 cards by value in ascending order. In
each step, your algorithm may compare or swap the positions of any two cards.
1.2.6. Write an algorithm to walk between two nearby locations, assuming the only legal
instructions are “Take s steps forward,” and “Turn d degrees to the left,” where s
and d are positive integers.
(For simplicity, we will assume that everyone answers the phone right away and
every phone call takes the same amount of time.) Is this the best algorithm for
solving the problem? What does “best” even mean?
Reflection 1.7 For the “phone tree” problem, what characteristics would make one
algorithm better than another?
As the question suggests, deciding whether one algorithm is better than another
12 What is computation?
(a) A 1 B 2 C 3 D 4 E 5 F 6 G 7 H
A
(b)
4
3 5
2 6
1 7
B C D E F G H
1 2
(c) B C
2 3 3 4
D E F G
3
depends on your criteria. For the “phone tree” problem, your primary criterion may
be to make as few calls as possible yourself, delegating most of the work to others.
The Alphabetical Phone Tree algorithm, graphically depicted in Figure 1.3(a),
is one way to satisfy this criterion. Alternatively, you may feel guilty about making
others do any work, so you decide to make all the calls yourself; this is depicted
in Figure 1.3(b). However, in the interest of community safety, we should really
organize the phone tree so that the last person is notified of the emergency as soon
as possible. Both of the previous two algorithms fail miserably in this regard. In fact,
they both take the longest possible time! A better algorithm would have you call
two people, then each of those people call two people, and so on. This is depicted in
Figure 1.3(c). Notice that this algorithm notifies everyone in only four steps because
more than one phone call happens concurrently; A and B are both making calls
during the second step; and B, C, and D are all making calls in the third step.
If all of the calls were utilizing a shared resource (such as a wireless network),
we might need to balance the time with the number of simultaneous calls. This
may not seem like an issue with only eight people in our phone tree, but it would
become a significant issue with many more people. For example, applying the
algorithm depicted in Figure 1.3(c) to thousands of people would result in thousands
of simultaneous calls.
Let’s now consider how these concerns might apply to algorithms more generally.
Efficient algorithms 13
(a) (b)
Plot of (a) a year’s worth of daily high temperature readings and (b) the
Figure 1.4
temperature readings smoothed over a five-day window.
Reflection 1.8 What general characteristics might make one algorithm for a par-
ticular problem better than another algorithm for the same problem?
As was the case in the phone tree problem, the most important hallmark of a good
algorithm is speed; given the choice, we almost always want the algorithm that
requires the least amount of time to finish. (Would you rather wait five minutes
for a web search or half of a second?) But there are other attributes as well that
can distinguish one algorithm from another. For example, we saw in Section 1.2
how a long, tedious algorithm can be represented more compactly using a loop;
the more compact version is easier to write down and translate into a program.
The compact version also requires less space in a computer’s memory. Because the
amount of storage space in a computer is limited, we want to create algorithms that
use as little of this resource as possible to store both their instructions and their
data. Efficient resource usage may also apply to network capacity, as in the phone
tree problem on a wireless network. In addition, just as writers and designers strive
to create elegant works, computer scientists pride themselves on writing elegant
algorithms that are easy to understand and do not contain extraneous steps. And
some advanced algorithms are considered to be especially important because they
introduce new techniques that can be applied to solve other hard problems.
A smoothing algorithm
To more formally illustrate how we can evaluate the time required by an algorithm,
let’s revisit the sequence of temperature readings from the previous section. Often,
when we are dealing with large data sets (much longer than this), anomalies can
arise due to errors in the sensing equipment, human fallibility, or in the network used
to send results to a lab or another collection point. We can mask these erroneous
measurements by “smoothing” the data, replacing each value with the mean of
the values in a “window” of values containing it. This technique is also useful for
14 What is computation?
(a) (b)
Figure 1.5Plot of (a) the ten high temperature readings and (b) the temperature
readings smoothed over a five-day window.
18.9, 18.9, 19.0, 19.2, 19.3, 19.3, 19.2, 22.1, 19.4, 19.3
The plot of this data in Figure 1.5(a) illustrates this erroneous “bump.”
Now let’s smooth the data by averaging over windows of size five. For each value
in the original list, its window will include itself and the four values that come
before it. Our algorithm will need to compute the mean of each of these windows,
and then add each of these means to a new smoothed list. The last four values do
not have four more values after them, so our smoothed list will contain four fewer
values than our original list. The first window looks like this:
18.9, 18.9, 19.0, 19.2, 19.3 19.3, 19.2, 22.1, 19.4, 19.3
´¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¸¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¶
mean = 95.3 / 5 = 19.06
To find the mean temperature for the window, we sum the five values and divide by
5. The result, 19.06, will represent this window in the smoothed list. The remaining
five windows are computed in the same way:
18.9, 18.9, 19.0, 19.2, 19.3, 19.3, 19.2, 22.1, 19.4, 19.3
´¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¸¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¶
mean = 95.7 / 5 = 19.14
Efficient algorithms 15
18.9, 18.9, 19.0, 19.2, 19.3, 19.3, 19.2, 22.1, 19.4, 19.3
´¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¸¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¶
mean = 96.0 / 5 = 19.20
18.9, 18.9, 19.0, 19.2, 19.3, 19.3, 19.2, 22.1, 19.4, 19.3
´¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¸¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¶
mean = 99.1 / 5 = 19.82
18.9, 18.9, 19.0, 19.2, 19.3, 19.3, 19.2, 22.1, 19.4, 19.3
´¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¸¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¶
mean = 99.3 / 5 = 19.86
18.9, 18.9, 19.0, 19.2, 19.3, 19.3, 19.2, 22.1, 19.4, 19.3
´¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¸¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¶
mean = 99.3 / 5 = 19.86
We can see from the plot of this smoothed list in Figure 1.5(b) that the “bump” has
indeed been smoothed somewhat.
We can express our smoothing algorithm using notation similar to our previous
algorithms. Notice that, to find each of the window means in our smoothing algorithm,
we call upon our Mean algorithm from Section 1.2.
Algorithm Smooth
Input: a list of n numbers and a window size w
1. Create an empty list of mean values.
2. For each position d, from 1 to n − w + 1, repeat the following:
(a) invoke the Mean algorithm on the list of numbers between
positions d and d + w − 1;
(b) append the result to the list of mean values.
Output: the list of mean values
Step 1 creates an empty list to hold the window means. We will append the mean
for each window to the end of this list after we compute it. Step 2 uses a loop to
compute the means for all of the windows. This loop is similar to the loop in the
Mean algorithm: the variable d takes on the values between 1 and n − w + 1, like t
took on each value in the list in the Mean algorithm. First, d is assigned the value
1, and the mean of the window between positions 1 and 1 + w − 1 = w is added to
the list of mean values. Then d is assigned the value 2, and the mean of the window
between positions 2 and 2 + w − 1 = w + 1 is added to the list of mean values. And so
on, until d takes on the value of n − w + 1, and the mean of the window between
positions n − w + 1 and (n − w + 1) + w − 1 = n is added to the list of mean values.
16 What is computation?
Reflection 1.9 Carry out each step of the Smooth algorithm with w = 5 and the
ten-element list in our example:
18.9, 18.9, 19.0, 19.2, 19.3, 19.3, 19.2, 22.1, 19.4, 19.3
Compare each step with what we worked out above to convince yourself that the
algorithm is correct.
Reflection 1.10 Based on this analysis, what are the elementary steps in this
algorithm? How many times are they each executed?
The only elementary steps we have identified are creating a list, appending to a
list, and arithmetic operations. Let’s start by counting the number of arithmetic
operations that are required. If each window has size five, then we perform five
Efficient algorithms 17
addition operations and one division operation each time we invoke the Mean
algorithm, for a total of six arithmetic operations per window. Therefore, the total
number of arithmetic operations is six times the number of windows. In general, the
window size is denoted w and there are n − w + 1 windows. So the algorithm performs
w additions and one division per window, for a total of (w + 1) ⋅ (n − w + 1) arithmetic
operations. For example, smoothing a list of 365 temperatures with a window size
of five days will require (w + 1) ⋅ (n − w + 1) = 6 ⋅ (365 − 5 + 1) = 2, 166 arithmetic
operations. In addition to the arithmetic operations, we create the list once and
append to the list once for every window, a total of n − w + 1 times. Therefore, the
total number of elementary steps is
(w + 1) ⋅ (n − w + 1) + 1 + n − w + 1 .
´¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹¸ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹¶ ® ´¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹¸¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¶
arithmetic create appends
list
The sum for the second window must be almost the same as the first window, since
they have four numbers in common. The only difference in the second window is
that it loses the first 18.9 and gains 19.3. So once we have the sum for the first
window (95.3), we can get the sum of the second window with only two additional
arithmetic operations: 95.3 − 18.9 + 19.3 = 95.7.
18.9, 18.9, 19.0, 19.2, 19.3, 19.3, 19.2, 22.1, 19.4, 19.3
´¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¸¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¶
sum = 95.7
18 What is computation?
We can apply this process to every subsequent window as well. At the end of the
algorithm, once we have the sums for all of the windows, we can simply divide each
by its window length to get the final list of means. Written in the same manner as
the previous algorithms, our new smoothing algorithm looks like this:
Algorithm Smooth 2
Input: a list of n numbers and a window size w
1. Create an empty list of window sums.
2. Compute the sum of the first w numbers and
append the result to the list of window sums.
3. For each position d, from 2 to n − w + 1, repeat the following:
(a) subtract the number in position d − 1 from the previous window
sum and then add the number in position d + w − 1;
(b) append the result to the list of window sums.
4. For each position d, from 1 to n − w + 1, repeat the following:
(a) divide the dth window sum by w.
Output: the list of mean values
Step 2 computes the sum for the first window and adds it to a list of window sums.
Step 3 then computes the sum for each subsequent window by subtracting the
number that is lost from the previous window and adding the number that is gained.
Finally, step 4 divides all of the window sums by w to get the list of mean values.
Reflection 1.12 As with the previous algorithm, carry out each step of the Smooth
2 algorithm with w = 5 and the ten-element list in our example:
18.9, 18.9, 19.0, 19.2, 19.3, 19.3, 19.2, 22.1, 19.4, 19.3
Does the Smooth 2 algorithm actually require fewer elementary steps than our
first attempt? Let’s look at each step individually. As before, step 1 counts as one
elementary step. Step 2 requires w − 1 addition operations and one append, for a
total of w elementary steps. Step 3 performs an addition, a subtraction, and an
append for every window but the first, for a total of 3(n − w) elementary steps.
Finally, step 4 performs one division operation per window, for a total of n − w + 1
arithmetic operations. This gives us a total of
1 + w + 3 (n − w) + n − w + 1
® ® ´¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¸¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¶ ´¹¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹¸¹ ¹ ¹ ¹ ¹ ¹ ¹ ¹ ¶
create first divisions
other
list window windows
Efficient algorithms 19
elementary steps. Combining all of these terms, we find that the time complexity of
Smooth 2 is 4n − 3w + 2. Therefore, our old algorithm requires
(w + 2) ⋅ (n − w + 1) + 1
4n − 3w + 2
times as many operations as the new one. It is hard to tell from this fraction, but
our new algorithm is about w/4 times faster than our old one. To see this, suppose
our list contains n = 10, 000 temperature readings. The following table shows the
value of the fraction for increasing window sizes w.
w Speedup
5 1.7
10 3.0
20 5.5
100 25.4
500 123.9
1,000 243.7
When w is small, our new algorithm does not make much difference, but the difference
becomes quite pronounced when w gets larger. In real applications of smoothing on
extremely large data sets containing billions or trillions of items, window sizes can
be as high as w = 100, 000. For example, smoothing is commonly used to visualize
statistics over DNA sequences that are billions of units long. So our refined algorithm
can have a marked impact! Indeed, as we will examine further in Section 6.4, it is
often the case that a faster algorithm can reduce the time required for a computation
significantly more than faster hardware.
Exercises
1.3.1. The phone tree algorithm depicted in Figure 1.3(c) comes very close to making
all of the phone calls in three steps. Is it possible to actually achieve three steps?
How?
1.3.2. Suppose the phone tree algorithm illustrated in Figure 1.3(c) was being executed
with a large number of people. We saw one call made during the first time step,
two calls during the second time step, and three calls during the third time step.
(a) How many concurrent calls would be made during time steps 4, 5, and 6?
(b) In general, can you provide a formula (or algorithm) to determine the number
of calls made during any time step t?
1.3.3. Describe the most important criterion for evaluating how good an algorithm is.
Then add at least one more criterion and describe how it would be applied to
algorithms for some everyday problem.
1.3.4. What is the time complexity of the Mean algorithm on Page 10, in terms of n
(the size of the input list)?
20 What is computation?
processors memory
core 1
HD / SSD Internet printer
core 2
bus
Inside a computer
The types of instructions that constitute a machine language are based on the internal
design of a modern computer. As illustrated in Figure 1.6, a computer essentially
consists of one or more processors connected to a memory. A computer’s memory,
Computers are dumb 21
often called RAM (short for random access memory), is conceptually organized as
a long sequence of cells, each of which can contain one unit of information. Each
cell is labeled with a unique memory address that allows the processor to reference
it specifically. So a computer’s memory is like a huge sequence of equal-sized post
office boxes, each of which can hold exactly one letter. Each P.O. box number is
analogous to a memory address and a letter is analogous to one unit of information.
The information in each cell can represent either one instruction or one unit of
data.1 So a computer’s memory stores both programs and the data on which the
programs work.
A processor, often called a CPU (short for central processing unit) or a core,
contains both the machinery for executing instructions and a small set of memory
locations called registers that temporarily hold data values needed by the current
instruction. If a computer contains more than one core, as most modern computers
do, then it is able to execute more than one instruction at a time. These instructions
may be from different programs or from the same program. This means that our
definition of an algorithm as a sequence of instructions on Page 7 is not strictly
correct. In fact, an algorithm (or a program) may consist of several semi-independent
sequences of steps called threads that cooperatively solve a problem.
As illustrated in Figure 1.6, the processors and memory are connected by a
communication channel called a bus. When a processor needs a value in memory,
it transmits the request over the bus, and then the memory returns the requested
value the same way. The bus also connects the processors and memory to several
other components that either improve the machine’s efficiency or its convenience,
like the Internet and secondary storage devices like hard drives, solid state drives,
and flash memory. As you probably know, the contents of a computer’s memory are
lost when the computer loses power, so we use secondary storage to preserve data
for longer periods of time. We interact with these devices through a “file system”
abstraction that makes it appear as if our hard drives are really filing cabinets.
When you execute a program or open a file, it is first copied from secondary storage
into memory where the processor can access it.
Machine language
The machine language instructions that a processor can execute are very simple. For
example, consider something as simple as computing x = 2 + 5. In a program, this
statement adds 2 and 5, and stores the result in a memory location referred to by
the variable x. But even this is likely to be too complex for one machine language
instruction. The machine language equivalent likely, depending on the computer,
consists of four instructions. The first instruction loads the value 2 into a register in
the processor. The second instruction loads the value 5 into another register in the
processor. The third instruction adds the values in these two registers, and stores
1
In reality, each instruction or unit of data usually occupies multiple contiguous cells.
22 What is computation?
the result in a third register. Finally, the fourth instruction stores the value in the
third register into the memory cell with address x.
From the moment a computer is turned on, its processors are operating in a
continuous loop called the fetch and execute cycle (or machine cycle). In each cycle,
the processor fetches one machine language instruction from memory and executes
it. This cycle repeats until the computer is turned off or loses power. In a nutshell,
this is all a computer does. The rate at which a computer performs the fetch and
execute cycle is loosely determined by the rate at which an internal clock “ticks”
(the processor’s clock rate). The ticks of this clock keep the machine’s operations
synchronized. Modern personal computers have clocks that tick a few billion times
each second; a 3 gigahertz (GHz) processor ticks 3 billion times per second (“giga”
means “billion” and a “hertz” is one tick per second).
So computers, at their most basic level, really are quite dumb; the processor
blindly follows the fetch and execute cycle, dutifully executing whatever sequence
of simple instructions we give it. The frustrating errors that we yell at computers
about are, in fact, human errors. The great thing about computers is not that they
are smart, but that they follow our instructions so very quickly; they can accomplish
an incredible amount of work in a very short amount of time.
Everything is bits
Our discussion so far has glossed over a very important consideration: in what
form does a computer store programs and data? In addition to machine language
instructions, we need to store numbers, documents, maps, images, sounds, presenta-
tions, spreadsheets, and more. Using a different storage medium for each type of
information would be insanely complicated and inefficient. Instead, we need a simple
storage format that can accommodate any type of data. The answer is bits. A bit
Computers are dumb 23
is the simplest possible unit of information, capable of taking on one of only two
values: 0 or 1 (or equivalently, off/on, no/yes, or false/true). This simplicity makes
both storing information (i.e., memory) and computing with it (e.g., processors)
relatively simple and efficient.
0100010001010101
This bit sequence can represent each of the following, depending upon how it is
interpreted:
(d) the Intel machine language instruction inc x (inc is short for “increment”);
or
(e) the following 4 × 4 black and white image, called a bitmap (0 represents a
white square and 1 represents a black square).
Other documents randomly have
different content
that they have to endure the same hardships, may, and very often
does, exercise pressure upon the authorities to surrender. Further,
should the commander of a besieged place expel the non-
combatants in order to lessen the number of those who consume his
store of provisions, the besieging force need not allow them to pass
through its lines, but may drive them back.[302]
[300] See above, § 110.
[301] Thus in 1870, during the Franco-German War, the German besiegers of Strassburg
as well as of Belfort allowed the women, the children, and the sick to leave the besieged
fortresses.
[302] See Land Warfare, § 129.
X
ESPIONAGE AND TREASON
Punishment of Espionage.
§ 161. The usual punishment for spying is hanging or shooting,
but less severe punishments are, of course, admissible and
sometimes inflicted. However this may be, according to article 30 of
the Hague Regulations a spy may not be punished without a trial
before a court-martial. And according to article 31 of the Hague
Regulations a spy who is not captured in the act but rejoins the
army to which he belongs, and is subsequently captured by the
enemy, may not be punished for his previous espionage and must be
treated as a prisoner of war. But it must be specially observed that
article 31 concerns only such spies as belong to the armed forces of
the enemy; civilians who act as spies and are captured later may be
punished. Be that as it may, no regard is paid to the status, rank,
position, or motive of a spy. He may be a soldier or a civilian, an
officer or a private. He may be following instructions of superiors or
acting on his own initiative from patriotic motives. A case of
espionage, remarkable on account of the position of the spy, is that
of the American Captain Nathan Hale, which occurred in 1776. After
the American forces had withdrawn from Long Island, Captain Hale
recrossed under disguise and obtained valuable information about
the English forces that had occupied the island. But he was caught
before he could rejoin his army, and he was executed as a spy.[313]
[313]The case of Major Jakoga and Captain Oki, which, though reported as a case of
espionage, is really a case of treason, will be discussed below in § 255.
Treason.
§ 162. Treason can be committed by a soldier or an ordinary
subject of a belligerent, but it can also be committed by an
inhabitant of an occupied enemy territory or even by the subject of a
neutral State temporarily staying there, and it can take place after
an arrangement with the favoured belligerent or without such an
arrangement. In any case a belligerent making use of treason acts
lawfully, although the Hague Regulations do not mention the matter
at all. But many acts of different sorts can be treasonable; the
possible cases of treason and the punishment of treason will be
discussed below in § 255.
Although it is generally recognised that a belligerent acts lawfully
who makes use of the offer of a traitor, the question is
controversial[314] whether a belligerent acts lawfully who bribes a
commander of an enemy fortress into surrender, incites enemy
soldiers to desertion, bribes enemy officers for the purpose of
getting important information, incites enemy subjects to rise against
the legitimate Government, and the like. If the rules of the Law of
Nations are formulated, not from doctrines of book-writers, but from
what is done by the belligerents in practice,[315] it must be asserted
that such acts, detestable and immoral as they are, are not
considered illegal according to the Law of Nations.
[314] See Vattel, III. § 180; Heffter, § 125; Taylor, § 490; Martens, II. § 110 (8); Longuet,
§ 52; Mérignhac, p. 188, and others. See also below, § 164.
[315] See Land Warfare, § 158.
XI
RUSES
[316] See Land Warfare, § 144, where a great number of legitimate ruses are
enumerated.
[317] See the examples quoted by Pradier-Fodéré, VI. No. 2761.
[318] See Pradier-Fodéré, VI. No. 2760.
[319] The point has been discussed above in § 162.
[320] See, for instance, Hall, § 187; Bluntschli, § 565; Taylor, § 488; Calvo, IV. No. 2106;
Pillet, p. 95; Longuet, § 54. But, on the other hand, the number of publicists who
consider it illegal to make use of the enemy flag, ensigns, and uniforms, even before an
actual attack, is daily becoming larger; see, for instance, Lueder in Holtzendorff, IV. p.
458; Mérignhac, p. 166; Pradier-Fodéré, VI. No. 2760; Bonfils, No. 1074; Kriegsbrauch,
p. 24. As regards the use of the enemy flag on the part of men-of-war, see below, in §
211.
[321] Some writers maintain that article 23 (f) of the Hague Regulations has settled the
controversy, but they forget that this article speaks only of the improper use of the
enemy ensigns and uniform. See Land Warfare, § 152.
[322] The use of the enemy uniform for the purpose of deceit is different from the case
when members of armed forces who are deficient in clothes wear the uniforms of
prisoners or of the enemy dead. If this is done—and it always will be done if necessary—
such distinct alterations in the uniform ought to be made as will make it apparent to
which side the soldiers concerned belong (see Land Warfare, § 154). Different again is
the case where soldiers are, through lack of clothing, obliged to wear the apparel of
civilians, such as greatcoats, hats, and the like. Care must then be taken that the soldiers
concerned do nevertheless wear a fixed distinctive emblem which marks them as
soldiers, since otherwise they lose the privileges of members of the armed forces of the
belligerents (see article 1, No. 2, of the Hague Regulations). During the Russo-Japanese
War both belligerents repeatedly accused each other of using Chinese clothing for
members of their armed forces; the soldiers concerned apparently were obliged through
lack of proper clothing temporarily to make use of Chinese garments. See, however,
Takahashi, pp. 174-178.
XII
OCCUPATION OF ENEMY TERRITORY
CHAPTER IV
WARFARE ON SEA
I
ON SEA WARFARE IN GENERAL
Declaration of Paris.
§ 177. Things began to undergo a change with the outbreak of the
Crimean War in 1854, when all the belligerents proclaimed that they
would not issue Letters of Marque, and when, further, Great Britain
declared that she would not seize enemy goods on neutral vessels,
and when, thirdly, France declared that she would not appropriate
neutral goods on enemy vessels. Although this alteration of attitude
on the part of the belligerents was originally intended for the
Crimean War only and exceptionally, it led after the conclusion of
peace in 1856 to the famous and epoch-making Declaration of Paris,
[346]
which enacted the four rules—(1) that privateering is abolished,
(2) that the neutral flag covers enemy goods[347] with the exception
of contraband of war, (3) that neutral goods, contraband of war
excepted, are not liable to capture under the enemy flag, (4) that
blockades, in order to be binding, must be effective, which means
maintained by a force sufficient really to prevent access to the coast
of the enemy. Since, with the exception of a few States such as the
United States of America, Colombia, Venezuela, Bolivia, and
Uruguay, all members of the Family of Nations are now parties to the
Declaration of Paris, it may well be maintained that the rules quoted
are general International Law, the more so as the non-signatory
Powers have hitherto in practice always acted in accordance with
those rules.[348]
[346] See Martens, N.R.G. XV. p. 767, and above, vol. I. § 559.
[347] It has been asserted—see, for instance, Rivier, II. p. 429—that the neutral flag
covers only private, not public, enemy property, and therefore that such goods on neutral
vessels as belong to the State of the enemy may be seized and appropriated. This
opinion would seem, however, to be untenable in face of the fact that the Declaration of
Paris speaks of marchandise neutre without any qualification, only excepting contraband
goods, thus protecting the whole of the cargo under the neutral flag, contraband
excepted. See below, § 319, p. 385, note 3.
[348] That there is an agitation for the abolition of the Declaration of Paris has been
mentioned above, § 83, p. 100, note 3.
The Principle of Appropriation of Private Enemy Vessels and Enemy Goods thereon.
§ 178. The Declaration of Paris did not touch upon the old rule
that private enemy vessels and private enemy goods thereon may be
seized and appropriated, and this rule is, therefore, as valid as ever,
although there is much agitation for its abolition. In 1785 Prussia
and the United States of America had already stipulated by article 23
of their Treaty of Friendship[349] that in case of war between the
parties each other's merchantmen shall not be seized and
appropriated. Again, in 1871 the United States and Italy, by article
12 of their Treaty of Commerce,[350] stipulated that in case of war
between the parties each other's merchantmen, with the exception
of those carrying contraband of war or attempting to break a
blockade, shall not be seized and appropriated. In 1823 the United
States had already made the proposal to Great Britain, France, and
Russia[351] for a treaty abrogating the rule that enemy merchantmen
and enemy goods thereon may be appropriated; but Russia alone
accepted the proposal under the condition that all other naval
Powers should consent. Again, in 1856,[352] on the occasion of the
Declaration of Paris, the United States endeavoured to obtain the
victory of the principle that enemy merchantmen shall not be
appropriated, making it a condition of their accession to the
Declaration of Paris that this principle should be recognised. But
again the attempt failed, owing to the opposition of Great Britain.
[349] See Martens, R. IV. p. 37. Perels (p. 198) maintains that this article has not been
adopted by the Treaty of Commerce between Prussia and the United States of May 1,
1828; but this statement is incorrect, for article 12 of this treaty—see Martens, N.R. VII.
p. 615—adopts it expressly.
[350] See Martens, N.R.G. 2nd Ser. I. p. 57.
[351] See Wharton, III. § 342, pp. 260-261, and Moore, VII. § 1198, p. 465.
[352] See Wharton, III. § 342, pp. 270-287, and Moore, VII. § 1198, p. 466.
At the outbreak of war in 1866, Prussia and Austria expressly
declared that they would not seize and appropriate each other's
merchantmen. At the outbreak of the Franco-German War in 1870,
Germany declared French merchantmen exempt from capture, but
she changed her attitude when France did not act upon the same
lines. It should also be mentioned that already in 1865 Italy, by
article 211 of her Marine Code, enacted that, in case of war with any
other State, enemy merchantmen not carrying contraband of war or
breaking a blockade shall not be seized and appropriated, provided
reciprocity be granted. And it should further be mentioned that the
United States of America made attempts[353] in vain to secure
immunity from capture to enemy merchantmen and goods on sea at
the First as well as at the Second Hague Peace Conference.
[353]See Holls, The Peace Conference at the Hague, pp. 306-321, and Scott,
Conferences, pp. 699-707.
It cannot be denied that the constant agitation, since the middle
of the eighteenth century, in favour of the abolition of the rule that
private enemy vessels and goods may be captured on the High Seas,
might, during the second half of the nineteenth century, have met
with success but for the decided opposition of Great Britain. Public
opinion in Great Britain was not, and is not, prepared to consent to
the abolition of this rule. And there is no doubt that the abolition of
the rule would involve a certain amount of danger to a country like
Great Britain whose position and power depend chiefly upon her
navy. The possibility of annihilating an enemy's commerce by
annihilating his merchant fleet is a powerful weapon in the hands of
a great naval Power. Moreover, if enemy merchantmen are not
captured, they can be fitted out as cruisers, or at least be made use
of for the transport of troops, munitions, and provisions. Have not
several maritime States made arrangements with their steamship
companies to secure the building of their Transatlantic liners
according to plans which make these merchantmen easily
convertible into men-of-war?
The argument that it is unjust that private enemy citizens should
suffer through having their property seized has no weight in face of
the probability that fear of the annihilation of its merchant fleet in
case of war may well deter a State intending to go to war from
doing so. It is a matter for politicians, not for jurists, to decide
whether Great Britain must in the interest of self-preservation
oppose the abolition of the rule that sea-borne private enemy
property may be confiscated.
However this may be, since the end of the nineteenth century it
has not been the attitude of Great Britain alone which stands in the
way of the abolition of the rule. Since the growth of navies among
continental Powers, these Powers have learnt to appreciate the value
of the rule in war, and the outcry against the capture of
merchantmen has become less loud. To-day, it may perhaps be said
that, even if Great Britain were to propose the abolition of the rule,
it is probable that a greater number of the maritime States would
refuse to accede. For it should be noted that at the Second Peace
Conference, France, Russia, Japan, Spain, Portugal, Mexico,
Colombia, and Panama, besides Great Britain, voted against the
abolition of the rule. And there is noticeable a slow, but constant,
increase in the number of continental publicists[354] who oppose the
abolition of the once so much objected to practice of capturing
enemy merchantmen.
[354] See, for instance, Perels, § 36, pp. 195-198; Röpcke, Das Seebeuterecht (1904),
pp. 36-47; Dupuis, Nos. 29-31; Pillet, p. 119; Giordana, La proprieta privata nelle guerre
maritime, etc. (1907); Niemeyer, Prinzipien des Seekriegsrechts (1909); Boidin, pp. 144-
167. On the other hand, the Institute of International Law has several times voted in
favour of the abolition of the rule; see Tableau Général de l'Institut de droit International
(1893), pp. 190-193. The literature concerning the question of confiscation of private
enemy property on sea is abundant. The following authors, besides those already quoted
above at the commencement of § 173, may be mentioned:—Upton, The Law of Nations
affecting Commerce during War (1863); Cauchy, Du respect de la propriété privée dans
la guerre maritime (1866); Vidari, Del rispetto della proprietà privata fra gli stati in
guerra (1867); Gessner, Zur Reform des Kriegsseerechts (1875); Klobukowski, Die
Seebeute oder das feindliche Privateigenthum zur See (1877); Bluntschli, Das Beuterecht
im Kriege und das Seebeuterecht insbesondere (1878); Boeck, De la propriété privée
ennemie sous pavillon ennemi (1882); Dupuis, La guerre maritime et les doctrines
anglaises (1899); Leroy, La guerre maritime (1900); Röpcke, Das Seebeuterecht (1904);
Hirst, Commerce and Property in Naval Warfare: A Letter of the Lord Chancellor (1906);
Hamman, Der Streit um das Seebeuterecht (1907); Wehberg, Das Beuterecht im Land
und Seekrieg (1909); Cohen, The Immunity of Enemy's Property from Capture at Sea
(1909); Macdonell, Some plain Reasons for Immunity from Capture of Private Property at
Sea (1910). See also the literature quoted by Bonfils, No. 1281, Pradier-Fodéré, VIII.
Nos. 3070-3090, and Boeck, Nos. 382-572, where the arguments of the authors against
and in favour of the present practice are discussed.
ebookbell.com