<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>apnorton</title><link>http://apnorton.com/</link><description>Recent content on apnorton</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>&amp;copy; 2016-2023 Andrew Norton</copyright><lastBuildDate>Mon, 19 Jun 2023 17:43:01 -0400</lastBuildDate><atom:link href="http://apnorton.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Downloading an HLS Stream with ffmpeg</title><link>http://apnorton.com/blog/2023/06/19/downloading-hls-stream/</link><pubDate>Mon, 19 Jun 2023 17:43:01 -0400</pubDate><guid>http://apnorton.com/blog/2023/06/19/downloading-hls-stream/</guid><description>&lt;p>I recently encountered a video served with an HLS stream that I wanted to have a copy of, but the website did not support downloading it. Trying &lt;code>yt-dlp&lt;/code> yielded no results (it was not one of the &amp;ldquo;common&amp;rdquo; websites), but I did learn that &lt;code>ffmpeg&lt;/code> supports conversion of HLS streams directly to a file. I referenced a &lt;a href="https://www.codementor.io/@chuksdurugo/download-and-combine-media-segments-of-a-hls-stream-locally-using-ffmpeg-150zo6t775" target="_blank">blog post on codementor.io&lt;/a>, though I&amp;rsquo;m sure that the same information is present in many other locations online.&lt;/p></description></item><item><title>Meeting Don Knuth</title><link>http://apnorton.com/blog/2018/12/07/Meeting-Don-Knuth/</link><pubDate>Fri, 07 Dec 2018 12:00:00 +0000</pubDate><guid>http://apnorton.com/blog/2018/12/07/Meeting-Don-Knuth/</guid><description>&lt;p>Everyone has heroes, but not everyone gets to meet them. This past Tuesday, I was fortunate to meet one of mine — Don Knuth. If you are in computer science and don’t know who Don Knuth is, I highly recommend you take a break from this post and do a bit of reading about him. He is most well-known for authoring his (still in progress) Art of Computer Programming, a compendium of all kinds of information on algorithms, but his contributions to computer science and software development reach far beyond that. He invented TeX (precursor to LaTeX), wrote Concrete Mathematics (a great mathematical foundations of computer science book), and received a Turing award.&lt;/p>

&lt;div class="fig_container">
&lt;img class="fig_image" src="http://apnorton.com/blog/2018/12/07/Meeting-Don-Knuth/knuth.jpg" alt="Me with Don Knuth"/>
&lt;p class="fig_caption">Me with Don Knuth&lt;/p>
&lt;/div></description></item><item><title>Raspberry Pi Default Groups</title><link>http://apnorton.com/blog/2017/11/25/Raspberry-Pi-Default-Groups/</link><pubDate>Sat, 25 Nov 2017 13:54:28 +0000</pubDate><guid>http://apnorton.com/blog/2017/11/25/Raspberry-Pi-Default-Groups/</guid><description>&lt;p>In setting up my Raspberry Pi for a home fileshare, I noticed the &lt;code>pi&lt;/code> user is a part of several default groups. These are:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1&lt;/span>&lt;span>pi adm dialout cdrom sudo audio video plugdev games users input netdev gpio i2c spi
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>(I&amp;rsquo;m using the 2017-09-07 image of Raspbian Stretch Lite.)&lt;/p>
&lt;p>This looked like a lot of groups to me! To make sure my new user only has the minimum permissions needed, let&amp;rsquo;s look at the what each group is and why it&amp;rsquo;s there.&lt;/p></description></item><item><title>How to Request a Regrade</title><link>http://apnorton.com/blog/2017/07/04/How-to-Request-a-Regrade/</link><pubDate>Tue, 04 Jul 2017 17:02:25 +0000</pubDate><guid>http://apnorton.com/blog/2017/07/04/How-to-Request-a-Regrade/</guid><description>&lt;p>One of the highlights of my time at UVA was working as a teaching assistant for the computer science department. In this capacity, I proctored labs and exams, held office hours, created exam questions, and even graded homework and exams. Due, in part, to the large class sizes of our introductory courses and the necessity of multiple graders for each assignment, most professors have a &amp;ldquo;regrade&amp;rdquo; policy &amp;ndash; if the grader has made an error in grading a student&amp;rsquo;s work, there is a formal process for the student to request a second look at his or her work.&lt;/p>
&lt;p>For CS 2150 (the course I TA&amp;rsquo;d), I was one of two or three TAs who processed most &amp;ndash; if not all &amp;ndash; of the regrades for exams in the past two semesters. Although grades are ideally determined solely by the answer&amp;rsquo;s merit, there are a few simple ways you can make your grader&amp;rsquo;s life easier. (And that&amp;rsquo;s always a good thing, right?)&lt;/p></description></item><item><title>A Brief Exploration of a Möbius Transformation</title><link>http://apnorton.com/blog/2017/04/18/A-Brief-Exploration-of-a-Mobius-Transformation/</link><pubDate>Tue, 18 Apr 2017 20:05:42 +0000</pubDate><guid>http://apnorton.com/blog/2017/04/18/A-Brief-Exploration-of-a-Mobius-Transformation/</guid><description>&lt;p>As part of a recent homework set in my complex analysis course, I was tasked with a problem that required a slight generalization on part of &lt;a href="http://mathworld.wolfram.com/SchwarzsLemma.html" target="_blank">Schwarz&amp;rsquo;s Lemma&lt;/a>:&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Lemma (Schwarz):&lt;/strong> Let $f$ be analytic on the unit disk with $|f(z)| \leq 1$ for all $z$ on the disk and $f(0) = 0$. Then $|f(z)| &amp;lt; |z|$ and $f&amp;rsquo;(0)\leq 1$.&lt;br>
If either $|f(z)|=|z|$ for some $z\neq0$ or if $|f&amp;rsquo;(0)|=1$, then $f$ is a rotation, i.e., $f(z)=az$ for some complex constant $a$ with $|a|=1$.&lt;/p>
&lt;/blockquote>
&lt;p>The homework assignment asked us (within the context of a larger problem) to consider the case when $f(\zeta) = 0$ for some $\zeta \neq 0$ on the interior of the unit disk. The secret to this problem was to find some analytic function $\varphi$ that maps the unit disk to itself, but &lt;em>swaps&lt;/em> $0$ and $\zeta$. Then, we may consider $\varphi^{-1}\circ f\circ \varphi$ and apply Schwarz&amp;rsquo;s Lemma.&lt;/p></description></item><item><title>How I wrote a GroupMe Chatbot in 24 hours</title><link>http://apnorton.com/blog/2017/02/28/How-I-wrote-a-Groupme-Chatbot-in-24-hours/</link><pubDate>Tue, 28 Feb 2017 23:05:39 +0000</pubDate><guid>http://apnorton.com/blog/2017/02/28/How-I-wrote-a-Groupme-Chatbot-in-24-hours/</guid><description>&lt;p>For the past couple years, I have worked as a teaching assistant for UVa&amp;rsquo;s CS 2150 (Program and Data Representation) course. We recently started a &lt;a href="https://groupme.com/" target="_blank">GroupMe&lt;/a> chat for the course staff, and I thought it would be fun to create a chatbot to help remind all the TAs to submit timesheets, keep track of when people are holding office hours, and remember when/where TA meetings are being held. Setting up a basic chatbot is a lot simpler than it sounds and is really fun&amp;ndash;I wrote my bot from scratch using Python in just one day.&lt;/p>

&lt;div class="fig_container">
&lt;img class="fig_image" src="http://apnorton.com/blog/2017/02/28/How-I-wrote-a-Groupme-Chatbot-in-24-hours/screenshot.png" alt="The 2150 chatbot"/>
&lt;p class="fig_caption">The 2150 chatbot&lt;/p>
&lt;/div>


&lt;h2 id="groupme-bot-overview">GroupMe Bot Overview&lt;a class="anchorjs-link" href="#groupme-bot-overview">&lt;/a>&lt;/h2>&lt;p>GroupMe has a very &lt;a href="https://dev.groupme.com/tutorials/bots" target="_blank">brief tutorial&lt;/a> explaining how their API may be used for bots. The easiest way to create a bot is through their &lt;a href="https://dev.groupme.com/bots/new" target="_blank">web form&lt;/a>, which prompts you for the bot&amp;rsquo;s name, callback URL (technically optional, but you want it), avatar URL (optional), and the name of the group where the bot will live. Once you&amp;rsquo;ve done this, you will be given a unique bot ID token. Anyone with this token can pretend to be your bot, so keep it safe. (Security is somewhat laughable here: your bot asserts its ID and the server believes it with no &amp;ldquo;login&amp;rdquo; procedure.) We&amp;rsquo;ll talk more about the callback URL in a moment; for now, just leave it blank.&lt;/p>
&lt;p>Once you&amp;rsquo;ve done these steps, you have created a bot&amp;ndash;as far as GroupMe is concerned. If you send a specifically formatted JSON mssage, the newly created bot will post in your group. However, if left at this point, your &amp;ldquo;bot&amp;rdquo; is little more than a proxy for human-written messages submitted with &lt;code>curl&lt;/code>. Your bot needs some way of reading messages sent to the group, formulating a response, and only then sending messages to the GroupMe servers.&lt;/p></description></item><item><title>TensorFlow with the Surface Book</title><link>http://apnorton.com/blog/2017/01/04/Machine-Learning-with-the-Surface-Book/</link><pubDate>Wed, 04 Jan 2017 15:32:45 +0000</pubDate><guid>http://apnorton.com/blog/2017/01/04/Machine-Learning-with-the-Surface-Book/</guid><description>&lt;p>While interning at Microsoft over the summer, I received a first-generation Surface Book with an i5-6300U CPU (2.4 GHz dual core with up to 3.0 GHz), 8GB RAM, and a &amp;ldquo;GeForce GPU&amp;rdquo; (officially unnamed, but believed to be equivalent to a GT 940). This is a huge step up from my older laptop, so I wanted to set it up for my ML work. In this post, I&amp;rsquo;ll outline how I set it up with TensorFlow and GPU acceleration.&lt;/p>
&lt;h2 id="cuda--cudnn">CUDA + cuDNN&lt;a class="anchorjs-link" href="#cuda--cudnn">&lt;/a>&lt;/h2>&lt;p>If you want to use GPU acceleration, the typical way to do so is with NVIDIA&amp;rsquo;s CUDA API. CUDA 8.0 is compatible with the Surface Book and is (as of this writing) the most up-to-date version of CUDA. Download it &lt;a href="https://developer.nvidia.com/cuda-downloads" target="_blank">from the NVIDIA website&lt;/a> and run their installer.&lt;/p>
&lt;p>For work with deep learning, you&amp;rsquo;ll also want to install cuDNN. To install, just &lt;a href="https://developer.nvidia.com/cudnn" target="_blank">download&lt;/a> the library from NVIDIA&amp;rsquo;s website and unzip it in a convenient place (I chose &lt;code>C:\cudnn&lt;/code>). The only &amp;ldquo;installation&amp;rdquo; you need to do is to add &lt;code>C:\cudnn\bin&lt;/code> to your &lt;code>PATH&lt;/code> environment variable.&lt;/p></description></item><item><title>Visualizing Multidimensional Data in Python</title><link>http://apnorton.com/blog/2016/12/19/Visualizing-Multidimensional-Data-in-Python/</link><pubDate>Mon, 19 Dec 2016 20:51:55 +0000</pubDate><guid>http://apnorton.com/blog/2016/12/19/Visualizing-Multidimensional-Data-in-Python/</guid><description>&lt;p>Nearly everyone is familiar with two-dimensional plots, and most college students in the hard sciences are familiar with three dimensional plots. However, modern datasets are rarely two- or three-dimensional. In machine learning, it is commonplace to have dozens if not hundreds of dimensions, and even human-generated datasets can have a dozen or so dimensions. At the same time, visualization is an important first step in working with data. In this blog entry, I&amp;rsquo;ll explore how we can use Python to work with n-dimensional data, where $n\geq 4$.&lt;/p>
&lt;h2 id="packages">Packages&lt;a class="anchorjs-link" href="#packages">&lt;/a>&lt;/h2>&lt;p>I&amp;rsquo;m going to assume we have the &lt;code>numpy&lt;/code>, &lt;code>pandas&lt;/code>, &lt;code>matplotlib&lt;/code>, and &lt;code>sklearn&lt;/code> packages installed for Python. In particular, the components I will use are as below:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1&lt;/span>&lt;span>&lt;span style="color:#ff79c6">import&lt;/span> matplotlib.pyplot &lt;span style="color:#ff79c6">as&lt;/span> plt
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2&lt;/span>&lt;span>&lt;span style="color:#ff79c6">import&lt;/span> pandas &lt;span style="color:#ff79c6">as&lt;/span> pd
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4&lt;/span>&lt;span>&lt;span style="color:#ff79c6">from&lt;/span> sklearn.decomposition &lt;span style="color:#ff79c6">import&lt;/span> PCA &lt;span style="color:#ff79c6">as&lt;/span> sklearnPCA
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5&lt;/span>&lt;span>&lt;span style="color:#ff79c6">from&lt;/span> sklearn.discriminant_analysis &lt;span style="color:#ff79c6">import&lt;/span> LinearDiscriminantAnalysis &lt;span style="color:#ff79c6">as&lt;/span> LDA
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">6&lt;/span>&lt;span>&lt;span style="color:#ff79c6">from&lt;/span> sklearn.datasets.samples_generator &lt;span style="color:#ff79c6">import&lt;/span> make_blobs
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">7&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">8&lt;/span>&lt;span>&lt;span style="color:#ff79c6">from&lt;/span> pandas.tools.plotting &lt;span style="color:#ff79c6">import&lt;/span> parallel_coordinates
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="plotting-2d-data">Plotting 2D Data&lt;a class="anchorjs-link" href="#plotting-2d-data">&lt;/a>&lt;/h2>&lt;p>Before dealing with multidimensional data, let&amp;rsquo;s see how a scatter plot works with two-dimensional data in Python.&lt;/p>
&lt;p>First, we&amp;rsquo;ll generate some random 2D data using &lt;code>sklearn.samples_generator.make_blobs&lt;/code>. We&amp;rsquo;ll create three classes of points and plot each class in a different color. After running the following code, we have datapoints in &lt;code>X&lt;/code>, while classifications are in &lt;code>y&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1&lt;/span>&lt;span>X, y &lt;span style="color:#ff79c6">=&lt;/span> make_blobs(n_samples&lt;span style="color:#ff79c6">=&lt;/span>&lt;span style="color:#bd93f9">200&lt;/span>, centers&lt;span style="color:#ff79c6">=&lt;/span>&lt;span style="color:#bd93f9">3&lt;/span>, n_features&lt;span style="color:#ff79c6">=&lt;/span>&lt;span style="color:#bd93f9">2&lt;/span>, random_state&lt;span style="color:#ff79c6">=&lt;/span>&lt;span style="color:#bd93f9">0&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To create a 2D scatter plot, we simply use the &lt;code>scatter&lt;/code> function from &lt;code>matplotlib&lt;/code>. Since we want each class to be a separate color, we use the &lt;code>c&lt;/code> parameter to set the datapoint color according to the &lt;code>y&lt;/code> (class) vector.&lt;/p></description></item><item><title>A Microsoft Summer, Part 1: Seattle Fun</title><link>http://apnorton.com/blog/2016/09/30/A-Summer-with-Microsoft/</link><pubDate>Fri, 30 Sep 2016 01:26:20 +0000</pubDate><guid>http://apnorton.com/blog/2016/09/30/A-Summer-with-Microsoft/</guid><description>&lt;p>As suggested by this post&amp;rsquo;s title, I spent this past summer as an intern with Microsoft in Redmond, Washington. The experience was highly educational for me&amp;ndash;as my first (and last!) &amp;ldquo;real&amp;rdquo; internship, I learned a lot about software development and the importance of corporate culture, as well as discovering a lot about myself. Overall, the experience was a positive one, though, and I had an enormous amount of fun!&lt;/p>
&lt;p>&lt;em>This is the first of a three-part series on my time at Microsoft. This post focuses on fun recreational activities for interns in the Seattle area.&lt;/em>&lt;/p>
&lt;h2 id="outdoors">Outdoors&lt;a class="anchorjs-link" href="#outdoors">&lt;/a>&lt;/h2>
&lt;div class="fig_container">
&lt;img class="fig_image" src="http://apnorton.com/blog/2016/09/30/A-Summer-with-Microsoft/north_cascades.jpg" alt="Hiking in the North Cascades"/>
&lt;p class="fig_caption">Hiking in the North Cascades&lt;/p>
&lt;/div>


&lt;p>The Pacific Northwest is home to some of the most amazing views I&amp;rsquo;ve ever seen. Seattle is conveniently located close to the beach, the mountains, Puget Sound, rainforests, and many hiking trails and campsites. Exploring the outdoors also has the advantage of being very inexpensive, which is great if you&amp;rsquo;re saving your internship money for college expenses. If you visit National Parks, consider the &lt;a href="https://www.nps.gov/elca/planyourvisit/passport-program.htm" target="_blank">National Park Passport Program&lt;/a>&amp;ndash;if you&amp;rsquo;re going to once-in-a-lifetime parks, it&amp;rsquo;s a good idea to get your passbook stamped!&lt;/p></description></item><item><title>Ada's Technical Books</title><link>http://apnorton.com/blog/2016/08/07/Ada-s-Technical-Books/</link><pubDate>Sun, 07 Aug 2016 01:01:24 +0000</pubDate><guid>http://apnorton.com/blog/2016/08/07/Ada-s-Technical-Books/</guid><description>&lt;p>This summer, I&amp;rsquo;ve been working as an intern for Microsoft on the Direct2D/DirectWrite team. While I can&amp;rsquo;t really talk about what my work entails, I &lt;em>can&lt;/em> talk about some of the fun things I&amp;rsquo;ve done this summer in my free time and the non-work-related components of my internship. I suppose most people wouldn&amp;rsquo;t start blogging about their internship by describing a bookstore, but I went to this place today and it was so incredible that I had to write about it.&lt;/p>
&lt;p>In Capitol Hill, there&amp;rsquo;s a small store by the name &lt;a href="http://www.seattletechnicalbooks.com/" target="_blank">&lt;em>Ada&amp;rsquo;s Technical Books&lt;/em>&lt;/a>. It&amp;rsquo;s in a house that&amp;rsquo;s been converted to a cafe and bookstore, and is quite possibly the most amazing bookstore I&amp;rsquo;ve ever seen. As you walk in, you&amp;rsquo;re greeted by an small cafe counter to your left and an open area to your right with short bookcases and comfy chairs. Toys, puzzles, and &amp;ldquo;Maker&amp;rdquo;-appropriate items like lockpicks and Raspberry Pis.&lt;/p>

&lt;div class="fig_container">
&lt;img class="fig_image" src="http://apnorton.com/blog/2016/08/07/Ada-s-Technical-Books/widgets.jpg" alt="Who can resist a giant 555 timer?"/>
&lt;p class="fig_caption">Who can resist a giant 555 timer?&lt;/p>
&lt;/div></description></item><item><title>Visualizing Graphs in Program Output</title><link>http://apnorton.com/blog/2016/03/08/Visualizing-Graphs-in-Program-Output/</link><pubDate>Tue, 08 Mar 2016 17:11:35 +0000</pubDate><guid>http://apnorton.com/blog/2016/03/08/Visualizing-Graphs-in-Program-Output/</guid><description>&lt;p>Many computer science problems utilize &lt;a href="https://en.wikipedia.org/wiki/Graph_%28discrete_mathematics%29" target="_blank">graph&lt;/a>-based data structures. Their use can range from explicit inclusion in an algorithm-centric problem (like path-finding) to a more &amp;ldquo;behind-the-scenes&amp;rdquo; presence in Bayesian networks or descriptions of finite automata. Unfortunately, visualizing large graphs can be difficult to do, especially for debugging. Unlike lists or dictionaries, which can be represented clearly by plain text printing, depicting a graph tends to require more graphics overhead than is reasonable for most programmers to write simply for debugging purposes. I&amp;rsquo;ve found that &lt;a href="http://graphviz.org/" target="_blank">Graphviz&lt;/a>, a free graph visualization utility, can be quite useful in debugging graph-related programs.&lt;/p>
&lt;h2 id="installing-graphviz">Installing Graphviz&lt;a class="anchorjs-link" href="#installing-graphviz">&lt;/a>&lt;/h2>&lt;p>If you&amp;rsquo;re on a Debian-based Linux OS (e.g. Ubuntu), you can install Graphviz using &lt;code>apt-get&lt;/code>. Just run &lt;code>$ sudo apt-get install graphviz&lt;/code> and you&amp;rsquo;ll have everything you need to complete the steps in this blog post. Mac OS X users can use &lt;code>brew&lt;/code> equivalently.&lt;/p>
&lt;p>Windows users should install using a binary downloaded from the &lt;a href="http://graphviz.org/Download_windows.php" target="_blank">Graphviz Windows page&lt;/a>, but there might be some issues with setting the &lt;code>PATH&lt;/code> variable for running in the commandline.&lt;/p>
&lt;h2 id="making-a-basic-graph">Making a basic graph&lt;a class="anchorjs-link" href="#making-a-basic-graph">&lt;/a>&lt;/h2>&lt;p>Once you&amp;rsquo;ve installed, the next thing you&amp;rsquo;ll want to do is create a basic graph to ensure the installation succeeded and to gain practice using Graphviz tools. We do this by creating a &lt;code>*.dot&lt;/code> file that describes the graph we wish to display. If you&amp;rsquo;re the type of person who likes to jump right in and experiment first before reading too much, or if you love formal language specification, the &lt;a href="http://www.graphviz.org/content/dot-language" target="_blank">DOT grammar&lt;/a> is fairly readable and can give a quick introduction to creating DOT files.&lt;/p>
&lt;p>The below is a fairly representative DOT file to demonstrate some of the capabilities of Graphviz. Open your favorite text editor, copy/paste it in, and save it as &lt;code>firstgraph.dot&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1&lt;/span>&lt;span>digraph G {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2&lt;/span>&lt;span> &lt;span style="color:#6272a4">// Style information for nodes&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3&lt;/span>&lt;span> A &lt;span style="color:#ff79c6">[&lt;/span>style&lt;span style="color:#ff79c6">=&lt;/span>&lt;span style="color:#f1fa8c">&amp;#34;filled&amp;#34;&lt;/span>, color&lt;span style="color:#ff79c6">=&lt;/span>&lt;span style="color:#f1fa8c">&amp;#34;.05 .3 1.0&amp;#34;&lt;/span>&lt;span style="color:#ff79c6">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5&lt;/span>&lt;span> &lt;span style="color:#6272a4">// Edge declarations&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6&lt;/span>&lt;span> A &lt;span style="color:#ff79c6">-&amp;gt;&lt;/span> {B, C};
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7&lt;/span>&lt;span> D &lt;span style="color:#ff79c6">-&amp;gt;&lt;/span> E &lt;span style="color:#ff79c6">[&lt;/span>label&lt;span style="color:#ff79c6">=&lt;/span>&lt;span style="color:#f1fa8c">&amp;#34;-1&amp;#34;&lt;/span>&lt;span style="color:#ff79c6">]&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8&lt;/span>&lt;span> E &lt;span style="color:#ff79c6">-&amp;gt;&lt;/span> F &lt;span style="color:#ff79c6">[&lt;/span>label&lt;span style="color:#ff79c6">=&lt;/span>&lt;span style="color:#f1fa8c">&amp;#34;3&amp;#34;&lt;/span>&lt;span style="color:#ff79c6">]&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9&lt;/span>&lt;span> F &lt;span style="color:#ff79c6">-&amp;gt;&lt;/span> D &lt;span style="color:#ff79c6">[&lt;/span>label&lt;span style="color:#ff79c6">=&lt;/span>&lt;span style="color:#f1fa8c">&amp;#34;10&amp;#34;&lt;/span>&lt;span style="color:#ff79c6">]&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10&lt;/span>&lt;span>} &lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>This creates a directed graph (also called a &lt;em>digraph&lt;/em>) with six nodes and two connected components. Some of the edges have labels, and one of the nodes is colored. After you&amp;rsquo;ve copied (or downloaded) this file, open up a terminal to the directory with &lt;code>firstgraph.dot&lt;/code> in it and run &lt;code>$ dot firstgraph.dot -Tpng -o firstgraph.png&lt;/code>. The resulting image file should look something like the below:&lt;/p>

&lt;div class="fig_container">
&lt;img class="fig_image" src="http://apnorton.com/blog/2016/03/08/Visualizing-Graphs-in-Program-Output/firstgraph.jpg" alt="The rendered `firstgraph.dot`"/>
&lt;p class="fig_caption">The rendered `firstgraph.dot`&lt;/p>
&lt;/div></description></item><item><title>Deranged Exams: An ICPC Problem</title><link>http://apnorton.com/blog/2015/10/15/Deranged-Exams-An-ICPC-Problem/</link><pubDate>Thu, 15 Oct 2015 20:24:00 +0000</pubDate><guid>http://apnorton.com/blog/2015/10/15/Deranged-Exams-An-ICPC-Problem/</guid><description>&lt;p>This past week, my ICPC team worked the 2013 Greater New York Regional problem packet. One of my favorite problems in this set was Problem E: Deranged Exams. The code required to solve this problem isn&amp;rsquo;t that complicated, but the math behind it is a little unusual. In this post, I aim to explain the math and provide a solution to this problem.&lt;/p>
&lt;h2 id="problem-description">Problem Description&lt;a class="anchorjs-link" href="#problem-description">&lt;/a>&lt;/h2>&lt;p>The &lt;a href="http://acmgnyr.org/year2013/e.pdf" target="_blank">full problem statement&lt;/a> is archived online; in shortened form, we can consider the problem to be:&lt;/p>
&lt;blockquote>
&lt;p>Given a &amp;ldquo;matching&amp;rdquo; test of $n$ questions (each question maps to exactly one answer, and no two questions have the same answer), how many possible ways are there to answer at least the first $k$ questions wrong?&lt;/p>
&lt;/blockquote>
&lt;p>It turns out that there&amp;rsquo;s a really nice solution to this problem using a topic from combinatorics called &amp;ldquo;derangements.&amp;rdquo; (Note that the problem title was a not-so-subtle hint towards the solution.)&lt;/p>
&lt;h2 id="derangements">Derangements&lt;a class="anchorjs-link" href="#derangements">&lt;/a>&lt;/h2>&lt;p>While the idea of a permutation should be familiar to most readers, the closely related topic of a derangement is rarely discussed in most undergraduate curriculum. So, it is reasonable to start with a definition:&lt;/p>
&lt;blockquote>
&lt;p>A derangement is a permutation in which no element is in its original place. The number of derangements on $n$ elements is denoted $D_n$; this is also called the subfactorial of $n$, denoted $!n$.&lt;/p>
&lt;/blockquote>
&lt;p>The sequence $\langle D_n\rangle$ is &lt;a href="https://oeis.org/A000166" target="_blank">A000166&lt;/a> in OEIS (a website with which, by the way, every competitive programmer should familiarize themselves).&lt;/p>
&lt;p>It turns out that there is both a recursive and an explicit formula for $D_n$:&lt;/p>
&lt;p>{% math %}
\begin{aligned}
D_n &amp;amp;= (-1)^n \sum_k\binom{n}{k} (-1)^k k! \
&amp;amp;= n\cdot D_{n-1} + (-1)^n;;(D_0=1)
\end{aligned}
{% endmath %}&lt;/p>
&lt;p>This is significant because we can use the explicit formulation for computing single values of derangements, or we can use dynamic programming to rapidly compute $D_n$ for relatively small $n$.&lt;/p></description></item><item><title>Eight Books on Math and Computer Science</title><link>http://apnorton.com/blog/2015/06/09/Eight-Books-on-Math-and-Computer-Science/</link><pubDate>Tue, 09 Jun 2015 00:41:23 +0000</pubDate><guid>http://apnorton.com/blog/2015/06/09/Eight-Books-on-Math-and-Computer-Science/</guid><description>&lt;p>A friend recently emailed me asking for titles of books I&amp;rsquo;d recommend to read over the summer, particularly to prepare for computer science and mathematics. I&amp;rsquo;ve adapted my suggestions into this post. I&amp;rsquo;d like to note that I&amp;rsquo;ve restricted my responses to &amp;ldquo;non-textbooks;&amp;rdquo; otherwise, I&amp;rsquo;d have several more additions that would increase the average page count and price quite drastically. As such, these books don&amp;rsquo;t have problems to work or present an extreme level of detail, but in many cases they present enough information to provide a strong foundation and context for math and CS classes.&lt;/p>
&lt;h2 id="from-mathematics-to-generic-programming">From Mathematics to Generic Programming&lt;a class="anchorjs-link" href="#from-mathematics-to-generic-programming">&lt;/a>&lt;/h2>&lt;p>&lt;em>Alexander Stepanov and Daniel Rose (&lt;a href="http://www.amazon.com/Mathematics-Generic-Programming-Alexander-Stepanov/dp/0321942043" target="_blank">on Amazon&lt;/a>)&lt;/em>&lt;/p>
&lt;p>I will most likely write a separate blog post about this book. I read it during the end of the fall semester and found that it presented a very interesting approach to designing reusable code by utilizing principles from abstract algebra. It&amp;rsquo;s written to be accessible by someone who hasn&amp;rsquo;t studied abstract algebra yet, which means it also can serve as an introduction to that subject.&lt;/p>
&lt;h2 id="code-the-hidden-language-of-computer-hardware-and-software">CODE: The Hidden Language of Computer Hardware and Software&lt;a class="anchorjs-link" href="#code-the-hidden-language-of-computer-hardware-and-software">&lt;/a>&lt;/h2>&lt;p>&lt;em>Charles Petzold (&lt;a href="http://www.amazon.com/Code-Language-Computer-Hardware-Software/dp/0735611319/" target="_blank">on Amazon&lt;/a>)&lt;/em>&lt;/p>
&lt;p>Four years ago, I wrote &lt;a href="http://robodesigners.blogspot.com/2011/04/code-hidden-language-of-computer.html" target="_blank">a review&lt;/a> of this book on RoboDesigners. At that time, my perspective was that of a high school student and I thought the book was interesting; with the additional perspective of a year of college study in Computer Science, I cannot recommend this book highly enough.&lt;/p>
&lt;p>By &amp;ldquo;building&amp;rdquo; a computer piece-by-piece from the idea of a relay through developing a simple assembly language, it covers nearly all of the material as the Digital Logic Design course I took, but in an easy-to-read book. If you comprehend the material in this book, you will be able to coast through DLD.&lt;/p>
&lt;h2 id="a-mathematicians-apology">A Mathematician&amp;rsquo;s Apology&lt;a class="anchorjs-link" href="#a-mathematicians-apology">&lt;/a>&lt;/h2>&lt;p>&lt;em>G. H. Hardy (&lt;a href="http://www.amazon.com/Mathematicians-Apology-Canto-Classics/dp/110760463X/" target="_blank">on Amazon&lt;/a>)&lt;/em>&lt;/p>
&lt;p>When a mathematician with Hardy&amp;rsquo;s stature writes a book on why he studies math, it&amp;rsquo;s probably advisable to read it! Multiple professors of mine have said it&amp;rsquo;s a book any mathematician should read and I wholeheartedly agree. It&amp;rsquo;s really short (the printing I&amp;rsquo;ve linked above is only 154 pages), but the content is amazing. Hardy addresses the complaints many have with pure math and embodies the spirit of &amp;ldquo;doing mathematics for mathematics&amp;rsquo; sake.&amp;rdquo; If you are thinking about pursuing a theoretical route in either CS or math, I highly recommend you read this book.&lt;/p></description></item><item><title>How to Learn Haskell</title><link>http://apnorton.com/blog/2014/07/14/How-to-Learn-Haskell/</link><pubDate>Mon, 14 Jul 2014 20:55:08 +0000</pubDate><guid>http://apnorton.com/blog/2014/07/14/How-to-Learn-Haskell/</guid><description>To grow my programming repertoire, I decided to learn a functional language; at the recommendation of a friend, I selected Haskell. Thus far, it seems great. As a mathematician at heart, I love the way that the notation and language constructs resemble math (list comprehensions, tuples, function composition, etc). In this blog post, I will outline the major resources I am using to learn Haskell.
To learn Haskell, I am using the ebook Learn You a Haskell for Great Good.</description></item><item><title>Factorization and Divisor Count</title><link>http://apnorton.com/blog/2014/07/14/Factorization-and-Divisor-Count/</link><pubDate>Mon, 14 Jul 2014 11:59:15 +0000</pubDate><guid>http://apnorton.com/blog/2014/07/14/Factorization-and-Divisor-Count/</guid><description>&lt;p>How many divisors are there of the number $1281942112$? It turns out that determining the answer to this problem is (at most) only as difficult as determining the prime factorization of the number. In this blog post, I will outline a solution to this (and similar) problems.&lt;/p>
&lt;h2 id="the-math">The Math&lt;a class="anchorjs-link" href="#the-math">&lt;/a>&lt;/h2>&lt;p>The &lt;a href="http://mathworld.wolfram.com/FundamentalTheoremofArithmetic.html" target="_blank">Fundamental Theorem of Arithmetic&lt;/a> guarantees each positive integer greater than $1$ a unique prime factorization. We write this factorization as:&lt;/p>
&lt;p>$$N = p_0^{e_0}p_1^{e_1}\cdots p_n^{e_n}$$&lt;/p>
&lt;p>where $p_k$ is a prime number, and $e_k$ is its corresponding exponent. This provides us with useful information regarding divisors of $N$: any divisor of $N$ must be comprised of some combination of those prime factors (and exponents). Specifically, we can define the divisor, $D$, as:&lt;/p>
&lt;p>$$D = p_0^{a_0}p_1^{a_1}\cdots p_n^{a_n}$$&lt;/p>
&lt;p>where the $p_k$ are the same as in the factorization of $N$ and $a_k \in {0, 1, \ldots, e_k}$. To find the total number of divisors, we multiply together the number of options we have for each exponent. That is,&lt;/p>
&lt;p>$$\text{Number of Divisors}; = (e_0+1)(e_1+1)\cdots(e_n + 1)$$&lt;/p>
&lt;p>Example: Consider $N = 20$. In this case, $N$ has $6$ divisors; to determine this without needing to list them all, we may note that $N = 2^2\cdot 5^1$. Using the notation described above, this means that $p_0 = 2,;p_1 = 5$ and $e_0 = 2;e_1 = 1$. Each of our divisors will be of the form $2^{a_0}\cdot 5^{a_1}$, where $a_0$ could be $0, 1,$ or $2$ and $a_1$ could be $0$ or $1$. Since we have $e_0+1 = 3$ options for $a_0$ and $e_1+1 = 2$ options for $a_1$, we have $3\cdot 2 = 6$ total divisors. In case you were wondering, the list of divisors is:&lt;/p>
&lt;p>$${2^0 5^0, 2^1 5^0,2^2 5^0,2^0 5^1,2^1 5^1,2^2 5^1}$$&lt;/p></description></item><item><title>"Big-O" notation: An Introduction to Asymptotics of Loops</title><link>http://apnorton.com/blog/2014/06/09/Big-O-notation-An-Introduction-to-Asymptotics-of-Loops/</link><pubDate>Mon, 09 Jun 2014 23:28:45 +0000</pubDate><guid>http://apnorton.com/blog/2014/06/09/Big-O-notation-An-Introduction-to-Asymptotics-of-Loops/</guid><description>&lt;p>Algorithmic efficiency is imperative for success in programming competitions; your programs must be accurate and fast. To help evaluate algorithms for speed, computer scientists focus on what is called &amp;ldquo;asymptotics,&amp;rdquo; or &amp;ldquo;asymptotic analysis.&amp;rdquo; The key question answered by asymptotics is: &lt;strong>&amp;ldquo;When your input gets &lt;em>really&lt;/em> big, how many steps does your program take?&amp;rdquo;&lt;/strong> This post seeks to explain basic asymptotic analysis and its application to computing simple program runtime.&lt;/p>
&lt;p>The underlying principle of asymptotic analysis is that a program&amp;rsquo;s runtime depends on the number of &lt;em>elementary operations&lt;/em> it performs. The fewer elementary operations, the faster the program (and vice-versa). What do I mean by &amp;ldquo;elementary operation?&amp;rdquo; By this, I refer to any operation such that the runtime is not affected by the input size. This is more commonly referred to as a &lt;em>constant-time&lt;/em> operation. Examples of such operations are assignment, basic arithmetic operations (&lt;code>+, -, *, /, %&lt;/code>), accessing an array element, increment/decrement operations, function returns, and boolean expressions.&lt;/p>
&lt;h2 id="a-first-example">A First Example&lt;a class="anchorjs-link" href="#a-first-example">&lt;/a>&lt;/h2>&lt;p>So, a good way of gauging the runtime of a program is to count the number of elementary operations it performs. Let&amp;rsquo;s jump right in by analyzing a simple program.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1&lt;/span>&lt;span>public static int test(int N) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2&lt;/span>&lt;span> int i = 0;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3&lt;/span>&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4&lt;/span>&lt;span> while(i &amp;lt; N) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5&lt;/span>&lt;span> i++;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">6&lt;/span>&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">7&lt;/span>&lt;span> return i;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">8&lt;/span>&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Obviously, this program always returns $N$, so the loop is unnecessary. However, let&amp;rsquo;s just analyze the method as-is.&lt;/p>
&lt;p>Lines 2 and 7 each contribute one constant-time operation. The loop contributes two constant-time operations per iteration (one for the comparison, one for the increment), plus one extra constant-time operation for the final comparison that terminates the loop. So, the total number of operations is:&lt;/p>
&lt;p>$$1 + 1 + \underbrace{\sum_{i = 0}^N 2}_{\text{loop operations}} + 1 = 3 + 2N$$&lt;/p>
&lt;p>(Notice how I used sigma (summation) notation for counting a loop&amp;rsquo;s operation. This is useful, because loops and sigma notation behave in much the same way.)&lt;/p>
&lt;p>Thus, it will take $3+2N$ operations to perform that method, given an input $N$. If each operation takes $2\times 10^{-9}$ (about the speed of a 2 GHz processor), it would take 5 seconds to run this program for an input of $N=10^{10}$.&lt;/p></description></item><item><title>Green's Theorem and the Area of Polygons</title><link>http://apnorton.com/blog/2014/06/05/Greens-Theorem-and-The-Area-of-Polygons/</link><pubDate>Thu, 05 Jun 2014 18:48:45 +0000</pubDate><guid>http://apnorton.com/blog/2014/06/05/Greens-Theorem-and-The-Area-of-Polygons/</guid><description>I am an avid member of the Math.StackExchange community. We have recently reached a milestone, as our request to create a site blog has been approved by the Stack Exchange administration. I volunteered to write a post which I believe should be useful to competition programmers.
Using Green&amp;rsquo;s Theorem, this post derives a formula for the area of any simple polygon, dependent solely on the coordinates of the vertices. This is useful for some computational geometry problems in programming; for example, the formula can be used to compute the area of the convex hull of a set of points.</description></item><item><title>Hello World!</title><link>http://apnorton.com/blog/2014/05/23/Hello-World/</link><pubDate>Fri, 23 May 2014 23:58:00 +0000</pubDate><guid>http://apnorton.com/blog/2014/05/23/Hello-World/</guid><description>After managing a fairly successful blog for many years about competitive robotics, I am attempting to re-brand myself as I begin my studies in the field of Computer Science and Mathematics.
This blog will be the place I post interesting pieces of code I either develop or find, as well as math concepts useful to competitive programmers. This blog will focus heavily on ACM-style competitions, and may occasionally contain hints or my solutions to problems from sites like USACO or UVA Online Judge.</description></item></channel></rss>